summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--utils/TableGen/AsmMatcherEmitter.cpp8
-rw-r--r--utils/TableGen/AsmWriterEmitter.cpp6
-rw-r--r--utils/TableGen/CodeGenInstruction.cpp3
-rw-r--r--utils/TableGen/CodeGenRegisters.cpp51
-rw-r--r--utils/TableGen/CodeGenRegisters.h47
-rw-r--r--utils/TableGen/CodeGenTarget.cpp9
-rw-r--r--utils/TableGen/DAGISelMatcherGen.cpp4
-rw-r--r--utils/TableGen/InstrInfoEmitter.cpp8
-rw-r--r--utils/TableGen/RegisterInfoEmitter.cpp14
9 files changed, 75 insertions, 75 deletions
diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp
index bbe43493d1..1d7a67bf66 100644
--- a/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/utils/TableGen/AsmMatcherEmitter.cpp
@@ -896,8 +896,8 @@ BuildRegisterClasses(SmallPtrSet<Record*, 16> &SingletonRegisters) {
// Gather the defined sets.
for (std::vector<CodeGenRegisterClass>::const_iterator it =
RegClassList.begin(), ie = RegClassList.end(); it != ie; ++it)
- RegisterSets.insert(std::set<Record*>(it->Elements.begin(),
- it->Elements.end()));
+ RegisterSets.insert(std::set<Record*>(it->getOrder().begin(),
+ it->getOrder().end()));
// Add any required singleton sets.
for (SmallPtrSet<Record*, 16>::iterator it = SingletonRegisters.begin(),
@@ -971,8 +971,8 @@ BuildRegisterClasses(SmallPtrSet<Record*, 16> &SingletonRegisters) {
// Name the register classes which correspond to a user defined RegisterClass.
for (std::vector<CodeGenRegisterClass>::const_iterator
it = RegClassList.begin(), ie = RegClassList.end(); it != ie; ++it) {
- ClassInfo *CI = RegisterSetClasses[std::set<Record*>(it->Elements.begin(),
- it->Elements.end())];
+ ClassInfo *CI = RegisterSetClasses[std::set<Record*>(it->getOrder().begin(),
+ it->getOrder().end())];
if (CI->ValueName.empty()) {
CI->ClassName = it->getName();
CI->Name = "MCK_" + it->getName();
diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp
index bfc63c0cf8..818053a3c4 100644
--- a/utils/TableGen/AsmWriterEmitter.cpp
+++ b/utils/TableGen/AsmWriterEmitter.cpp
@@ -805,16 +805,16 @@ void AsmWriterEmitter::EmitRegIsInRegClass(raw_ostream &O) {
O << " case RC_" << Name << ":\n";
// Emit the register list now.
- unsigned IE = RC.Elements.size();
+ unsigned IE = RC.getOrder().size();
if (IE == 1) {
- O << " if (Reg == " << getQualifiedName(RC.Elements[0]) << ")\n";
+ O << " if (Reg == " << getQualifiedName(RC.getOrder()[0]) << ")\n";
O << " return true;\n";
} else {
O << " switch (Reg) {\n";
O << " default: break;\n";
for (unsigned II = 0; II != IE; ++II) {
- Record *Reg = RC.Elements[II];
+ Record *Reg = RC.getOrder()[II];
O << " case " << getQualifiedName(Reg) << ":\n";
}
diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp
index 5b0aedfbc8..73fe916258 100644
--- a/utils/TableGen/CodeGenInstruction.cpp
+++ b/utils/TableGen/CodeGenInstruction.cpp
@@ -417,7 +417,8 @@ bool CodeGenInstAlias::tryAliasOpMatch(DagInit *Result, unsigned AliasOpNo,
if (!InstOpRec->isSubClassOf("RegisterClass"))
return false;
- if (!T.getRegisterClass(InstOpRec).containsRegister(ADI->getDef()))
+ if (!T.getRegisterClass(InstOpRec)
+ .contains(T.getRegBank().getReg(ADI->getDef())))
throw TGError(Loc, "fixed register " +ADI->getDef()->getName()
+ " is not a member of the " + InstOpRec->getName() +
" register class!");
diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp
index 37c6856f40..1df9cc10bf 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.
diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h
index 26305b6e3b..d096ccd3f3 100644
--- a/utils/TableGen/CodeGenRegisters.h
+++ b/utils/TableGen/CodeGenRegisters.h
@@ -17,6 +17,7 @@
#include "Record.h"
#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SetVector.h"
#include <cstdlib>
@@ -65,13 +66,14 @@ namespace llvm {
// Order CodeGenRegister pointers by EnumValue.
struct Less {
- bool operator()(const CodeGenRegister *A, const CodeGenRegister *B) {
+ bool operator()(const CodeGenRegister *A,
+ const CodeGenRegister *B) const {
return A->EnumValue < B->EnumValue;
}
};
// Canonically ordered set.
- typedef std::set<CodeGenRegister*, Less> Set;
+ typedef std::set<const CodeGenRegister*, Less> Set;
private:
bool SubRegsComplete;
@@ -80,10 +82,12 @@ namespace llvm {
};
- struct CodeGenRegisterClass {
+ class CodeGenRegisterClass {
+ CodeGenRegister::Set Members;
+ std::vector<Record*> Elements;
+ public:
Record *TheDef;
std::string Namespace;
- std::vector<Record*> Elements;
std::vector<MVT::SimpleValueType> VTs;
unsigned SpillSize;
unsigned SpillAlignment;
@@ -104,13 +108,10 @@ namespace llvm {
abort();
}
- bool containsRegister(Record *R) const {
- for (unsigned i = 0, e = Elements.size(); i != e; ++i)
- if (Elements[i] == R) return true;
- return false;
- }
+ // Return true if this this class contains the register.
+ bool contains(const CodeGenRegister*) const;
- // Returns true if RC is a strict subclass.
+ // Returns true if RC is a 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:
@@ -119,29 +120,15 @@ namespace llvm {
// 2. The RC spill size must not be smaller than our spill size.
// 3. RC spill alignment must be compatible with ours.
//
- bool hasSubClass(const CodeGenRegisterClass *RC) const {
-
- if (RC->Elements.size() > Elements.size() ||
- (SpillAlignment && RC->SpillAlignment % SpillAlignment) ||
- SpillSize > RC->SpillSize)
- return false;
-
- std::set<Record*> RegSet;
- for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
- Record *Reg = Elements[i];
- RegSet.insert(Reg);
- }
-
- for (unsigned i = 0, e = RC->Elements.size(); i != e; ++i) {
- Record *Reg = RC->Elements[i];
- if (!RegSet.count(Reg))
- return false;
- }
+ bool hasSubClass(const CodeGenRegisterClass *RC) const;
- return true;
+ // Returns an ordered list of class members.
+ // The order of registers is the same as in the .td file.
+ ArrayRef<Record*> getOrder() const {
+ return Elements;
}
- CodeGenRegisterClass(Record *R);
+ CodeGenRegisterClass(CodeGenRegBank&, Record *R);
};
// CodeGenRegBank - Represent a target's registers and the relations between
diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp
index 9d0aadfdc9..6751ae7ca8 100644
--- a/utils/TableGen/CodeGenTarget.cpp
+++ b/utils/TableGen/CodeGenTarget.cpp
@@ -178,15 +178,14 @@ const CodeGenRegister *CodeGenTarget::getRegisterByName(StringRef Name) const {
std::vector<MVT::SimpleValueType> CodeGenTarget::
getRegisterVTs(Record *R) const {
+ const CodeGenRegister *Reg = getRegBank().getReg(R);
std::vector<MVT::SimpleValueType> Result;
const std::vector<CodeGenRegisterClass> &RCs = getRegisterClasses();
for (unsigned i = 0, e = RCs.size(); i != e; ++i) {
const CodeGenRegisterClass &RC = RCs[i];
- for (unsigned ei = 0, ee = RC.Elements.size(); ei != ee; ++ei) {
- if (R == RC.Elements[ei]) {
- const std::vector<MVT::SimpleValueType> &InVTs = RC.getValueTypes();
- Result.insert(Result.end(), InVTs.begin(), InVTs.end());
- }
+ if (RC.contains(Reg)) {
+ const std::vector<MVT::SimpleValueType> &InVTs = RC.getValueTypes();
+ Result.insert(Result.end(), InVTs.begin(), InVTs.end());
}
}
diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp
index 402a239ec5..a8736fa2f6 100644
--- a/utils/TableGen/DAGISelMatcherGen.cpp
+++ b/utils/TableGen/DAGISelMatcherGen.cpp
@@ -25,12 +25,12 @@ static MVT::SimpleValueType getRegisterValueType(Record *R,
const CodeGenTarget &T) {
bool FoundRC = false;
MVT::SimpleValueType VT = MVT::Other;
+ const CodeGenRegister *Reg = T.getRegBank().getReg(R);
const std::vector<CodeGenRegisterClass> &RCs = T.getRegisterClasses();
- std::vector<Record*>::const_iterator Element;
for (unsigned rc = 0, e = RCs.size(); rc != e; ++rc) {
const CodeGenRegisterClass &RC = RCs[rc];
- if (!std::count(RC.Elements.begin(), RC.Elements.end(), R))
+ if (!RC.contains(Reg))
continue;
if (!FoundRC) {
diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp
index 67cce0e55f..fc544ee658 100644
--- a/utils/TableGen/InstrInfoEmitter.cpp
+++ b/utils/TableGen/InstrInfoEmitter.cpp
@@ -166,13 +166,13 @@ void InstrInfoEmitter::DetectRegisterClassBarriers(std::vector<Record*> &Defs,
for (unsigned i = 0, e = RCs.size(); i != e; ++i) {
const CodeGenRegisterClass &RC = RCs[i];
- unsigned NumRegs = RC.Elements.size();
- if (NumRegs > NumDefs)
+ ArrayRef<Record*> Order = RC.getOrder();
+ if (Order.size() > NumDefs)
continue; // Can't possibly clobber this RC.
bool Clobber = true;
- for (unsigned j = 0; j < NumRegs; ++j) {
- Record *Reg = RC.Elements[j];
+ for (unsigned j = 0; j < Order.size(); ++j) {
+ Record *Reg = Order[j];
if (!DefSet.count(Reg)) {
Clobber = false;
break;
diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp
index 6853a0fff8..5e2143614e 100644
--- a/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/utils/TableGen/RegisterInfoEmitter.cpp
@@ -214,20 +214,21 @@ void RegisterInfoEmitter::run(raw_ostream &OS) {
// Emit the register enum value arrays for each RegisterClass
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
const CodeGenRegisterClass &RC = RegisterClasses[rc];
+ ArrayRef<Record*> Order = RC.getOrder();
// Collect allocatable registers.
if (RC.Allocatable)
- AllocatableRegs.insert(RC.Elements.begin(), RC.Elements.end());
+ AllocatableRegs.insert(Order.begin(), Order.end());
// Give the register class a legal C name if it's anonymous.
- std::string Name = RC.TheDef->getName();
+ std::string Name = RC.getName();
// Emit the register list now.
OS << " // " << Name << " Register Class...\n"
<< " static const unsigned " << Name
<< "[] = {\n ";
- for (unsigned i = 0, e = RC.Elements.size(); i != e; ++i) {
- Record *Reg = RC.Elements[i];
+ for (unsigned i = 0, e = Order.size(); i != e; ++i) {
+ Record *Reg = Order[i];
OS << getQualifiedName(Reg) << ", ";
}
OS << "\n };\n\n";
@@ -238,7 +239,7 @@ void RegisterInfoEmitter::run(raw_ostream &OS) {
const CodeGenRegisterClass &RC = RegisterClasses[rc];
// Give the register class a legal C name if it's anonymous.
- std::string Name = RC.TheDef->getName() + "VTs";
+ std::string Name = RC.getName() + "VTs";
// Emit the register list now.
OS << " // " << Name
@@ -425,7 +426,8 @@ void RegisterInfoEmitter::run(raw_ostream &OS) {
<< RC.SpillAlignment/8 << ", "
<< RC.CopyCost << ", "
<< RC.Allocatable << ", "
- << RC.getName() << ", " << RC.getName() << " + " << RC.Elements.size()
+ << RC.getName() << ", " << RC.getName() << " + "
+ << RC.getOrder().size()
<< ") {}\n";
}