Add support to tablegen for specifying subregister classes on a per register class...
authorChristopher Lamb <christopher.lamb@gmail.com>
Wed, 13 Jun 2007 22:20:15 +0000 (22:20 +0000)
committerChristopher Lamb <christopher.lamb@gmail.com>
Wed, 13 Jun 2007 22:20:15 +0000 (22:20 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37572 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/MRegisterInfo.h
lib/Target/Target.td
utils/TableGen/CodeGenRegisters.h
utils/TableGen/CodeGenTarget.cpp
utils/TableGen/RegisterInfoEmitter.cpp

index 723ab69bd13fe6560ba9244ab6b5b1a4979ca7e9..ea10c1cc47bfb91d87102a8dba73c225adca1ff9 100644 (file)
@@ -64,6 +64,7 @@ private:
   const vt_iterator VTs;
   const sc_iterator SubClasses;
   const sc_iterator SuperClasses;
+  const sc_iterator SubRegClasses;
   const unsigned RegSize, Alignment;    // Size & Alignment of register in bytes
   const iterator RegsBegin, RegsEnd;
 public:
@@ -71,8 +72,10 @@ public:
                       const MVT::ValueType *vts,
                       const TargetRegisterClass * const *subcs,
                       const TargetRegisterClass * const *supcs,
+                      const TargetRegisterClass * const *subregcs,
                       unsigned RS, unsigned Al, iterator RB, iterator RE)
     : ID(id), VTs(vts), SubClasses(subcs), SuperClasses(supcs),
+    SubRegClasses(subregcs),
     RegSize(RS), Alignment(Al), RegsBegin(RB), RegsEnd(RE) {}
   virtual ~TargetRegisterClass() {}     // Allow subclasses
   
@@ -167,6 +170,47 @@ public:
     return I;
   }
   
+  /// hasSubRegForClass - return true if the specified TargetRegisterClass is a
+  /// class of a sub-register class for this TargetRegisterClass.
+  bool hasSubRegForClass(const TargetRegisterClass *cs) const {
+    for (int i = 0; SubRegClasses[i] != NULL; ++i) 
+      if (SubRegClasses[i] == cs)
+        return true;
+    return false;
+  }
+
+  /// hasClassForSubReg - return true if the specified TargetRegisterClass is a
+  /// class of a sub-register class for this TargetRegisterClass.
+  bool hasClassForSubReg(unsigned SubReg) const {
+    --SubReg;
+    for (unsigned i = 0; SubRegClasses[i] != NULL; ++i) 
+      if (i == SubReg)
+        return true;
+    return false;
+  }
+
+  /// getClassForSubReg - return theTargetRegisterClass for the sub-register
+  /// at idx for this TargetRegisterClass.
+  sc_iterator getClassForSubReg(unsigned SubReg) const {
+    --SubReg;
+    for (unsigned i = 0; SubRegClasses[i] != NULL; ++i) 
+      if (i == SubReg)
+        return &SubRegClasses[i];
+    return NULL;
+  }
+  
+  /// subregclasses_begin / subregclasses_end - Loop over all of
+  /// the subregister classes of this register class.
+  sc_iterator subregclasses_begin() const {
+    return SubRegClasses;
+  }
+  
+  sc_iterator subregclasses_end() const {
+    sc_iterator I = SubRegClasses;
+    while (*I != NULL) ++I;
+    return I;
+  }
+  
   /// allocation_order_begin/end - These methods define a range of registers
   /// which specify the registers in this class that are valid to register
   /// allocate, and the preferred order to allocate them in.  For example,
index d646e28c1d1f7f1eae76956a5d75cdaf18f24216..4babef15747d22d016248dd48bf5757dbda4bbfd 100644 (file)
@@ -109,6 +109,10 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
   // allocation used by the register allocator.
   //
   list<Register> MemberList = regList;
+  
+  // SubClassList - Specify which register classes correspond to subregisters
+  // of this class. The order should be by subregister set index.
+  list<RegisterClass> SubRegClassList = [];
 
   // MethodProtos/MethodBodies - These members can be used to insert arbitrary
   // code into a generated register class.   The normal usage of this is to 
index 8e9008c74aad69c3bac5e078008a1abda0752aff..83c85b8f3a945c5664bbc30d9b90ad24715632f9 100644 (file)
@@ -38,6 +38,7 @@ namespace llvm {
     std::vector<MVT::ValueType> VTs;
     unsigned SpillSize;
     unsigned SpillAlignment;
+    std::vector<Record*> SubRegClasses;
     std::string MethodProtos, MethodBodies;
 
     const std::string &getName() const;
index 17cea6f2a611aec0cc0b9a394d527a07d34b438d..c3c1ac22717202557f2ed133c22bcb53a4204fa7 100644 (file)
@@ -199,6 +199,16 @@ CodeGenRegisterClass::CodeGenRegisterClass(Record *R) : TheDef(R) {
     Elements.push_back(Reg);
   }
   
+  std::vector<Record*> SubRegClassList = 
+                        R->getValueAsListOfDefs("SubRegClassList");
+  for (unsigned i = 0, e = SubRegClassList.size(); i != e; ++i) {
+    Record *SubRegClass = SubRegClassList[i];
+    if (!SubRegClass->isSubClassOf("RegisterClass"))
+      throw "Register Class member '" + SubRegClass->getName() +
+            "' does not derive from the RegisterClass class!";
+    SubRegClasses.push_back(SubRegClass);
+  }  
+  
   // Allow targets to override the size in bits of the RegisterClass.
   unsigned Size = R->getValueAsInt("Size");
 
index 5fbd013eaaf07c0c4e017d15098d62beca150bda..a2269a83fc719870fe3f985847f24eeb4d2729b7 100644 (file)
@@ -224,6 +224,44 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
          
     std::map<unsigned, std::set<unsigned> > SuperClassMap;
     OS << "\n";
+    
+    
+    // Emit the sub-register classes for each RegisterClass
+    for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
+      const CodeGenRegisterClass &RC = RegisterClasses[rc];
+
+      // Give the register class a legal C name if it's anonymous.
+      std::string Name = RC.TheDef->getName();
+
+      OS << "  // " << Name 
+         << " Sub-register Classess...\n"
+         << "  static const TargetRegisterClass* const "
+         << Name << "SubRegClasses [] = {\n    ";
+
+      bool Empty = true;
+      
+      for (unsigned subrc = 0, e2 = RC.SubRegClasses.size();
+            subrc != e2; ++subrc) {
+        unsigned rc2 = 0, e2 = RegisterClasses.size();
+        for (; rc2 != e2; ++rc2) {
+          const CodeGenRegisterClass &RC2 =  RegisterClasses[rc2];
+          if (RC.SubRegClasses[subrc]->getName() == RC2.getName()) {
+            if (!Empty) OS << ", ";
+              OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass";
+            Empty = false;
+            break;
+          }
+        }
+        if (rc2 == e2)
+          throw "Register Class member '" + 
+            RC.SubRegClasses[subrc]->getName() + 
+            "' is not a valid RegisterClass!";
+      }
+
+      OS << (!Empty ? ", " : "") << "NULL";
+      OS << "\n  };\n\n";
+    }
+    
     // Emit the sub-classes array for each RegisterClass
     for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
       const CodeGenRegisterClass &RC = RegisterClasses[rc];
@@ -304,6 +342,7 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
          << RC.getName() + "VTs" << ", "
          << RC.getName() + "Subclasses" << ", "
          << RC.getName() + "Superclasses" << ", "
+         << RC.getName() + "SubRegClasses" << ", "
          << RC.SpillSize/8 << ", "
          << RC.SpillAlignment/8 << ", " << RC.getName() << ", "
          << RC.getName() << " + " << RC.Elements.size() << ") {}\n";