forked from OSchip/llvm-project
Add support to tablegen for specifying subregister classes on a per register class basis.
llvm-svn: 37572
This commit is contained in:
parent
c68554683d
commit
f274efef9f
|
@ -64,6 +64,7 @@ private:
|
|||
const vt_iterator VTs;
|
||||
const sc_iterator SubClasses;
|
||||
const sc_iterator SuperClasses;
|
||||
const sc_iterator SubRegClasses;
|
||||
const unsigned RegSize, Alignment; // Size & Alignment of register in bytes
|
||||
const iterator RegsBegin, RegsEnd;
|
||||
public:
|
||||
|
@ -71,8 +72,10 @@ public:
|
|||
const MVT::ValueType *vts,
|
||||
const TargetRegisterClass * const *subcs,
|
||||
const TargetRegisterClass * const *supcs,
|
||||
const TargetRegisterClass * const *subregcs,
|
||||
unsigned RS, unsigned Al, iterator RB, iterator RE)
|
||||
: ID(id), VTs(vts), SubClasses(subcs), SuperClasses(supcs),
|
||||
SubRegClasses(subregcs),
|
||||
RegSize(RS), Alignment(Al), RegsBegin(RB), RegsEnd(RE) {}
|
||||
virtual ~TargetRegisterClass() {} // Allow subclasses
|
||||
|
||||
|
@ -167,6 +170,47 @@ public:
|
|||
return I;
|
||||
}
|
||||
|
||||
/// hasSubRegForClass - return true if the specified TargetRegisterClass is a
|
||||
/// class of a sub-register class for this TargetRegisterClass.
|
||||
bool hasSubRegForClass(const TargetRegisterClass *cs) const {
|
||||
for (int i = 0; SubRegClasses[i] != NULL; ++i)
|
||||
if (SubRegClasses[i] == cs)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// hasClassForSubReg - return true if the specified TargetRegisterClass is a
|
||||
/// class of a sub-register class for this TargetRegisterClass.
|
||||
bool hasClassForSubReg(unsigned SubReg) const {
|
||||
--SubReg;
|
||||
for (unsigned i = 0; SubRegClasses[i] != NULL; ++i)
|
||||
if (i == SubReg)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// getClassForSubReg - return theTargetRegisterClass for the sub-register
|
||||
/// at idx for this TargetRegisterClass.
|
||||
sc_iterator getClassForSubReg(unsigned SubReg) const {
|
||||
--SubReg;
|
||||
for (unsigned i = 0; SubRegClasses[i] != NULL; ++i)
|
||||
if (i == SubReg)
|
||||
return &SubRegClasses[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// subregclasses_begin / subregclasses_end - Loop over all of
|
||||
/// the subregister classes of this register class.
|
||||
sc_iterator subregclasses_begin() const {
|
||||
return SubRegClasses;
|
||||
}
|
||||
|
||||
sc_iterator subregclasses_end() const {
|
||||
sc_iterator I = SubRegClasses;
|
||||
while (*I != NULL) ++I;
|
||||
return I;
|
||||
}
|
||||
|
||||
/// allocation_order_begin/end - These methods define a range of registers
|
||||
/// which specify the registers in this class that are valid to register
|
||||
/// allocate, and the preferred order to allocate them in. For example,
|
||||
|
|
|
@ -109,6 +109,10 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
|
|||
// allocation used by the register allocator.
|
||||
//
|
||||
list<Register> MemberList = regList;
|
||||
|
||||
// SubClassList - Specify which register classes correspond to subregisters
|
||||
// of this class. The order should be by subregister set index.
|
||||
list<RegisterClass> SubRegClassList = [];
|
||||
|
||||
// MethodProtos/MethodBodies - These members can be used to insert arbitrary
|
||||
// code into a generated register class. The normal usage of this is to
|
||||
|
|
|
@ -38,6 +38,7 @@ namespace llvm {
|
|||
std::vector<MVT::ValueType> VTs;
|
||||
unsigned SpillSize;
|
||||
unsigned SpillAlignment;
|
||||
std::vector<Record*> SubRegClasses;
|
||||
std::string MethodProtos, MethodBodies;
|
||||
|
||||
const std::string &getName() const;
|
||||
|
|
|
@ -199,6 +199,16 @@ CodeGenRegisterClass::CodeGenRegisterClass(Record *R) : TheDef(R) {
|
|||
Elements.push_back(Reg);
|
||||
}
|
||||
|
||||
std::vector<Record*> SubRegClassList =
|
||||
R->getValueAsListOfDefs("SubRegClassList");
|
||||
for (unsigned i = 0, e = SubRegClassList.size(); i != e; ++i) {
|
||||
Record *SubRegClass = SubRegClassList[i];
|
||||
if (!SubRegClass->isSubClassOf("RegisterClass"))
|
||||
throw "Register Class member '" + SubRegClass->getName() +
|
||||
"' does not derive from the RegisterClass class!";
|
||||
SubRegClasses.push_back(SubRegClass);
|
||||
}
|
||||
|
||||
// Allow targets to override the size in bits of the RegisterClass.
|
||||
unsigned Size = R->getValueAsInt("Size");
|
||||
|
||||
|
|
|
@ -224,6 +224,44 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
|
|||
|
||||
std::map<unsigned, std::set<unsigned> > SuperClassMap;
|
||||
OS << "\n";
|
||||
|
||||
|
||||
// Emit the sub-register classes for each RegisterClass
|
||||
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
|
||||
const CodeGenRegisterClass &RC = RegisterClasses[rc];
|
||||
|
||||
// Give the register class a legal C name if it's anonymous.
|
||||
std::string Name = RC.TheDef->getName();
|
||||
|
||||
OS << " // " << Name
|
||||
<< " Sub-register Classess...\n"
|
||||
<< " static const TargetRegisterClass* const "
|
||||
<< Name << "SubRegClasses [] = {\n ";
|
||||
|
||||
bool Empty = true;
|
||||
|
||||
for (unsigned subrc = 0, e2 = RC.SubRegClasses.size();
|
||||
subrc != e2; ++subrc) {
|
||||
unsigned rc2 = 0, e2 = RegisterClasses.size();
|
||||
for (; rc2 != e2; ++rc2) {
|
||||
const CodeGenRegisterClass &RC2 = RegisterClasses[rc2];
|
||||
if (RC.SubRegClasses[subrc]->getName() == RC2.getName()) {
|
||||
if (!Empty) OS << ", ";
|
||||
OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass";
|
||||
Empty = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (rc2 == e2)
|
||||
throw "Register Class member '" +
|
||||
RC.SubRegClasses[subrc]->getName() +
|
||||
"' is not a valid RegisterClass!";
|
||||
}
|
||||
|
||||
OS << (!Empty ? ", " : "") << "NULL";
|
||||
OS << "\n };\n\n";
|
||||
}
|
||||
|
||||
// Emit the sub-classes array for each RegisterClass
|
||||
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
|
||||
const CodeGenRegisterClass &RC = RegisterClasses[rc];
|
||||
|
@ -304,6 +342,7 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
|
|||
<< RC.getName() + "VTs" << ", "
|
||||
<< RC.getName() + "Subclasses" << ", "
|
||||
<< RC.getName() + "Superclasses" << ", "
|
||||
<< RC.getName() + "SubRegClasses" << ", "
|
||||
<< RC.SpillSize/8 << ", "
|
||||
<< RC.SpillAlignment/8 << ", " << RC.getName() << ", "
|
||||
<< RC.getName() << " + " << RC.Elements.size() << ") {}\n";
|
||||
|
|
Loading…
Reference in New Issue