Teach TableGen to automatically generate missing SubRegIndex instances.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Sat, 7 May 2011 21:22:39 +0000 (21:22 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Sat, 7 May 2011 21:22:39 +0000 (21:22 +0000)
The RegisterInfo.td file should only specify the indexes that sources need to
refer to. The rest is inferred.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131058 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 57f7fdc4dc49abeb5d6f3cc74be1fb937029a552..0328c9ac917e4949b0faa2fbfb10978087281fc4 100644 (file)
@@ -98,14 +98,14 @@ std::string llvm::getEnumName(MVT::SimpleValueType T) {
 /// namespace qualifier if the record contains one.
 ///
 std::string llvm::getQualifiedName(const Record *R) {
-  std::string Namespace = R->getValueAsString("Namespace");
+  std::string Namespace;
+  if (R->getValue("Namespace"))
+     Namespace = R->getValueAsString("Namespace");
   if (Namespace.empty()) return R->getName();
   return Namespace + "::" + R->getName();
 }
 
 
-
-
 /// getTarget - Return the current instance of the Target class.
 ///
 CodeGenTarget::CodeGenTarget(RecordKeeper &records) : Records(records) {
@@ -182,6 +182,13 @@ void CodeGenTarget::ReadSubRegIndices() const {
   std::sort(SubRegIndices.begin(), SubRegIndices.end(), LessRecord());
 }
 
+Record *CodeGenTarget::createSubRegIndex(const std::string &Name) {
+  Record *R = new Record(Name, SMLoc(), Records);
+  Records.addDef(R);
+  SubRegIndices.push_back(R);
+  return R;
+}
+
 void CodeGenTarget::ReadRegisterClasses() const {
   std::vector<Record*> RegClasses =
     Records.getAllDerivedDefinitions("RegisterClass");
index 4e041548f5f1413ff6c846e29f7d55da232de947..891b2d524c7de942e3cd38ff2b098a1defc50298 100644 (file)
@@ -121,6 +121,9 @@ public:
     return (i - SubRegIndices.begin()) + 1;
   }
 
+  // Create a new SubRegIndex with the given name.
+  Record *createSubRegIndex(const std::string &Name);
+
   const std::vector<CodeGenRegisterClass> &getRegisterClasses() const {
     if (RegisterClasses.empty()) ReadRegisterClasses();
     return RegisterClasses;
index 4ddc47d5519a0927725dfee047268263ee44d11e..053d926265443707ebb4ab40ff7288968931d69a 100644 (file)
@@ -56,7 +56,7 @@ void RegisterInfoEmitter::runEnums(raw_ostream &OS) {
     OS << "enum {\n  NoSubRegister,\n";
     for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i)
       OS << "  " << SubRegIndices[i]->getName() << ",\t// " << i+1 << "\n";
-    OS << "  NUM_TARGET_SUBREGS = " << SubRegIndices.size()+1 << "\n";
+    OS << "  NUM_TARGET_NAMED_SUBREGS = " << SubRegIndices.size()+1 << "\n";
     OS << "};\n";
     if (!Namespace.empty())
       OS << "}\n";
@@ -172,7 +172,7 @@ struct RegisterMaps {
   typedef std::map<Record*, SubRegMap> SubRegMaps;
 
   SubRegMaps SubReg;
-  SubRegMap &inferSubRegIndices(Record *Reg);
+  SubRegMap &inferSubRegIndices(Record *Reg, CodeGenTarget &);
 
   // Composite SubRegIndex instances.
   // Map (SubRegIndex,SubRegIndex) -> SubRegIndex
@@ -185,7 +185,8 @@ struct RegisterMaps {
 };
 
 // Calculate all subregindices for Reg. Loopy subregs cause infinite recursion.
-RegisterMaps::SubRegMap &RegisterMaps::inferSubRegIndices(Record *Reg) {
+RegisterMaps::SubRegMap &RegisterMaps::inferSubRegIndices(Record *Reg,
+                                                        CodeGenTarget &Target) {
   SubRegMap &SRM = SubReg[Reg];
   if (!SRM.empty())
     return SRM;
@@ -199,7 +200,7 @@ RegisterMaps::SubRegMap &RegisterMaps::inferSubRegIndices(Record *Reg) {
     if (!SRM.insert(std::make_pair(Indices[i], SubRegs[i])).second)
       throw "SubRegIndex " + Indices[i]->getName()
         + " appears twice in Register " + Reg->getName();
-    inferSubRegIndices(SubRegs[i]);
+    inferSubRegIndices(SubRegs[i], Target);
   }
 
   // Keep track of inherited subregs and how they can be reached.
@@ -248,18 +249,17 @@ RegisterMaps::SubRegMap &RegisterMaps::inferSubRegIndices(Record *Reg) {
     Orphans.erase(R2);
   }
 
-  // Now, Orphans contains the inherited subregisters without a direct index.
-  if (!Orphans.empty()) {
-    errs() << "Error: Register " << getQualifiedName(Reg)
-           << " inherited subregisters without an index:\n";
-    for (OrphanMap::iterator i = Orphans.begin(), e = Orphans.end(); i != e;
-         ++i) {
-      errs() << "  " << getQualifiedName(i->first)
-             << " = " << i->second.first->getName()
-             << ", " << i->second.second->getName() << "\n";
-    }
-    abort();
+  // Now Orphans contains the inherited subregisters without a direct index.
+  // Create inferred indexes for all missing entries.
+  for (OrphanMap::iterator I = Orphans.begin(), E = Orphans.end(); I != E;
+       ++I) {
+    Record *&Comp = Composite[I->second];
+    if (!Comp)
+      Comp = Target.createSubRegIndex(I->second.first->getName() + "_then_" +
+                                      I->second.second->getName());
+    SRM[Comp] = I->first;
   }
+
   return SRM;
 }
 
@@ -861,6 +861,13 @@ void RegisterInfoEmitter::run(raw_ostream &OS) {
   }
   OS << "  };\n";      // End of register descriptors...
 
+  // Calculate the mapping of subregister+index pairs to physical registers.
+  // This will also create further anonymous indexes.
+  unsigned NamedIndices = Target.getSubRegIndices().size();
+  RegisterMaps RegMaps;
+  for (unsigned i = 0, e = Regs.size(); i != e; ++i)
+    RegMaps.inferSubRegIndices(Regs[i].TheDef, Target);
+
   // Emit SubRegIndex names, skipping 0
   const std::vector<Record*> SubRegIndices = Target.getSubRegIndices();
   OS << "\n  const char *const SubRegIndexTable[] = { \"";
@@ -870,13 +877,21 @@ void RegisterInfoEmitter::run(raw_ostream &OS) {
       OS << "\", \"";
   }
   OS << "\" };\n\n";
+
+  // Emit names of the anonymus subreg indexes.
+  if (SubRegIndices.size() > NamedIndices) {
+    OS << "  enum {";
+    for (unsigned i = NamedIndices, e = SubRegIndices.size(); i != e; ++i) {
+      OS << "\n    " << SubRegIndices[i]->getName() << " = " << i+1;
+      if (i+1 != e)
+        OS << ',';
+    }
+    OS << "\n  };\n\n";
+  }
   OS << "}\n\n";       // End of anonymous namespace...
 
   std::string ClassName = Target.getName() + "GenRegisterInfo";
 
-  // Calculate the mapping of subregister+index pairs to physical registers.
-  RegisterMaps RegMaps;
-
   // Emit the subregister + index mapping function based on the information
   // calculated above.
   OS << "unsigned " << ClassName
@@ -884,7 +899,7 @@ void RegisterInfoEmitter::run(raw_ostream &OS) {
      << "  switch (RegNo) {\n"
      << "  default:\n    return 0;\n";
   for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
-    RegisterMaps::SubRegMap &SRM = RegMaps.inferSubRegIndices(Regs[i].TheDef);
+    RegisterMaps::SubRegMap &SRM = RegMaps.SubReg[Regs[i].TheDef];
     if (SRM.empty())
       continue;
     OS << "  case " << getQualifiedName(Regs[i].TheDef) << ":\n";