[llvm-commits] [llvm] r146872 - in /llvm/trunk/utils/TableGen: CodeGenRegisters.cpp CodeGenRegisters.h
Jakob Stoklund Olesen
stoklund at 2pi.dk
Mon Dec 19 08:53:28 PST 2011
Author: stoklund
Date: Mon Dec 19 10:53:28 2011
New Revision: 146872
URL: http://llvm.org/viewvc/llvm-project?rev=146872&view=rev
Log:
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.
Modified:
llvm/trunk/utils/TableGen/CodeGenRegisters.cpp
llvm/trunk/utils/TableGen/CodeGenRegisters.h
Modified: llvm/trunk/utils/TableGen/CodeGenRegisters.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenRegisters.cpp?rev=146872&r1=146871&r2=146872&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenRegisters.cpp (original)
+++ llvm/trunk/utils/TableGen/CodeGenRegisters.cpp Mon Dec 19 10:53:28 2011
@@ -836,12 +836,69 @@
}
//
+// 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<std::pair<const CodeGenRegister*,
+ const CodeGenRegister*>, 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 @@
// 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;
+ }
}
}
Modified: llvm/trunk/utils/TableGen/CodeGenRegisters.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenRegisters.h?rev=146872&r1=146871&r2=146872&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenRegisters.h (original)
+++ llvm/trunk/utils/TableGen/CodeGenRegisters.h Mon Dec 19 10:53:28 2011
@@ -246,6 +246,8 @@
void computeInferredRegisterClasses();
void inferCommonSubClass(CodeGenRegisterClass *RC);
void inferSubClassWithSubReg(CodeGenRegisterClass *RC);
+ void inferMatchingSuperRegClass(CodeGenRegisterClass *RC,
+ unsigned FirstSubRegRC = 0);
// Composite SubRegIndex instances.
// Map (SubRegIndex, SubRegIndex) -> SubRegIndex.
More information about the llvm-commits
mailing list