Start parsing register classes into a more structured form
llvm-svn: 15961
This commit is contained in:
parent
e34ae99942
commit
2a86fab933
|
@ -16,6 +16,7 @@
|
||||||
#define CODEGEN_REGISTERS_H
|
#define CODEGEN_REGISTERS_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
class Record;
|
class Record;
|
||||||
|
@ -31,7 +32,14 @@ namespace llvm {
|
||||||
|
|
||||||
|
|
||||||
struct CodeGenRegisterClass {
|
struct CodeGenRegisterClass {
|
||||||
|
Record *TheDef;
|
||||||
|
std::vector<Record*> Elements;
|
||||||
|
unsigned SpillSize;
|
||||||
|
unsigned SpillAlignment;
|
||||||
|
|
||||||
|
const std::string &getName() const;
|
||||||
|
|
||||||
|
CodeGenRegisterClass(Record *R);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,6 +121,38 @@ const std::string &CodeGenRegister::getName() const {
|
||||||
return TheDef->getName();
|
return TheDef->getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CodeGenTarget::ReadRegisterClasses() const {
|
||||||
|
std::vector<Record*> RegClasses =
|
||||||
|
Records.getAllDerivedDefinitions("RegisterClass");
|
||||||
|
if (RegClasses.empty())
|
||||||
|
throw std::string("No 'RegisterClass' subclasses defined!");
|
||||||
|
|
||||||
|
RegisterClasses.reserve(RegClasses.size());
|
||||||
|
RegisterClasses.assign(RegClasses.begin(), RegClasses.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
CodeGenRegisterClass::CodeGenRegisterClass(Record *R) : TheDef(R) {
|
||||||
|
SpillSize = R->getValueAsInt("Size");
|
||||||
|
SpillAlignment = R->getValueAsInt("Alignment");
|
||||||
|
|
||||||
|
ListInit *RegList = R->getValueAsListInit("MemberList");
|
||||||
|
for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) {
|
||||||
|
DefInit *RegDef = dynamic_cast<DefInit*>(RegList->getElement(i));
|
||||||
|
if (!RegDef) throw "Register class member is not a record!";
|
||||||
|
Record *Reg = RegDef->getDef();
|
||||||
|
|
||||||
|
if (!Reg->isSubClassOf("Register"))
|
||||||
|
throw "Register Class member '" + Reg->getName() +
|
||||||
|
"' does not derive from the Register class!";
|
||||||
|
Elements.push_back(Reg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string &CodeGenRegisterClass::getName() const {
|
||||||
|
return TheDef->getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void CodeGenTarget::ReadInstructions() const {
|
void CodeGenTarget::ReadInstructions() const {
|
||||||
std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
|
std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
|
||||||
|
|
|
@ -46,8 +46,10 @@ class CodeGenTarget {
|
||||||
|
|
||||||
mutable std::map<std::string, CodeGenInstruction> Instructions;
|
mutable std::map<std::string, CodeGenInstruction> Instructions;
|
||||||
mutable std::vector<CodeGenRegister> Registers;
|
mutable std::vector<CodeGenRegister> Registers;
|
||||||
void ReadInstructions() const;
|
mutable std::vector<CodeGenRegisterClass> RegisterClasses;
|
||||||
void ReadRegisters() const;
|
void ReadRegisters() const;
|
||||||
|
void ReadRegisterClasses() const;
|
||||||
|
void ReadInstructions() const;
|
||||||
public:
|
public:
|
||||||
CodeGenTarget();
|
CodeGenTarget();
|
||||||
|
|
||||||
|
@ -73,6 +75,12 @@ public:
|
||||||
return Registers;
|
return Registers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<CodeGenRegisterClass> getRegisterClasses() {
|
||||||
|
if (RegisterClasses.empty()) ReadRegisterClasses();
|
||||||
|
return RegisterClasses;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// getInstructions - Return all of the instructions defined for this target.
|
/// getInstructions - Return all of the instructions defined for this target.
|
||||||
///
|
///
|
||||||
const std::map<std::string, CodeGenInstruction> &getInstructions() const {
|
const std::map<std::string, CodeGenInstruction> &getInstructions() const {
|
||||||
|
|
|
@ -85,8 +85,8 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
|
||||||
// a set of registers which belong to a register class, this is to ensure that
|
// a set of registers which belong to a register class, this is to ensure that
|
||||||
// each register is only in a single register class.
|
// each register is only in a single register class.
|
||||||
//
|
//
|
||||||
std::vector<Record*> RegisterClasses =
|
const std::vector<CodeGenRegisterClass> &RegisterClasses =
|
||||||
Records.getAllDerivedDefinitions("RegisterClass");
|
Target.getRegisterClasses();
|
||||||
|
|
||||||
std::set<Record*> RegistersFound;
|
std::set<Record*> RegistersFound;
|
||||||
std::vector<std::string> RegClassNames;
|
std::vector<std::string> RegClassNames;
|
||||||
|
@ -95,9 +95,9 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
|
||||||
OS << "namespace { // Register classes...\n";
|
OS << "namespace { // Register classes...\n";
|
||||||
|
|
||||||
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
|
for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
|
||||||
Record *RC = RegisterClasses[rc];
|
const CodeGenRegisterClass &RC = RegisterClasses[rc];
|
||||||
|
|
||||||
std::string Name = RC->getName();
|
std::string Name = RC.getName();
|
||||||
if (Name.size() > 9 && Name[9] == '.') {
|
if (Name.size() > 9 && Name[9] == '.') {
|
||||||
static unsigned AnonCounter = 0;
|
static unsigned AnonCounter = 0;
|
||||||
Name = "AnonRegClass_"+utostr(AnonCounter++);
|
Name = "AnonRegClass_"+utostr(AnonCounter++);
|
||||||
|
@ -108,14 +108,8 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
|
||||||
// Emit the register list now...
|
// Emit the register list now...
|
||||||
OS << " // " << Name << " Register Class...\n const unsigned " << Name
|
OS << " // " << Name << " Register Class...\n const unsigned " << Name
|
||||||
<< "[] = {\n ";
|
<< "[] = {\n ";
|
||||||
ListInit *RegList = RC->getValueAsListInit("MemberList");
|
for (unsigned i = 0, e = RC.Elements.size(); i != e; ++i) {
|
||||||
for (unsigned i = 0, e = RegList->getSize(); i != e; ++i) {
|
Record *Reg = RC.Elements[i];
|
||||||
DefInit *RegDef = dynamic_cast<DefInit*>(RegList->getElement(i));
|
|
||||||
if (!RegDef) throw "Register class member is not a record!";
|
|
||||||
Record *Reg = RegDef->getDef();
|
|
||||||
if (!Reg->isSubClassOf("Register"))
|
|
||||||
throw "Register Class member '" + Reg->getName() +
|
|
||||||
" does not derive from the Register class!";
|
|
||||||
if (RegistersFound.count(Reg))
|
if (RegistersFound.count(Reg))
|
||||||
throw "Register '" + Reg->getName() +
|
throw "Register '" + Reg->getName() +
|
||||||
"' included in multiple register classes!";
|
"' included in multiple register classes!";
|
||||||
|
@ -126,15 +120,15 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
|
||||||
|
|
||||||
OS << " struct " << Name << "Class : public TargetRegisterClass {\n"
|
OS << " struct " << Name << "Class : public TargetRegisterClass {\n"
|
||||||
<< " " << Name << "Class() : TargetRegisterClass("
|
<< " " << Name << "Class() : TargetRegisterClass("
|
||||||
<< RC->getValueAsInt("Size")/8 << ", " << RC->getValueAsInt("Alignment")
|
<< RC.SpillSize/8 << ", " << RC.SpillAlignment << ", " << Name << ", "
|
||||||
<< ", " << Name << ", " << Name << " + " << RegList->getSize()
|
<< Name << " + " << RC.Elements.size() << ") {}\n";
|
||||||
<< ") {}\n";
|
|
||||||
|
|
||||||
if (CodeInit *CI = dynamic_cast<CodeInit*>(RC->getValueInit("Methods")))
|
if (CodeInit *CI =
|
||||||
|
dynamic_cast<CodeInit*>(RC.TheDef->getValueInit("Methods")))
|
||||||
OS << CI->getValue();
|
OS << CI->getValue();
|
||||||
else
|
else
|
||||||
throw "Expected 'code' fragment for 'Methods' value in register class '"+
|
throw "Expected 'code' fragment for 'Methods' value in register class '"+
|
||||||
RC->getName() + "'!";
|
RC.getName() + "'!";
|
||||||
|
|
||||||
OS << " } " << Name << "Instance;\n\n";
|
OS << " } " << Name << "Instance;\n\n";
|
||||||
}
|
}
|
||||||
|
@ -215,7 +209,7 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
|
||||||
|
|
||||||
OS << "namespace " << Target.getName() << " { // Register classes\n";
|
OS << "namespace " << Target.getName() << " { // Register classes\n";
|
||||||
for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) {
|
for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) {
|
||||||
const std::string &Name = RegisterClasses[i]->getName();
|
const std::string &Name = RegisterClasses[i].getName();
|
||||||
if (Name.size() < 9 || Name[9] != '.') // Ignore anonymous classes
|
if (Name.size() < 9 || Name[9] != '.') // Ignore anonymous classes
|
||||||
OS << " TargetRegisterClass *" << Name << "RegisterClass = &"
|
OS << " TargetRegisterClass *" << Name << "RegisterClass = &"
|
||||||
<< Name << "Instance;\n";
|
<< Name << "Instance;\n";
|
||||||
|
|
Loading…
Reference in New Issue