aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Trick <atrick@apple.com>2012-03-31 01:35:59 +0000
committerAndrew Trick <atrick@apple.com>2012-03-31 01:35:59 +0000
commitdd9a50196cd75dbcb2bd604754cd62f8c1f30357 (patch)
tree92a37437028d4ca8fa4953d6dbfb9e2731985ea9
parent3ee3661f8f10e7f82094a89c40d9118630ab0a40 (diff)
downloadexternal_llvm-dd9a50196cd75dbcb2bd604754cd62f8c1f30357.zip
external_llvm-dd9a50196cd75dbcb2bd604754cd62f8c1f30357.tar.gz
external_llvm-dd9a50196cd75dbcb2bd604754cd62f8c1f30357.tar.bz2
Introduce Register Units: Give each leaf register a number.
First small step toward modeling multi-register multi-pressure. In the future, register units can also be used to model liveness and aliasing. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153794 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--utils/TableGen/CodeGenRegisters.cpp49
-rw-r--r--utils/TableGen/CodeGenRegisters.h11
2 files changed, 60 insertions, 0 deletions
diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp
index d86ca7a..73f0356 100644
--- a/utils/TableGen/CodeGenRegisters.cpp
+++ b/utils/TableGen/CodeGenRegisters.cpp
@@ -88,6 +88,26 @@ const std::string &CodeGenRegister::getName() const {
return TheDef->getName();
}
+// Merge two RegUnitLists maintining the order and removing duplicates.
+// Overwrites MergedRU in the process.
+static void mergeRegUnits(CodeGenRegister::RegUnitList &MergedRU,
+ const CodeGenRegister::RegUnitList &RRU)
+{
+ CodeGenRegister::RegUnitList LRU = MergedRU;
+ MergedRU.clear();
+ for (CodeGenRegister::RegUnitList::const_iterator
+ RI = RRU.begin(), RE = RRU.end(), LI = LRU.begin(), LE = LRU.end();
+ RI != RE || LI != LE;) {
+
+ CodeGenRegister::RegUnitList::const_iterator &NextI =
+ (RI != RE && (LI == LE || *RI < *LI)) ? RI : LI;
+
+ if (MergedRU.empty() || *NextI != MergedRU.back())
+ MergedRU.push_back(*NextI);
+ ++NextI;
+ }
+}
+
const CodeGenRegister::SubRegMap &
CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) {
// Only compute this map once.
@@ -227,6 +247,34 @@ CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) {
if (Orphans.erase(SI->second))
SubRegs[RegBank.getCompositeSubRegIndex(Idx, SI->first)] = SI->second;
}
+
+ // Initialize RegUnitList. A register with no subregisters creates its own
+ // unit. Otherwise, it inherits all its subregister's units. Because
+ // getSubRegs is called recursively, this processes the register hierarchy in
+ // postorder.
+ //
+ // TODO: We currently assume all register units correspond to a named "leaf"
+ // register. We should also unify register units for ad-hoc register
+ // aliases. This can be done by iteratively merging units for aliasing
+ // registers using a worklist.
+ assert(RegUnits.empty() && "Should only initialize RegUnits once");
+ if (SubRegs.empty()) {
+ RegUnits.push_back(RegBank.newRegUnit());
+ }
+ else {
+ for (SubRegMap::const_iterator I = SubRegs.begin(), E = SubRegs.end();
+ I != E; ++I) {
+ // Strangely a register may have itself as a subreg (self-cycle) e.g. XMM.
+ CodeGenRegister *SR = I->second;
+ if (SR == this) {
+ if (RegUnits.empty())
+ RegUnits.push_back(RegBank.newRegUnit());
+ continue;
+ }
+ // Merge the subregister's units into this register's RegUnits.
+ mergeRegUnits(RegUnits, SR->RegUnits);
+ }
+ }
return SubRegs;
}
@@ -659,6 +707,7 @@ CodeGenRegBank::CodeGenRegBank(RecordKeeper &Records) : Records(Records) {
// Precompute all sub-register maps now all the registers are known.
// This will create Composite entries for all inferred sub-register indices.
+ NumRegUnits = 0;
for (unsigned i = 0, e = Registers.size(); i != e; ++i)
Registers[i]->getSubRegs(*this);
diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h
index f5372c0..f73519e 100644
--- a/utils/TableGen/CodeGenRegisters.h
+++ b/utils/TableGen/CodeGenRegisters.h
@@ -123,6 +123,13 @@ namespace llvm {
return SuperRegs;
}
+ // List of register units in ascending order.
+ typedef SmallVector<unsigned, 16> RegUnitList;
+
+ // Get the list of register units.
+ // This is only valid after getSubRegs() completes.
+ const RegUnitList &getRegUnits() const { return RegUnits; }
+
// Order CodeGenRegister pointers by EnumValue.
struct Less {
bool operator()(const CodeGenRegister *A,
@@ -139,6 +146,7 @@ namespace llvm {
bool SubRegsComplete;
SubRegMap SubRegs;
SuperRegList SuperRegs;
+ RegUnitList RegUnits;
};
@@ -307,6 +315,7 @@ namespace llvm {
// Registers.
std::vector<CodeGenRegister*> Registers;
DenseMap<Record*, CodeGenRegister*> Def2Reg;
+ unsigned NumRegUnits;
// Register classes.
std::vector<CodeGenRegisterClass*> RegClasses;
@@ -355,6 +364,8 @@ namespace llvm {
// Find a register from its Record def.
CodeGenRegister *getReg(Record*);
+ unsigned newRegUnit() { return NumRegUnits++; }
+
ArrayRef<CodeGenRegisterClass*> getRegClasses() const {
return RegClasses;
}