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
This commit is contained in:
Jakob Stoklund Olesen 2011-06-15 04:50:36 +00:00
parent 393c4047c0
commit ae1920b1ef
9 changed files with 75 additions and 75 deletions

View File

@ -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();

View File

@ -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";
}

View File

@ -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!");

View File

@ -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.

View File

@ -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 {
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;
}
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

View File

@ -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());
}
}

View File

@ -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) {

View File

@ -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;

View File

@ -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";
}