From a9f65b9a1f57dcf546399ac32bf89d71d20df5b9 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Mon, 19 Dec 2011 16:53:28 +0000 Subject: [PATCH] Synthesize register classes for TRI::getMatchingSuperRegClass(). Teach TableGen to create the missing register classes needed for getMatchingSuperRegClass() to return maximal results. The function is still not auto-generated, so it still returns inexact results. This produces these new register classes: ARM: QQPR_with_dsub_0_in_DPR_8 QQQQPR_with_dsub_0_in_DPR_8 X86: GR64_with_sub_32bit_in_GR32_NOAX GR64_with_sub_32bit_in_GR32_NOAX_and_GR32_NOSP GR64_with_sub_16bit_in_GR16_NOREX GR64_with_sub_32bit_in_GR32_NOAX_and_GR32_NOREX GR64_TC_and_GR64_with_sub_32bit_in_GR32_NOAX GR64_with_sub_32bit_in_GR32_NOAX_and_GR32_NOREX_NOSP GR64_TCW64_and_GR64_with_sub_32bit_in_GR32_NOAX GR64_TC_and_GR64_with_sub_32bit_in_GR32_NOAX_and_GR32_NOREX GR64_with_sub_32bit_in_GR32_TC GR64_with_sub_32bit_in_GR32_ABCD_and_GR32_NOAX GR64_with_sub_32bit_in_GR32_NOAX_and_GR32_TC GR64_with_sub_32bit_in_GR32_AD GR64_with_sub_32bit_in_GR32_AD_and_GR32_NOAX The other targets in the tree are not weird enough to be affected. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146872 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenRegisters.cpp | 73 +++++++++++++++++++++++++++++++++++++ utils/TableGen/CodeGenRegisters.h | 2 + 2 files changed, 75 insertions(+) diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index 3aadf503207..8ff24fd3615 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -836,12 +836,69 @@ void CodeGenRegBank::inferSubClassWithSubReg(CodeGenRegisterClass *RC) { } // +// Synthesize missing sub-classes of RC for getMatchingSuperRegClass(). +// +// Create sub-classes of RC such that getMatchingSuperRegClass(RC, SubIdx, X) +// has a maximal result for any SubIdx and any X >= FirstSubRegRC. +// + +void CodeGenRegBank::inferMatchingSuperRegClass(CodeGenRegisterClass *RC, + unsigned FirstSubRegRC) { + SmallVector, 16> SSPairs; + + // Iterate in SubRegIndex numerical order to visit synthetic indices last. + for (unsigned sri = 0, sre = SubRegIndices.size(); sri != sre; ++sri) { + Record *SubIdx = SubRegIndices[sri]; + // Skip indexes that aren't fully supported by RC's registers. This was + // computed by inferSubClassWithSubReg() above which should have been + // called first. + if (RC->getSubClassWithSubReg(SubIdx) != RC) + continue; + + // Build list of (Super, Sub) pairs for this SubIdx. + SSPairs.clear(); + for (CodeGenRegister::Set::const_iterator RI = RC->getMembers().begin(), + RE = RC->getMembers().end(); RI != RE; ++RI) { + const CodeGenRegister *Super = *RI; + const CodeGenRegister *Sub = Super->getSubRegs().find(SubIdx)->second; + assert(Sub && "Missing sub-register"); + SSPairs.push_back(std::make_pair(Super, Sub)); + } + + // Iterate over sub-register class candidates. Ignore classes created by + // this loop. They will never be useful. + for (unsigned rci = FirstSubRegRC, rce = RegClasses.size(); rci != rce; + ++rci) { + CodeGenRegisterClass *SubRC = RegClasses[rci]; + // Compute the subset of RC that maps into SubRC. + CodeGenRegister::Set SubSet; + for (unsigned i = 0, e = SSPairs.size(); i != e; ++i) + if (SubRC->contains(SSPairs[i].second)) + SubSet.insert(SSPairs[i].first); + if (SubSet.empty()) + continue; + // RC injects completely into SubRC. + if (SubSet.size() == SSPairs.size()) + continue; + // Only a subset of RC maps into SubRC. Make sure it is represented by a + // class. + getOrCreateSubClass(RC, &SubSet, RC->getName() + + "_with_" + SubIdx->getName() + + "_in_" + SubRC->getName()); + } + } +} + + +// // Infer missing register classes. // void CodeGenRegBank::computeInferredRegisterClasses() { // When this function is called, the register classes have not been sorted // and assigned EnumValues yet. That means getSubClasses(), // getSuperClasses(), and hasSubClass() functions are defunct. + unsigned FirstNewRC = RegClasses.size(); // Visit all register classes, including the ones being added by the loop. for (unsigned rci = 0; rci != RegClasses.size(); ++rci) { @@ -852,6 +909,22 @@ void CodeGenRegBank::computeInferredRegisterClasses() { // Synthesize answers for getCommonSubClass(). inferCommonSubClass(RC); + + // Synthesize answers for getMatchingSuperRegClass(). + inferMatchingSuperRegClass(RC); + + // New register classes are created while this loop is running, and we need + // to visit all of them. I particular, inferMatchingSuperRegClass needs + // to match old super-register classes with sub-register classes created + // after inferMatchingSuperRegClass was called. At this point, + // inferMatchingSuperRegClass has checked SuperRC = [0..rci] with SubRC = + // [0..FirstNewRC). We need to cover SubRC = [FirstNewRC..rci]. + if (rci + 1 == FirstNewRC) { + unsigned NextNewRC = RegClasses.size(); + for (unsigned rci2 = 0; rci2 != FirstNewRC; ++rci2) + inferMatchingSuperRegClass(RegClasses[rci2], FirstNewRC); + FirstNewRC = NextNewRC; + } } } diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h index c74cfd6d001..f9d3146c83e 100644 --- a/utils/TableGen/CodeGenRegisters.h +++ b/utils/TableGen/CodeGenRegisters.h @@ -246,6 +246,8 @@ namespace llvm { void computeInferredRegisterClasses(); void inferCommonSubClass(CodeGenRegisterClass *RC); void inferSubClassWithSubReg(CodeGenRegisterClass *RC); + void inferMatchingSuperRegClass(CodeGenRegisterClass *RC, + unsigned FirstSubRegRC = 0); // Composite SubRegIndex instances. // Map (SubRegIndex, SubRegIndex) -> SubRegIndex. -- 2.11.0