Switch TargetRegisterInfo::getSubReg() to use a lookup table.
authorJim Grosbach <grosbach@apple.com>
Wed, 29 Feb 2012 20:31:17 +0000 (20:31 +0000)
committerJim Grosbach <grosbach@apple.com>
Wed, 29 Feb 2012 20:31:17 +0000 (20:31 +0000)
Instead of nested switch statements, use a lookup table. On ARM, this replaces
a 23k (x86_64 release build) function with a 16k table. Its not unlikely to
be faster, as well.

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

utils/TableGen/RegisterInfoEmitter.cpp

index d33b0b229d5b266c7c60e26f624f89479a2bfcc6..0c5c1c6e2cb91bd38a5e85c7c381dc744314ccea 100644 (file)
@@ -735,28 +735,44 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
 
   std::string ClassName = Target.getName() + "GenRegisterInfo";
 
+  // Emit the data table for getSubReg().
+  if (SubRegIndices.size()) {
+    OS << "static const unsigned short " << TargetName << "SubRegTable[]["
+      << SubRegIndices.size() << "] = {\n";
+    for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
+      const CodeGenRegister::SubRegMap &SRM = Regs[i]->getSubRegs();
+      OS << "  /* " << Regs[i]->TheDef->getName() << " */\n";
+      if (SRM.empty()) {
+        OS << "  {0},\n";
+        continue;
+      }
+      OS << "  {";
+      for (unsigned j = 0, je = SubRegIndices.size(); j != je; ++j) {
+        // FIXME: We really should keep this to 80 columns...
+        CodeGenRegister::SubRegMap::const_iterator SubReg =
+          SRM.find(SubRegIndices[j]);
+        if (SubReg != SRM.end())
+          OS << getQualifiedName(SubReg->second->TheDef);
+        else
+          OS << "0";
+        if (j != je - 1)
+          OS << ", ";
+      }
+      OS << "}" << (i != e ? "," : "") << "\n";
+    }
+    OS << "};\n\n";
+  }
+
   // Emit the subregister + index mapping function based on the information
   // calculated above.
   OS << "unsigned " << ClassName
      << "::getSubReg(unsigned RegNo, unsigned Index) const {\n"
-     << "  switch (RegNo) {\n"
-     << "  default:\n    return 0;\n";
-  for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
-    const CodeGenRegister::SubRegMap &SRM = Regs[i]->getSubRegs();
-    if (SRM.empty())
-      continue;
-    OS << "  case " << getQualifiedName(Regs[i]->TheDef) << ":\n";
-    OS << "    switch (Index) {\n";
-    OS << "    default: return 0;\n";
-    for (CodeGenRegister::SubRegMap::const_iterator ii = SRM.begin(),
-         ie = SRM.end(); ii != ie; ++ii)
-      OS << "    case " << ii->first->getQualifiedName()
-         << ": return " << getQualifiedName(ii->second->TheDef) << ";\n";
-    OS << "    };\n" << "    break;\n";
-  }
-  OS << "  };\n";
-  OS << "  return 0;\n";
-  OS << "}\n\n";
+     << "  assert(RegNo > 0 && Index > 0 && \"invalid subreg query!\");\n";
+  if (SubRegIndices.size())
+     OS << "  return " << TargetName << "SubRegTable[RegNo - 1][Index - 1];\n"
+        << "}\n\n";
+  else
+    OS << "  return 0;\n}\n\n";
 
   OS << "unsigned " << ClassName
      << "::getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const {\n"