aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2012-05-31 17:18:26 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2012-05-31 17:18:26 +0000
commitf5d4e5158fcbec26d1c243daa725878ca1ae560b (patch)
tree92d2dac30dc36830f1211a9e60e0db9a00eca8dc
parent703360f93cf88aeab3d602a454c554622eba63e9 (diff)
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
-rw-r--r--include/llvm/MC/MCRegisterInfo.h47
-rw-r--r--utils/TableGen/RegisterInfoEmitter.cpp17
2 files changed, 63 insertions, 1 deletions
diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h
index 1a15424108..a2ec7bc9c4 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 f8af06c75f..b9e8a2e35e 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<const CodeGenRegister*> 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<CodeGenRegisterClass*> 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"