[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