From f5d4e5158fcbec26d1c243daa725878ca1ae560b Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Thu, 31 May 2012 17:18:26 +0000 Subject: [PATCH] Emit register unit root tables. Each register unit has one or two root registers. The full set of registers containing a given register unit can be computed as the union of the root registers and their super-registers. Provide an MCRegUnitRootIterator class to enumerate the roots. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157753 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCRegisterInfo.h | 47 +++++++++++++++++++++++++- utils/TableGen/RegisterInfoEmitter.cpp | 17 ++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h index 1a154241084..a2ec7bc9c4f 100644 --- a/include/llvm/MC/MCRegisterInfo.h +++ b/include/llvm/MC/MCRegisterInfo.h @@ -147,6 +147,7 @@ private: const MCRegisterClass *Classes; // Pointer to the regclass array unsigned NumClasses; // Number of entries in the array unsigned NumRegUnits; // Number of regunits. + const uint16_t (*RegUnitRoots)[2]; // Pointer to regunit root table. const uint16_t *RegLists; // Pointer to the reglists array const uint16_t *DiffLists; // Pointer to the difflists array const char *RegStrings; // Pointer to the string table. @@ -238,11 +239,14 @@ public: friend class MCSuperRegIterator; friend class MCRegAliasIterator; friend class MCRegUnitIterator; + friend class MCRegUnitRootIterator; /// InitMCRegisterInfo - Initialize MCRegisterInfo, called by TableGen /// auto-generated routines. *DO NOT USE*. void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA, - const MCRegisterClass *C, unsigned NC, unsigned NRU, + const MCRegisterClass *C, unsigned NC, + const uint16_t (*RURoots)[2], + unsigned NRU, const uint16_t *RL, const uint16_t *DL, const char *Strings, @@ -257,6 +261,7 @@ public: DiffLists = DL; RegStrings = Strings; NumClasses = NC; + RegUnitRoots = RURoots; NumRegUnits = NRU; SubRegIndices = SubIndices; NumSubRegIndices = NumIndices; @@ -525,6 +530,46 @@ public: } }; +// Each register unit has one or two root registers. The complete set of +// registers containing a register unit is the union of the roots and their +// super-registers. All registers aliasing Unit can be visited like this: +// +// for (MCRegUnitRootIterator RI(Unit, MCRI); RI.isValid(); ++RI) { +// unsigned Root = *RI; +// visit(Root); +// for (MCSuperRegIterator SI(Root, MCRI); SI.isValid(); ++SI) +// visit(*SI); +// } + +/// MCRegUnitRootIterator enumerates the root registers of a register unit. +class MCRegUnitRootIterator { + uint16_t Reg0; + uint16_t Reg1; +public: + MCRegUnitRootIterator(unsigned RegUnit, const MCRegisterInfo *MCRI) { + assert(RegUnit < MCRI->getNumRegUnits() && "Invalid register unit"); + Reg0 = MCRI->RegUnitRoots[RegUnit][0]; + Reg1 = MCRI->RegUnitRoots[RegUnit][1]; + } + + /// Dereference to get the current root register. + unsigned operator*() const { + return Reg0; + } + + /// isValid - Check if the iterator is at the end of the list. + bool isValid() const { + return Reg0; + } + + /// Preincrement to move to the next root register. + void operator++() { + assert(isValid() && "Cannot move off the end of the list."); + Reg0 = Reg1; + Reg1 = 0; + } +}; + } // End llvm namespace #endif diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index f8af06c75fc..b9e8a2e35e3 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -616,6 +616,20 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, } OS << "};\n\n"; // End of register descriptors... + // Emit the table of register unit roots. Each regunit has one or two root + // registers. + OS << "extern const uint16_t " << TargetName << "RegUnitRoots[][2] = {\n"; + for (unsigned i = 0, e = RegBank.getNumNativeRegUnits(); i != e; ++i) { + ArrayRef Roots = RegBank.getRegUnit(i).getRoots(); + assert(!Roots.empty() && "All regunits must have a root register."); + assert(Roots.size() <= 2 && "More than two roots not supported yet."); + OS << " { " << getQualifiedName(Roots.front()->TheDef); + for (unsigned r = 1; r != Roots.size(); ++r) + OS << ", " << getQualifiedName(Roots[r]->TheDef); + OS << " },\n"; + } + OS << "};\n\n"; + ArrayRef RegisterClasses = RegBank.getRegClasses(); // Loop over all of the register classes... emitting each one. @@ -735,6 +749,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, OS << " RI->InitMCRegisterInfo(" << TargetName << "RegDesc, " << Regs.size()+1 << ", RA, " << TargetName << "MCRegisterClasses, " << RegisterClasses.size() << ", " + << TargetName << "RegUnitRoots, " << RegBank.getNumNativeRegUnits() << ", " << TargetName << "RegLists, " << TargetName << "RegDiffLists, " @@ -1098,6 +1113,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, OS << "extern const uint16_t " << TargetName << "RegLists[];\n"; OS << "extern const uint16_t " << TargetName << "RegDiffLists[];\n"; OS << "extern const char " << TargetName << "RegStrings[];\n"; + OS << "extern const uint16_t " << TargetName << "RegUnitRoots[][2];\n"; if (SubRegIndices.size() != 0) OS << "extern const uint16_t *get" << TargetName << "SubRegTable();\n"; @@ -1113,6 +1129,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, << " InitMCRegisterInfo(" << TargetName << "RegDesc, " << Regs.size()+1 << ", RA,\n " << TargetName << "MCRegisterClasses, " << RegisterClasses.size() << ",\n" + << " " << TargetName << "RegUnitRoots,\n" << " " << RegBank.getNumNativeRegUnits() << ",\n" << " " << TargetName << "RegLists,\n" << " " << TargetName << "RegDiffLists,\n"