diff options
author | Chris Lattner <sabre@nondot.org> | 2004-08-21 04:05:00 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-08-21 04:05:00 +0000 |
commit | 056afeface2ac98664ed8fa4799b46178a4a6fe3 (patch) | |
tree | b20825736e75aae16c585715fa1f6feab2fe5233 | |
parent | 7a680c60646fb3b06085f1fe6a7a1917c35010c6 (diff) | |
download | external_llvm-056afeface2ac98664ed8fa4799b46178a4a6fe3.zip external_llvm-056afeface2ac98664ed8fa4799b46178a4a6fe3.tar.gz external_llvm-056afeface2ac98664ed8fa4799b46178a4a6fe3.tar.bz2 |
Start parsing register classes into a more structured form
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15961 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | utils/TableGen/CodeGenRegisters.h | 8 | ||||
-rw-r--r-- | utils/TableGen/CodeGenTarget.cpp | 32 | ||||
-rw-r--r-- | utils/TableGen/CodeGenTarget.h | 10 | ||||
-rw-r--r-- | utils/TableGen/RegisterInfoEmitter.cpp | 30 |
4 files changed, 61 insertions, 19 deletions
diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h index ba89190..bbec4ea 100644 --- a/utils/TableGen/CodeGenRegisters.h +++ b/utils/TableGen/CodeGenRegisters.h @@ -16,6 +16,7 @@ #define CODEGEN_REGISTERS_H #include <string> +#include <vector> namespace llvm { class Record; @@ -31,7 +32,14 @@ namespace llvm { struct CodeGenRegisterClass { + Record *TheDef; + std::vector<Record*> Elements; + unsigned SpillSize; + unsigned SpillAlignment; + + const std::string &getName() const; + CodeGenRegisterClass(Record *R); }; } diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp index c495519..e0d585c 100644 --- a/utils/TableGen/CodeGenTarget.cpp +++ b/utils/TableGen/CodeGenTarget.cpp @@ -121,6 +121,38 @@ const std::string &CodeGenRegister::getName() const { 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 { std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction"); diff --git a/utils/TableGen/CodeGenTarget.h b/utils/TableGen/CodeGenTarget.h index 2d65b7b..9b338d8 100644 --- a/utils/TableGen/CodeGenTarget.h +++ b/utils/TableGen/CodeGenTarget.h @@ -46,8 +46,10 @@ class CodeGenTarget { mutable std::map<std::string, CodeGenInstruction> Instructions; mutable std::vector<CodeGenRegister> Registers; - void ReadInstructions() const; + mutable std::vector<CodeGenRegisterClass> RegisterClasses; void ReadRegisters() const; + void ReadRegisterClasses() const; + void ReadInstructions() const; public: CodeGenTarget(); @@ -73,6 +75,12 @@ public: return Registers; } + const std::vector<CodeGenRegisterClass> getRegisterClasses() { + if (RegisterClasses.empty()) ReadRegisterClasses(); + return RegisterClasses; + } + + /// getInstructions - Return all of the instructions defined for this target. /// const std::map<std::string, CodeGenInstruction> &getInstructions() const { diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index 4ed1a0f..6763af3 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -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 // each register is only in a single register class. // - std::vector<Record*> RegisterClasses = - Records.getAllDerivedDefinitions("RegisterClass"); + const std::vector<CodeGenRegisterClass> &RegisterClasses = + Target.getRegisterClasses(); std::set<Record*> RegistersFound; std::vector<std::string> RegClassNames; @@ -95,9 +95,9 @@ void RegisterInfoEmitter::run(std::ostream &OS) { OS << "namespace { // Register classes...\n"; 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] == '.') { static unsigned AnonCounter = 0; Name = "AnonRegClass_"+utostr(AnonCounter++); @@ -108,14 +108,8 @@ void RegisterInfoEmitter::run(std::ostream &OS) { // Emit the register list now... OS << " // " << Name << " Register Class...\n const unsigned " << Name << "[] = {\n "; - ListInit *RegList = RC->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!"; + for (unsigned i = 0, e = RC.Elements.size(); i != e; ++i) { + Record *Reg = RC.Elements[i]; if (RegistersFound.count(Reg)) throw "Register '" + Reg->getName() + "' included in multiple register classes!"; @@ -126,15 +120,15 @@ void RegisterInfoEmitter::run(std::ostream &OS) { OS << " struct " << Name << "Class : public TargetRegisterClass {\n" << " " << Name << "Class() : TargetRegisterClass(" - << RC->getValueAsInt("Size")/8 << ", " << RC->getValueAsInt("Alignment") - << ", " << Name << ", " << Name << " + " << RegList->getSize() - << ") {}\n"; + << RC.SpillSize/8 << ", " << RC.SpillAlignment << ", " << Name << ", " + << Name << " + " << RC.Elements.size() << ") {}\n"; - if (CodeInit *CI = dynamic_cast<CodeInit*>(RC->getValueInit("Methods"))) + if (CodeInit *CI = + dynamic_cast<CodeInit*>(RC.TheDef->getValueInit("Methods"))) OS << CI->getValue(); else throw "Expected 'code' fragment for 'Methods' value in register class '"+ - RC->getName() + "'!"; + RC.getName() + "'!"; OS << " } " << Name << "Instance;\n\n"; } @@ -215,7 +209,7 @@ void RegisterInfoEmitter::run(std::ostream &OS) { OS << "namespace " << Target.getName() << " { // Register classes\n"; 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 OS << " TargetRegisterClass *" << Name << "RegisterClass = &" << Name << "Instance;\n"; |