mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-17 21:35:07 +00:00
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:
parent
393c4047c0
commit
ae1920b1ef
@ -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();
|
||||
|
@ -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";
|
||||
}
|
||||
|
||||
|
@ -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!");
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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";
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user