Use a shared implementation of getMatchingSuperRegClass().
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 3 May 2012 22:49:04 +0000 (22:49 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Thu, 3 May 2012 22:49:04 +0000 (22:49 +0000)
TargetRegisterClass now gives access to the necessary tables.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156122 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/TargetRegisterInfo.h
lib/Target/TargetRegisterInfo.cpp
utils/TableGen/RegisterInfoEmitter.cpp

index 85562b60100f2c95d12be27d732fc8509d1ad9af..b8097a231edf4c3df522c52997757c966d7093a0 100644 (file)
@@ -434,9 +434,7 @@ public:
   /// TableGen will synthesize missing A sub-classes.
   virtual const TargetRegisterClass *
   getMatchingSuperRegClass(const TargetRegisterClass *A,
-                           const TargetRegisterClass *B, unsigned Idx) const {
-    llvm_unreachable("Target has no sub-registers");
-  }
+                           const TargetRegisterClass *B, unsigned Idx) const;
 
   /// getSubClassWithSubReg - Returns the largest legal sub-class of RC that
   /// supports the sub-register index Idx.
index 10970f0c596afe417d68da5ce843ebbdc0f7220e..3ae3fed5d59e1181cf30aead5f18a592495cb76b 100644 (file)
@@ -145,3 +145,33 @@ TargetRegisterInfo::getCommonSubClass(const TargetRegisterClass *A,
   // No common sub-class exists.
   return NULL;
 }
+
+const TargetRegisterClass *
+TargetRegisterInfo::getMatchingSuperRegClass(const TargetRegisterClass *A,
+                                             const TargetRegisterClass *B,
+                                             unsigned Idx) const {
+  assert(A && B && "Missing register class");
+  assert(Idx && "Bad sub-register index");
+
+  // Find Idx in the list of super-register indices.
+  const uint16_t *SRI = B->getSuperRegIndices();
+  unsigned Offset = 0;
+  while (SRI[Offset] != Idx) {
+    if (!SRI[Offset])
+      return 0;
+    ++Offset;
+  }
+
+  // The register class bit mask corresponding to SRI[Offset]. The bit mask
+  // contains all register classes that are projected into B by Idx. Find a
+  // class that is also a sub-class of A.
+  const unsigned RCMaskWords = (getNumRegClasses()+31)/32;
+  const uint32_t *TV = B->getSubClassMask() + (Offset + 1) * RCMaskWords;
+  const uint32_t *SC = A->getSubClassMask();
+
+  // Find the first common register class in TV and SC.
+  for (unsigned i = 0; i != RCMaskWords ; ++i)
+    if (unsigned Common = TV[i] & SC[i])
+      return getRegClass(32*i + CountTrailingZeros_32(Common));
+  return 0;
+}
index 6769892db42ac6c73b5ba035fd2599aae9a6f18a..6c2103223355014c6ed7b8949ab8b7026af2b14b 100644 (file)
@@ -680,10 +680,7 @@ RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target,
   if (!RegBank.getSubRegIndices().empty()) {
     OS << "  unsigned composeSubRegIndices(unsigned, unsigned) const;\n"
       << "  const TargetRegisterClass *"
-      "getSubClassWithSubReg(const TargetRegisterClass*, unsigned) const;\n"
-      << "  const TargetRegisterClass *getMatchingSuperRegClass("
-      "const TargetRegisterClass*, const TargetRegisterClass*, "
-      "unsigned) const;\n";
+      "getSubClassWithSubReg(const TargetRegisterClass*, unsigned) const;\n";
   }
   OS << "  const RegClassWeight &getRegClassWeight("
      << "const TargetRegisterClass *RC) const;\n"
@@ -734,9 +731,6 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
   ArrayRef<CodeGenRegisterClass*> RegisterClasses = RegBank.getRegClasses();
   ArrayRef<CodeGenSubRegIndex*> SubRegIndices = RegBank.getSubRegIndices();
 
-  // The number of 32-bit words in a register class bit mask.
-  const unsigned RCMaskWords = (RegisterClasses.size()+31)/32;
-
   // Collect all registers belonging to any allocatable class.
   std::set<Record*> AllocatableRegs;
 
@@ -1050,33 +1044,6 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
        << "  return TV ? getRegClass(TV - 1) : 0;\n}\n\n";
   }
 
-  if (!SubRegIndices.empty()) {
-    // Emit getMatchingSuperRegClass.
-    // We need to find the largest sub-class of A such that every register has
-    // an Idx sub-register in B.  Map (B, Idx) to a bit-vector of
-    // super-register classes that map into B. Then compute the largest common
-    // sub-class with A by taking advantage of the register class ordering,
-    // like getCommonSubClass().
-    OS << "const TargetRegisterClass *" << ClassName
-       << "::getMatchingSuperRegClass(const TargetRegisterClass *A,"
-       << " const TargetRegisterClass *B, unsigned Idx) const {\n"
-       << "  assert(A && B && \"Missing regclass\");\n"
-       << "  assert(Idx && Idx <= " << SubRegIndices.size()
-       << " && \"Bad subreg\");\n"
-       << "  const uint16_t *SRI = B->getSuperRegIndices();\n"
-       << "  unsigned Offset = 0;\n"
-       << "  while (SRI[Offset] != Idx) {\n"
-       << "    if (!SRI[Offset])\n      return 0;\n"
-       << "    ++Offset;\n  }\n"
-       << "  const uint32_t *TV = B->getSubClassMask() + (Offset+1)*"
-       << RCMaskWords << ";\n"
-       << "  const uint32_t *SC = A->getSubClassMask();\n"
-       << "  for (unsigned i = 0; i != " << RCMaskWords << "; ++i)\n"
-       << "    if (unsigned Common = TV[i] & SC[i])\n"
-       << "      return getRegClass(32*i + CountTrailingZeros_32(Common));\n"
-       << "  return 0;\n}\n\n";
-  }
-
   EmitRegUnitPressure(OS, RegBank, ClassName);
 
   // Emit the constructor of the class...