From dd9a50196cd75dbcb2bd604754cd62f8c1f30357 Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Sat, 31 Mar 2012 01:35:59 +0000 Subject: [PATCH] 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 --- utils/TableGen/CodeGenRegisters.cpp | 49 +++++++++++++++++++++++++++++ utils/TableGen/CodeGenRegisters.h | 11 +++++++ 2 files changed, 60 insertions(+) diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index d86ca7a282b..73f0356ab0d 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 f5372c07c8f..f73519ebbf7 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 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 Registers; DenseMap Def2Reg; + unsigned NumRegUnits; // Register classes. std::vector RegClasses; @@ -355,6 +364,8 @@ namespace llvm { // Find a register from its Record def. CodeGenRegister *getReg(Record*); + unsigned newRegUnit() { return NumRegUnits++; } + ArrayRef getRegClasses() const { return RegClasses; }