aboutsummaryrefslogtreecommitdiffstats
path: root/utils/TableGen/CodeGenRegisters.cpp
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2011-06-15 04:50:36 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2011-06-15 04:50:36 +0000
commitae1920b1efa72c1789d562df4746110d0c2e10bd (patch)
tree22d7d8690b9997d57f32d4a0fd850b3d99dd0846 /utils/TableGen/CodeGenRegisters.cpp
parent393c4047c05b6d7b5851d339e51bb2cc35f630c2 (diff)
downloadexternal_llvm-ae1920b1efa72c1789d562df4746110d0c2e10bd.zip
external_llvm-ae1920b1efa72c1789d562df4746110d0c2e10bd.tar.gz
external_llvm-ae1920b1efa72c1789d562df4746110d0c2e10bd.tar.bz2
Give CodeGenRegisterClass a real sorted member set.
Make the Elements vector private and expose an ArrayRef through getOrder() instead. getOrder will eventually provide multiple user-specified allocation orders. Use the sorted member set for member and subclass tests. Clean up a lot of ad hoc searches. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@133040 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/TableGen/CodeGenRegisters.cpp')
-rw-r--r--utils/TableGen/CodeGenRegisters.cpp51
1 files changed, 31 insertions, 20 deletions
diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp
index 37c6856..1df9cc1 100644
--- a/utils/TableGen/CodeGenRegisters.cpp
+++ b/utils/TableGen/CodeGenRegisters.cpp
@@ -154,7 +154,8 @@ CodeGenRegister::addSubRegsPreOrder(SetVector<CodeGenRegister*> &OSet) const {
// CodeGenRegisterClass
//===----------------------------------------------------------------------===//
-CodeGenRegisterClass::CodeGenRegisterClass(Record *R) : TheDef(R) {
+CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R)
+ : TheDef(R) {
// Rename anonymous register classes.
if (R->getName().size() > 9 && R->getName()[9] == '.') {
static unsigned AnonCounter = 0;
@@ -171,14 +172,9 @@ CodeGenRegisterClass::CodeGenRegisterClass(Record *R) : TheDef(R) {
}
assert(!VTs.empty() && "RegisterClass must contain at least one ValueType!");
- std::vector<Record*> RegList = R->getValueAsListOfDefs("MemberList");
- for (unsigned i = 0, e = RegList.size(); i != e; ++i) {
- Record *Reg = RegList[i];
- if (!Reg->isSubClassOf("Register"))
- throw "Register Class member '" + Reg->getName() +
- "' does not derive from the Register class!";
- Elements.push_back(Reg);
- }
+ Elements = R->getValueAsListOfDefs("MemberList");
+ for (unsigned i = 0, e = Elements.size(); i != e; ++i)
+ Members.insert(RegBank.getReg(Elements[i]));
// SubRegClasses is a list<dag> containing (RC, subregindex, ...) dags.
ListInit *SRC = R->getValueAsListInit("SubRegClasses");
@@ -215,6 +211,26 @@ CodeGenRegisterClass::CodeGenRegisterClass(Record *R) : TheDef(R) {
MethodProtos = R->getValueAsCode("MethodProtos");
}
+bool CodeGenRegisterClass::contains(const CodeGenRegister *Reg) const {
+ return Members.count(Reg);
+}
+
+// Returns true if RC is a strict subclass.
+// RC is a sub-class of this class if it is a valid replacement for any
+// instruction operand where a register of this classis required. It must
+// satisfy these conditions:
+//
+// 1. All RC registers are also in this.
+// 2. The RC spill size must not be smaller than our spill size.
+// 3. RC spill alignment must be compatible with ours.
+//
+bool CodeGenRegisterClass::hasSubClass(const CodeGenRegisterClass *RC) const {
+ return SpillAlignment && RC->SpillAlignment % SpillAlignment == 0 &&
+ SpillSize <= RC->SpillSize &&
+ std::includes(Members.begin(), Members.end(),
+ RC->Members.begin(), RC->Members.end());
+}
+
const std::string &CodeGenRegisterClass::getName() const {
return TheDef->getName();
}
@@ -244,7 +260,8 @@ CodeGenRegBank::CodeGenRegBank(RecordKeeper &Records) : Records(Records) {
throw std::string("No 'RegisterClass' subclasses defined!");
RegClasses.reserve(RCs.size());
- RegClasses.assign(RCs.begin(), RCs.end());
+ for (unsigned i = 0, e = RCs.size(); i != e; ++i)
+ RegClasses.push_back(CodeGenRegisterClass(*this, RCs[i]));
}
CodeGenRegister *CodeGenRegBank::getReg(Record *Def) {
@@ -432,11 +449,12 @@ void CodeGenRegBank::computeDerivedInfo() {
/// superclass. Otherwise return null.
const CodeGenRegisterClass*
CodeGenRegBank::getRegClassForRegister(Record *R) {
+ const CodeGenRegister *Reg = getReg(R);
const std::vector<CodeGenRegisterClass> &RCs = getRegClasses();
const CodeGenRegisterClass *FoundRC = 0;
for (unsigned i = 0, e = RCs.size(); i != e; ++i) {
const CodeGenRegisterClass &RC = RCs[i];
- if (!RC.containsRegister(R))
+ if (!RC.contains(Reg))
continue;
// If this is the first class that contains the register,
@@ -450,16 +468,10 @@ CodeGenRegBank::getRegClassForRegister(Record *R) {
if (RC.getValueTypes() != FoundRC->getValueTypes())
return 0;
- std::vector<Record *> Elements(RC.Elements);
- std::vector<Record *> FoundElements(FoundRC->Elements);
- std::sort(Elements.begin(), Elements.end());
- std::sort(FoundElements.begin(), FoundElements.end());
-
// Check to see if the previously found class that contains
// the register is a subclass of the current class. If so,
// prefer the superclass.
- if (std::includes(Elements.begin(), Elements.end(),
- FoundElements.begin(), FoundElements.end())) {
+ if (RC.hasSubClass(FoundRC)) {
FoundRC = &RC;
continue;
}
@@ -467,8 +479,7 @@ CodeGenRegBank::getRegClassForRegister(Record *R) {
// Check to see if the previously found class that contains
// the register is a superclass of the current class. If so,
// prefer the superclass.
- if (std::includes(FoundElements.begin(), FoundElements.end(),
- Elements.begin(), Elements.end()))
+ if (FoundRC->hasSubClass(&RC))
continue;
// Multiple classes, and neither is a superclass of the other.