[llvm-commits] CVS: llvm/utils/TableGen/IntrinsicEmitter.cpp

Chris Lattner lattner at cs.uiuc.edu
Thu Mar 30 20:25:10 PST 2006



Changes in directory llvm/utils/TableGen:

IntrinsicEmitter.cpp updated: 1.17 -> 1.18
---
Log message:

When emitting code for the verifier, instead of emitting each case statement
independently, batch up checks so that identically typed intrinsics share
verifier code.  This dramatically reduces the size of the verifier function,
which should help avoid GCC running out of memory compiling Verifier.cpp.


---
Diffs of the changes:  (+42 -9)

 IntrinsicEmitter.cpp |   51 ++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 42 insertions(+), 9 deletions(-)


Index: llvm/utils/TableGen/IntrinsicEmitter.cpp
diff -u llvm/utils/TableGen/IntrinsicEmitter.cpp:1.17 llvm/utils/TableGen/IntrinsicEmitter.cpp:1.18
--- llvm/utils/TableGen/IntrinsicEmitter.cpp:1.17	Tue Mar 28 16:25:56 2006
+++ llvm/utils/TableGen/IntrinsicEmitter.cpp	Thu Mar 30 22:24:58 2006
@@ -127,22 +127,55 @@
   }
 }
 
+/// RecordListComparator - Provide a determinstic comparator for lists of
+/// records.
+namespace {
+  struct RecordListComparator {
+    bool operator()(const std::vector<Record*> &LHS,
+                    const std::vector<Record*> &RHS) const {
+      unsigned i = 0;
+      do {
+        if (i == RHS.size()) return false;  // RHS is shorter than LHS.
+        if (LHS[i] != RHS[i])
+          return LHS[i]->getName() < RHS[i]->getName();
+      } while (++i != LHS.size());
+      
+      return i != RHS.size();
+    }
+  };
+}
+
 void IntrinsicEmitter::EmitVerifier(const std::vector<CodeGenIntrinsic> &Ints, 
                                     std::ostream &OS) {
   OS << "// Verifier::visitIntrinsicFunctionCall code.\n";
   OS << "#ifdef GET_INTRINSIC_VERIFIER\n";
   OS << "  switch (ID) {\n";
   OS << "  default: assert(0 && \"Invalid intrinsic!\");\n";
-  for (unsigned i = 0, e = Ints.size(); i != e; ++i) {
-    OS << "  case Intrinsic::" << Ints[i].EnumName << ":\t\t// "
-       << Ints[i].Name << "\n";
-    OS << "    Assert1(FTy->getNumParams() == " << Ints[i].ArgTypes.size()-1
-       << ",\n"
+  
+  // This checking can emit a lot of very common code.  To reduce the amount of
+  // code that we emit, batch up cases that have identical types.  This avoids
+  // problems where GCC can run out of memory compiling Verifier.cpp.
+  typedef std::map<std::vector<Record*>, std::vector<unsigned>, 
+    RecordListComparator> MapTy;
+  MapTy UniqueArgInfos;
+  
+  // Compute the unique argument type info.
+  for (unsigned i = 0, e = Ints.size(); i != e; ++i)
+    UniqueArgInfos[Ints[i].ArgTypeDefs].push_back(i);
+
+  // Loop through the array, emitting one comparison for each batch.
+  for (MapTy::iterator I = UniqueArgInfos.begin(),
+       E = UniqueArgInfos.end(); I != E; ++I) {
+    for (unsigned i = 0, e = I->second.size(); i != e; ++i) {
+      OS << "  case Intrinsic::" << Ints[I->second[i]].EnumName << ":\t\t// "
+         << Ints[I->second[i]].Name << "\n";
+    }
+    const std::vector<Record*> &ArgTypes = I->first;
+    OS << "    Assert1(FTy->getNumParams() == " << ArgTypes.size()-1 << ",\n"
        << "            \"Illegal # arguments for intrinsic function!\", IF);\n";
-    EmitTypeVerify(OS, "FTy->getReturnType()", Ints[i].ArgTypeDefs[0]);
-    for (unsigned j = 1; j != Ints[i].ArgTypes.size(); ++j)
-      EmitTypeVerify(OS, "FTy->getParamType(" + utostr(j-1) + ")",
-                     Ints[i].ArgTypeDefs[j]);
+    EmitTypeVerify(OS, "FTy->getReturnType()", ArgTypes[0]);
+    for (unsigned j = 1; j != ArgTypes.size(); ++j)
+      EmitTypeVerify(OS, "FTy->getParamType(" + utostr(j-1) + ")", ArgTypes[j]);
     OS << "    break;\n";
   }
   OS << "  }\n";






More information about the llvm-commits mailing list