summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2011-10-05 00:35:49 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2011-10-05 00:35:49 +0000
commit845d2c0c776abce551d16f7b1b7dc1f4d4df1a27 (patch)
tree204c79f6f26643a182bb869965b36795d212421e /utils
parent2a85015313b585c2a6d2a59d5bfc99a5ebe88f30 (diff)
downloadllvm-845d2c0c776abce551d16f7b1b7dc1f4d4df1a27.tar.gz
llvm-845d2c0c776abce551d16f7b1b7dc1f4d4df1a27.tar.bz2
llvm-845d2c0c776abce551d16f7b1b7dc1f4d4df1a27.tar.xz
Add TRI::getSubClassWithSubReg(RC, Idx) function.
This function is used to constrain a register class to a sub-class that supports the given sub-register index. For example, getSubClassWithSubReg(GR32, sub_8bit) -> GR32_ABCD. The function will be used to compute register classes when emitting INSERT_SUBREG and EXTRACT_SUBREG nodes and for register class inflation of sub-register operations. The version provided by TableGen is usually adequate, but targets can override. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141142 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/CodeGenRegisters.cpp20
-rw-r--r--utils/TableGen/CodeGenRegisters.h13
-rw-r--r--utils/TableGen/RegisterInfoEmitter.cpp40
3 files changed, 67 insertions, 6 deletions
diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp
index b731544616..8de4615279 100644
--- a/utils/TableGen/CodeGenRegisters.cpp
+++ b/utils/TableGen/CodeGenRegisters.cpp
@@ -768,23 +768,31 @@ void CodeGenRegBank::computeInferredRegisterClasses() {
// Find matching classes for all SRSets entries. Iterate in SubRegIndex
// numerical order to visit synthetic indices last.
for (unsigned sri = 0, sre = SubRegIndices.size(); sri != sre; ++sri) {
- SubReg2SetMap::const_iterator I = SRSets.find(SubRegIndices[sri]);
+ Record *SubIdx = SubRegIndices[sri];
+ SubReg2SetMap::const_iterator I = SRSets.find(SubIdx);
// Unsupported SubRegIndex. Skip it.
if (I == SRSets.end())
continue;
- // In most cases, all RC registers support the SubRegIndex. Skip those.
- if (I->second.size() == RC.getMembers().size())
+ // In most cases, all RC registers support the SubRegIndex.
+ if (I->second.size() == RC.getMembers().size()) {
+ RC.setSubClassWithSubReg(SubIdx, &RC);
continue;
+ }
// This is a real subset. See if we have a matching class.
CodeGenRegisterClass::Key K(&I->second, RC.SpillSize, RC.SpillAlignment);
RCKeyMap::const_iterator FoundI = Key2RC.find(K);
- if (FoundI != Key2RC.end())
+ if (FoundI != Key2RC.end()) {
+ RC.setSubClassWithSubReg(SubIdx, FoundI->second);
continue;
+ }
// Class doesn't exist.
- addToMaps(new CodeGenRegisterClass(RC.getName() + "_with_" +
- I->first->getName(), K));
+ CodeGenRegisterClass *NewRC =
+ new CodeGenRegisterClass(RC.getName() + "_with_" +
+ I->first->getName(), K);
+ addToMaps(NewRC);
+ RC.setSubClassWithSubReg(SubIdx, NewRC);
}
}
}
diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h
index 72c8ac0502..ab3e68efc2 100644
--- a/utils/TableGen/CodeGenRegisters.h
+++ b/utils/TableGen/CodeGenRegisters.h
@@ -101,6 +101,9 @@ namespace llvm {
// super-class.
void inheritProperties(CodeGenRegBank&);
+ // Map SubRegIndex -> sub-class
+ DenseMap<Record*, CodeGenRegisterClass*> SubClassWithSubReg;
+
public:
unsigned EnumValue;
std::string Namespace;
@@ -145,6 +148,16 @@ namespace llvm {
return SubClasses.test(RC->EnumValue);
}
+ // getSubClassWithSubReg - Returns the largest sub-class where all
+ // registers have a SubIdx sub-register.
+ CodeGenRegisterClass *getSubClassWithSubReg(Record *SubIdx) const {
+ return SubClassWithSubReg.lookup(SubIdx);
+ }
+
+ void setSubClassWithSubReg(Record *SubIdx, CodeGenRegisterClass *SubRC) {
+ SubClassWithSubReg[SubIdx] = SubRC;
+ }
+
// 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 f2cc36d371..a66a78cf91 100644
--- a/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/utils/TableGen/RegisterInfoEmitter.cpp
@@ -426,6 +426,8 @@ RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target,
<< " unsigned getSubReg(unsigned RegNo, unsigned Index) const;\n"
<< " unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const;\n"
<< " unsigned composeSubRegIndices(unsigned, unsigned) const;\n"
+ << " const TargetRegisterClass *"
+ "getSubClassWithSubReg(const TargetRegisterClass*, unsigned) const;\n"
<< "};\n\n";
const std::vector<Record*> &SubRegIndices = RegBank.getSubRegIndices();
@@ -802,6 +804,44 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
}
OS << " }\n}\n\n";
+ // Emit getSubClassWithSubReg.
+ OS << "const TargetRegisterClass *" << ClassName
+ << "::getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx)"
+ " const {\n";
+ if (SubRegIndices.empty()) {
+ OS << " assert(Idx == 0 && \"Target has no sub-registers\");\n"
+ << " return RC;\n";
+ } else {
+ // Use the smallest type that can hold a regclass ID with room for a
+ // sentinel.
+ if (RegisterClasses.size() < UINT8_MAX)
+ OS << " static const uint8_t Table[";
+ else if (RegisterClasses.size() < UINT16_MAX)
+ OS << " static const uint16_t Table[";
+ else
+ throw "Too many register classes.";
+ OS << RegisterClasses.size() << "][" << SubRegIndices.size() << "] = {\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];
+ if (CodeGenRegisterClass *SRC = RC.getSubClassWithSubReg(Idx))
+ OS << " " << SRC->EnumValue + 1 << ",\t// " << Idx->getName()
+ << " -> " << SRC->getName() << "\n";
+ else
+ OS << " 0,\t// " << Idx->getName() << "\n";
+ }
+ OS << " },\n";
+ }
+ OS << " };\n assert(RC && \"Missing regclass\");\n"
+ << " if (!Idx) return RC;\n --Idx;\n"
+ << " assert(Idx < " << SubRegIndices.size() << " && \"Bad subreg\");\n"
+ << " unsigned TV = Table[RC->getID()][Idx];\n"
+ << " return TV ? getRegClass(TV - 1) : 0;\n";
+ }
+ OS << "}\n\n";
+
// Emit the constructor of the class...
OS << "extern MCRegisterDesc " << TargetName << "RegDesc[];\n";