summaryrefslogtreecommitdiff
path: root/utils/TableGen/RegisterInfoEmitter.cpp
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2011-06-12 03:05:52 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2011-06-12 03:05:52 +0000
commit026dc223aeef2579d63f395007491e37d6cde3a0 (patch)
treeabec90e272dbfb4d639a58ab5e95e611909fc692 /utils/TableGen/RegisterInfoEmitter.cpp
parentaff232a5941c9ffb7ad52e08f81ad53794fed56b (diff)
downloadllvm-026dc223aeef2579d63f395007491e37d6cde3a0.tar.gz
llvm-026dc223aeef2579d63f395007491e37d6cde3a0.tar.bz2
llvm-026dc223aeef2579d63f395007491e37d6cde3a0.tar.xz
Compute lists of sub-regs, super-regs, and overlapping regs.
Besides moving structural computations to CodeGenRegisters.cpp, this also well-defines the order of these lists: - Sub-register lists come from a pre-order traversal of the graph defined by the SubRegs lists in the .td files. - Super-register lists are topologically ordered so no register comes before any of its sub-registers. When the sub-register graph is not a tree, independent super-registers appear in numerical order. - Lists of overlapping registers are ordered according to register number. This reverses the order of the super-regs lists, but nobody was depending on that. The previous order of the overlaps lists was odd, and it may have depended on the precise behavior of std::stable_sort. The old computations are still there, but will be removed shortly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@132881 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/TableGen/RegisterInfoEmitter.cpp')
-rw-r--r--utils/TableGen/RegisterInfoEmitter.cpp85
1 files changed, 31 insertions, 54 deletions
diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp
index 5a441e285e..3694aa8a49 100644
--- a/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/utils/TableGen/RegisterInfoEmitter.cpp
@@ -168,26 +168,15 @@ static void addSubSuperReg(Record *R, Record *S,
addSubSuperReg(R, *I, SubRegs, SuperRegs, Aliases);
}
-class RegisterSorter {
-private:
- std::map<Record*, std::set<Record*>, LessRecord> &RegisterSubRegs;
-
-public:
- RegisterSorter(std::map<Record*, std::set<Record*>, LessRecord> &RS)
- : RegisterSubRegs(RS) {}
-
- bool operator()(Record *RegA, Record *RegB) {
- // B is sub-register of A.
- return RegisterSubRegs.count(RegA) && RegisterSubRegs[RegA].count(RegB);
- }
-};
-
// RegisterInfoEmitter::run - Main register file description emitter.
//
void RegisterInfoEmitter::run(raw_ostream &OS) {
CodeGenTarget Target(Records);
CodeGenRegBank &RegBank = Target.getRegBank();
RegBank.computeDerivedInfo();
+ std::map<const CodeGenRegister*, CodeGenRegister::Set> Overlaps;
+ RegBank.computeOverlaps(Overlaps);
+
EmitSourceFileHeader("Register Information Source Fragment", OS);
OS << "namespace llvm {\n\n";
@@ -632,60 +621,48 @@ void RegisterInfoEmitter::run(raw_ostream &OS) {
OS << "\n\n // Register Overlap Lists...\n";
// Emit an overlap list for all registers.
- for (std::map<Record*, std::set<Record*>, LessRecord >::iterator
- I = RegisterAliases.begin(), E = RegisterAliases.end(); I != E; ++I) {
- OS << " const unsigned " << I->first->getName() << "_Overlaps[] = { "
- << getQualifiedName(I->first) << ", ";
- for (std::set<Record*>::iterator ASI = I->second.begin(),
- E = I->second.end(); ASI != E; ++ASI)
- OS << getQualifiedName(*ASI) << ", ";
+ for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
+ const CodeGenRegister *Reg = &Regs[i];
+ const CodeGenRegister::Set &O = Overlaps[Reg];
+ // Move Reg to the front so TRI::getAliasSet can share the list.
+ OS << " const unsigned " << Reg->getName() << "_Overlaps[] = { "
+ << getQualifiedName(Reg->TheDef) << ", ";
+ for (CodeGenRegister::Set::const_iterator I = O.begin(), E = O.end();
+ I != E; ++I)
+ if (*I != Reg)
+ OS << getQualifiedName((*I)->TheDef) << ", ";
OS << "0 };\n";
}
- if (!RegisterSubRegs.empty())
- OS << "\n\n // Register Sub-registers Sets...\n";
-
// Emit the empty sub-registers list
OS << " const unsigned Empty_SubRegsSet[] = { 0 };\n";
// Loop over all of the registers which have sub-registers, emitting the
// sub-registers list to memory.
- for (std::map<Record*, std::set<Record*>, LessRecord>::iterator
- I = RegisterSubRegs.begin(), E = RegisterSubRegs.end(); I != E; ++I) {
- if (I->second.empty())
+ for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
+ const CodeGenRegister &Reg = Regs[i];
+ if (Reg.getSubRegs().empty())
continue;
- OS << " const unsigned " << I->first->getName() << "_SubRegsSet[] = { ";
- std::vector<Record*> SubRegsVector;
- for (std::set<Record*>::iterator ASI = I->second.begin(),
- E = I->second.end(); ASI != E; ++ASI)
- SubRegsVector.push_back(*ASI);
- RegisterSorter RS(RegisterSubRegs);
- std::stable_sort(SubRegsVector.begin(), SubRegsVector.end(), RS);
- for (unsigned i = 0, e = SubRegsVector.size(); i != e; ++i)
- OS << getQualifiedName(SubRegsVector[i]) << ", ";
+ // getSubRegs() orders by SubRegIndex. We want a topological order.
+ SetVector<CodeGenRegister*> SR;
+ Reg.addSubRegsPreOrder(SR);
+ OS << " const unsigned " << Reg.getName() << "_SubRegsSet[] = { ";
+ for (unsigned j = 0, je = SR.size(); j != je; ++j)
+ OS << getQualifiedName(SR[j]->TheDef) << ", ";
OS << "0 };\n";
}
- if (!RegisterSuperRegs.empty())
- OS << "\n\n // Register Super-registers Sets...\n";
-
// Emit the empty super-registers list
OS << " const unsigned Empty_SuperRegsSet[] = { 0 };\n";
// Loop over all of the registers which have super-registers, emitting the
// super-registers list to memory.
- for (std::map<Record*, std::set<Record*>, LessRecord >::iterator
- I = RegisterSuperRegs.begin(), E = RegisterSuperRegs.end(); I != E; ++I) {
- if (I->second.empty())
+ for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
+ const CodeGenRegister &Reg = Regs[i];
+ const CodeGenRegister::SuperRegList &SR = Reg.getSuperRegs();
+ if (SR.empty())
continue;
- OS << " const unsigned " << I->first->getName() << "_SuperRegsSet[] = { ";
-
- std::vector<Record*> SuperRegsVector;
- for (std::set<Record*>::iterator ASI = I->second.begin(),
- E = I->second.end(); ASI != E; ++ASI)
- SuperRegsVector.push_back(*ASI);
- RegisterSorter RS(RegisterSubRegs);
- std::stable_sort(SuperRegsVector.begin(), SuperRegsVector.end(), RS);
- for (unsigned i = 0, e = SuperRegsVector.size(); i != e; ++i)
- OS << getQualifiedName(SuperRegsVector[i]) << ", ";
+ OS << " const unsigned " << Reg.getName() << "_SuperRegsSet[] = { ";
+ for (unsigned j = 0, je = SR.size(); j != je; ++j)
+ OS << getQualifiedName(SR[j]->TheDef) << ", ";
OS << "0 };\n";
}
@@ -698,11 +675,11 @@ void RegisterInfoEmitter::run(raw_ostream &OS) {
const CodeGenRegister &Reg = Regs[i];
OS << " { \"";
OS << Reg.getName() << "\",\t" << Reg.getName() << "_Overlaps,\t";
- if (!RegisterSubRegs[Reg.TheDef].empty())
+ if (!Reg.getSubRegs().empty())
OS << Reg.getName() << "_SubRegsSet,\t";
else
OS << "Empty_SubRegsSet,\t";
- if (!RegisterSuperRegs[Reg.TheDef].empty())
+ if (!Reg.getSuperRegs().empty())
OS << Reg.getName() << "_SuperRegsSet,\t";
else
OS << "Empty_SuperRegsSet,\t";