summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2012-05-03 22:49:04 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2012-05-03 22:49:04 +0000
commitdd63a063e2df0d0bc52b50732e3462fd58a636c0 (patch)
treeb668e64ff3ed9f1e0c036f148be7db00c9a274ad
parent1a2a19dd3ce2b163837b5f0a1ea474c72527cad6 (diff)
downloadllvm-dd63a063e2df0d0bc52b50732e3462fd58a636c0.tar.gz
llvm-dd63a063e2df0d0bc52b50732e3462fd58a636c0.tar.bz2
llvm-dd63a063e2df0d0bc52b50732e3462fd58a636c0.tar.xz
Use a shared implementation of getMatchingSuperRegClass().
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
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h4
-rw-r--r--lib/Target/TargetRegisterInfo.cpp30
-rw-r--r--utils/TableGen/RegisterInfoEmitter.cpp35
3 files changed, 32 insertions, 37 deletions
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index 85562b6010..b8097a231e 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -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.
diff --git a/lib/Target/TargetRegisterInfo.cpp b/lib/Target/TargetRegisterInfo.cpp
index 10970f0c59..3ae3fed5d5 100644
--- a/lib/Target/TargetRegisterInfo.cpp
+++ b/lib/Target/TargetRegisterInfo.cpp
@@ -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;
+}
diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp
index 6769892db4..6c21032233 100644
--- a/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/utils/TableGen/RegisterInfoEmitter.cpp
@@ -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...