Start parsing register classes into a more structured form
authorChris Lattner <sabre@nondot.org>
Sat, 21 Aug 2004 04:05:00 +0000 (04:05 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 21 Aug 2004 04:05:00 +0000 (04:05 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15961 91177308-0d34-0410-b5e6-96231b3b80d8

utils/TableGen/CodeGenRegisters.h
utils/TableGen/CodeGenTarget.cpp
utils/TableGen/CodeGenTarget.h
utils/TableGen/RegisterInfoEmitter.cpp

index ba89190325d6a199a027856653ffe5c3186eee8d..bbec4ea6706d1ee19a43bcb448339586a29d909c 100644 (file)
@@ -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);
   };
 }
 
index c495519e58dc360836556f308ac5c50f20aa3770..e0d585c6187a10440257a819bb1be2452724fa68 100644 (file)
@@ -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");
index 2d65b7be8eaf6ceca2a93e8883f9ea70beceb228..9b338d88c9fea73becc60b8a1c486df673c95129 100644 (file)
@@ -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 {
index 4ed1a0fe8c596706ba976bdb749deccd07be162a..6763af3f65bcef8175bce2998a3de1c1c65107d4 100644 (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
   // 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";