diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index 85562b60100..b8097a231ed 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 10970f0c596..3ae3fed5d59 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 6769892db42..6c210322335 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 RegisterClasses = RegBank.getRegClasses(); ArrayRef 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 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...