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
This commit is contained in:
Jakob Stoklund Olesen 2012-05-03 22:49:04 +00:00
parent 1a2a19dd3c
commit dd63a063e2
3 changed files with 32 additions and 37 deletions

View 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.

View 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;
}

View 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...