aboutsummaryrefslogtreecommitdiff
path: root/utils/TableGen/RegisterInfoEmitter.cpp
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2012-11-01 00:32:10 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2012-11-01 00:32:10 +0000
commitad0b3b21e3abea7a9e9918ae1724f7dd7376b2cf (patch)
tree464b4e08c94bd0d7687db3ad8d1a52e1482020b5 /utils/TableGen/RegisterInfoEmitter.cpp
parent3037a58a218c6ca60214e1756951576c3a780b4a (diff)
Generate a table-driven version of TRI::composeSubRegIndices().
Explicitly allow composition of null sub-register indices, and handle that common case in an inlinable stub. Use a compressed table implementation instead of the previous nested switches which generated pretty bad code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@167190 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/TableGen/RegisterInfoEmitter.cpp')
-rw-r--r--utils/TableGen/RegisterInfoEmitter.cpp128
1 files changed, 102 insertions, 26 deletions
diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp
index 273cac0c01..95b6267238 100644
--- a/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/utils/TableGen/RegisterInfoEmitter.cpp
@@ -62,6 +62,8 @@ private:
void EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank,
const std::string &ClassName);
+ void emitComposeSubRegIndices(raw_ostream &OS, CodeGenRegBank &RegBank,
+ const std::string &ClassName);
};
} // End anonymous namespace
@@ -530,6 +532,102 @@ static void printDiff16(raw_ostream &OS, uint16_t Val) {
OS << Val;
}
+// Try to combine Idx's compose map into Vec if it is compatible.
+// Return false if it's not possible.
+static bool combine(const CodeGenSubRegIndex *Idx,
+ SmallVectorImpl<CodeGenSubRegIndex*> &Vec) {
+ const CodeGenSubRegIndex::CompMap &Map = Idx->getComposites();
+ for (CodeGenSubRegIndex::CompMap::const_iterator
+ I = Map.begin(), E = Map.end(); I != E; ++I) {
+ CodeGenSubRegIndex *&Entry = Vec[I->first->EnumValue - 1];
+ if (Entry && Entry != I->second)
+ return false;
+ }
+
+ // All entries are compatible. Make it so.
+ for (CodeGenSubRegIndex::CompMap::const_iterator
+ I = Map.begin(), E = Map.end(); I != E; ++I)
+ Vec[I->first->EnumValue - 1] = I->second;
+ return true;
+}
+
+static const char *getMinimalTypeForRange(uint64_t Range) {
+ assert(Range < 0xFFFFFFFFULL && "Enum too large");
+ if (Range > 0xFFFF)
+ return "uint32_t";
+ if (Range > 0xFF)
+ return "uint16_t";
+ return "uint8_t";
+}
+
+void
+RegisterInfoEmitter::emitComposeSubRegIndices(raw_ostream &OS,
+ CodeGenRegBank &RegBank,
+ const std::string &ClName) {
+ ArrayRef<CodeGenSubRegIndex*> SubRegIndices = RegBank.getSubRegIndices();
+ OS << "unsigned " << ClName
+ << "::composeSubRegIndicesImpl(unsigned IdxA, unsigned IdxB) const {\n";
+
+ // Many sub-register indexes are composition-compatible, meaning that
+ //
+ // compose(IdxA, IdxB) == compose(IdxA', IdxB)
+ //
+ // for many IdxA, IdxA' pairs. Not all sub-register indexes can be composed.
+ // The illegal entries can be use as wildcards to compress the table further.
+
+ // Map each Sub-register index to a compatible table row.
+ SmallVector<unsigned, 4> RowMap;
+ SmallVector<SmallVector<CodeGenSubRegIndex*, 4>, 4> Rows;
+
+ for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) {
+ unsigned Found = ~0u;
+ for (unsigned r = 0, re = Rows.size(); r != re; ++r) {
+ if (combine(SubRegIndices[i], Rows[r])) {
+ Found = r;
+ break;
+ }
+ }
+ if (Found == ~0u) {
+ Found = Rows.size();
+ Rows.resize(Found + 1);
+ Rows.back().resize(SubRegIndices.size());
+ combine(SubRegIndices[i], Rows.back());
+ }
+ RowMap.push_back(Found);
+ }
+
+ // Output the row map if there is multiple rows.
+ if (Rows.size() > 1) {
+ OS << " static const " << getMinimalTypeForRange(Rows.size())
+ << " RowMap[" << SubRegIndices.size() << "] = {\n ";
+ for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i)
+ OS << RowMap[i] << ", ";
+ OS << "\n };\n";
+ }
+
+ // Output the rows.
+ OS << " static const " << getMinimalTypeForRange(SubRegIndices.size()+1)
+ << " Rows[" << Rows.size() << "][" << SubRegIndices.size() << "] = {\n";
+ for (unsigned r = 0, re = Rows.size(); r != re; ++r) {
+ OS << " { ";
+ for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i)
+ if (Rows[r][i])
+ OS << Rows[r][i]->EnumValue << ", ";
+ else
+ OS << "0, ";
+ OS << "},\n";
+ }
+ OS << " };\n\n";
+
+ OS << " --IdxA; assert(IdxA < " << SubRegIndices.size() << ");\n"
+ << " --IdxB; assert(IdxB < " << SubRegIndices.size() << ");\n";
+ if (Rows.size() > 1)
+ OS << " return Rows[RowMap[IdxA]][IdxB];\n";
+ else
+ OS << " return Rows[0][IdxB];\n";
+ OS << "}\n\n";
+}
+
//
// runMCDesc - Print out MC register descriptions.
//
@@ -802,7 +900,8 @@ RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target,
<< " virtual bool needsStackRealignment(const MachineFunction &) const\n"
<< " { return false; }\n";
if (!RegBank.getSubRegIndices().empty()) {
- OS << " virtual unsigned composeSubRegIndices(unsigned, unsigned) const;\n"
+ OS << " virtual unsigned composeSubRegIndicesImpl"
+ << "(unsigned, unsigned) const;\n"
<< " virtual const TargetRegisterClass *"
"getSubClassWithSubReg(const TargetRegisterClass*, unsigned) const;\n";
}
@@ -1054,31 +1153,8 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
std::string ClassName = Target.getName() + "GenRegisterInfo";
- // Emit composeSubRegIndices
- if (!SubRegIndices.empty()) {
- OS << "unsigned " << ClassName
- << "::composeSubRegIndices(unsigned IdxA, unsigned IdxB) const {\n"
- << " switch (IdxA) {\n"
- << " default:\n return IdxB;\n";
- for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) {
- bool Open = false;
- for (unsigned j = 0; j != e; ++j) {
- CodeGenSubRegIndex *Comp = SubRegIndices[i]->compose(SubRegIndices[j]);
- if (Comp && Comp != SubRegIndices[j]) {
- if (!Open) {
- OS << " case " << SubRegIndices[i]->getQualifiedName()
- << ": switch(IdxB) {\n default: return IdxB;\n";
- Open = true;
- }
- OS << " case " << SubRegIndices[j]->getQualifiedName()
- << ": return " << Comp->getQualifiedName() << ";\n";
- }
- }
- if (Open)
- OS << " }\n";
- }
- OS << " }\n}\n\n";
- }
+ if (!SubRegIndices.empty())
+ emitComposeSubRegIndices(OS, RegBank, ClassName);
// Emit getSubClassWithSubReg.
if (!SubRegIndices.empty()) {