aboutsummaryrefslogtreecommitdiffstats
path: root/utils
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2011-12-19 16:53:34 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2011-12-19 16:53:34 +0000
commit570f9a972e02830d1ca223743dd6b4cc4fdf9549 (patch)
treeff67aae70fb2690c391b75f7ec47ff5a4fc5c55c /utils
parenta9f65b9a1f57dcf546399ac32bf89d71d20df5b9 (diff)
downloadexternal_llvm-570f9a972e02830d1ca223743dd6b4cc4fdf9549.zip
external_llvm-570f9a972e02830d1ca223743dd6b4cc4fdf9549.tar.gz
external_llvm-570f9a972e02830d1ca223743dd6b4cc4fdf9549.tar.bz2
Emit a getMatchingSuperRegClass() implementation for every target.
Use information computed while inferring new register classes to emit accurate, table-driven implementations of getMatchingSuperRegClass(). Delete the old manual, error-prone implementations in the targets. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146873 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/CodeGenRegisters.cpp16
-rw-r--r--utils/TableGen/CodeGenRegisters.h18
-rw-r--r--utils/TableGen/RegisterInfoEmitter.cpp48
3 files changed, 80 insertions, 2 deletions
diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp
index 8ff24fd..e023991 100644
--- a/utils/TableGen/CodeGenRegisters.cpp
+++ b/utils/TableGen/CodeGenRegisters.cpp
@@ -504,6 +504,18 @@ void CodeGenRegisterClass::computeSubClasses(CodeGenRegBank &RegBank) {
RegClasses[rci]->inheritProperties(RegBank);
}
+void
+CodeGenRegisterClass::getSuperRegClasses(Record *SubIdx, BitVector &Out) const {
+ DenseMap<Record*, SmallPtrSet<CodeGenRegisterClass*, 8> >::const_iterator
+ FindI = SuperRegClasses.find(SubIdx);
+ if (FindI == SuperRegClasses.end())
+ return;
+ for (SmallPtrSet<CodeGenRegisterClass*, 8>::const_iterator I =
+ FindI->second.begin(), E = FindI->second.end(); I != E; ++I)
+ Out.set((*I)->EnumValue);
+}
+
+
//===----------------------------------------------------------------------===//
// CodeGenRegBank
//===----------------------------------------------------------------------===//
@@ -879,8 +891,10 @@ void CodeGenRegBank::inferMatchingSuperRegClass(CodeGenRegisterClass *RC,
if (SubSet.empty())
continue;
// RC injects completely into SubRC.
- if (SubSet.size() == SSPairs.size())
+ if (SubSet.size() == SSPairs.size()) {
+ SubRC->addSuperRegClass(SubIdx, RC);
continue;
+ }
// Only a subset of RC maps into SubRC. Make sure it is represented by a
// class.
getOrCreateSubClass(RC, &SubSet, RC->getName() +
diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h
index f9d3146..1d1454c 100644
--- a/utils/TableGen/CodeGenRegisters.h
+++ b/utils/TableGen/CodeGenRegisters.h
@@ -101,9 +101,16 @@ namespace llvm {
// super-class.
void inheritProperties(CodeGenRegBank&);
- // Map SubRegIndex -> sub-class
+ // Map SubRegIndex -> sub-class. This is the largest sub-class where all
+ // registers have a SubRegIndex sub-register.
DenseMap<Record*, CodeGenRegisterClass*> SubClassWithSubReg;
+ // Map SubRegIndex -> set of super-reg classes. This is all register
+ // classes SuperRC such that:
+ //
+ // R:SubRegIndex in this RC for all R in SuperRC.
+ //
+ DenseMap<Record*, SmallPtrSet<CodeGenRegisterClass*, 8> > SuperRegClasses;
public:
unsigned EnumValue;
std::string Namespace;
@@ -158,6 +165,15 @@ namespace llvm {
SubClassWithSubReg[SubIdx] = SubRC;
}
+ // getSuperRegClasses - Returns a bit vector of all register classes
+ // containing only SubIdx super-registers of this class.
+ void getSuperRegClasses(Record *SubIdx, BitVector &Out) const;
+
+ // addSuperRegClass - Add a class containing only SudIdx super-registers.
+ void addSuperRegClass(Record *SubIdx, CodeGenRegisterClass *SuperRC) {
+ SuperRegClasses[SubIdx].insert(SuperRC);
+ }
+
// getSubClasses - Returns a constant BitVector of subclasses indexed by
// EnumValue.
// The SubClasses vector includs an entry for this class.
diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp
index d228f72..5fa2fe0 100644
--- a/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/utils/TableGen/RegisterInfoEmitter.cpp
@@ -426,6 +426,9 @@ RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target,
<< " unsigned composeSubRegIndices(unsigned, unsigned) const;\n"
<< " const TargetRegisterClass *"
"getSubClassWithSubReg(const TargetRegisterClass*, unsigned) const;\n"
+ << " const TargetRegisterClass *getMatchingSuperRegClass("
+ "const TargetRegisterClass*, const TargetRegisterClass*, "
+ "unsigned) const;\n"
<< "};\n\n";
const std::vector<Record*> &SubRegIndices = RegBank.getSubRegIndices();
@@ -815,6 +818,51 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
}
OS << "}\n\n";
+ // Emit getMatchingSuperRegClass.
+ OS << "const TargetRegisterClass *" << ClassName
+ << "::getMatchingSuperRegClass(const TargetRegisterClass *A,"
+ " const TargetRegisterClass *B, unsigned Idx) const {\n";
+ if (SubRegIndices.empty()) {
+ OS << " llvm_unreachable(\"Target has no sub-registers\");\n";
+ } else {
+ // We need to find the largest sub-class of A such that every register has
+ // an Idx sub-register in B. Map (B, Idx) to a bit-vector of
+ // super-register classes that map into B. Then compute the largest common
+ // sub-class with A by taking advantage of the register class ordering,
+ // like getCommonSubClass().
+
+ // Bitvector table is NumRCs x NumSubIndexes x BVWords, where BVWords is
+ // the number of 32-bit words required to represent all register classes.
+ const unsigned BVWords = (RegisterClasses.size()+31)/32;
+ BitVector BV(RegisterClasses.size());
+
+ OS << " static const unsigned Table[" << RegisterClasses.size()
+ << "][" << SubRegIndices.size() << "][" << BVWords << "] = {\n";
+ for (unsigned rci = 0, rce = RegisterClasses.size(); rci != rce; ++rci) {
+ const CodeGenRegisterClass &RC = *RegisterClasses[rci];
+ OS << " {\t// " << RC.getName() << "\n";
+ for (unsigned sri = 0, sre = SubRegIndices.size(); sri != sre; ++sri) {
+ Record *Idx = SubRegIndices[sri];
+ BV.reset();
+ RC.getSuperRegClasses(Idx, BV);
+ OS << " { ";
+ printBitVectorAsHex(OS, BV, 32);
+ OS << "},\t// " << Idx->getName() << '\n';
+ }
+ OS << " },\n";
+ }
+ OS << " };\n assert(A && B && \"Missing regclass\");\n"
+ << " --Idx;\n"
+ << " assert(Idx < " << SubRegIndices.size() << " && \"Bad subreg\");\n"
+ << " const unsigned *TV = Table[B->getID()][Idx];\n"
+ << " const unsigned *SC = A->getSubClassMask();\n"
+ << " for (unsigned i = 0; i != " << BVWords << "; ++i)\n"
+ << " if (unsigned Common = TV[i] & SC[i])\n"
+ << " return getRegClass(32*i + CountTrailingZeros_32(Common));\n"
+ << " return 0;\n";
+ }
+ OS << "}\n\n";
+
// Emit the constructor of the class...
OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[];\n";