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