Start parsing register classes into a more structured form

llvm-svn: 15961
This commit is contained in:
Chris Lattner 2004-08-21 04:05:00 +00:00
parent e34ae99942
commit 2a86fab933
4 changed files with 61 additions and 19 deletions

View File

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

View File

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

View File

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

View File

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