[llvm-commits] CVS: llvm/lib/AsmParser/llvmAsmParser.y

Chris Lattner lattner at cs.uiuc.edu
Mon Feb 9 15:04:05 PST 2004


Changes in directory llvm/lib/AsmParser:

llvmAsmParser.y updated: 1.155 -> 1.156

---
Log message:

It turns out that the two dimensional vectors were causing big slowdowns
in this for programs with lots of types (like the testcase in PR224).
The problem was that the type ID that the outer vector was using was not
very dense (as many types are getting resolved), so the vector is large
and gets reallocated a lot.

Since there are a lot of values in the program (the .ll file is 10M), 
each reallocation has to copy the subvectors, which is also quite slow
(this wouldn't be a problem if C++ supported move semantics, but it
doesn't, at least not yet :(

Changing the outer data structure to a map speeds a release build of
llvm-as up from 11.21s to 5.13s on the testcase in PR224.



---
Diffs of the changes:  (+34 -32)

Index: llvm/lib/AsmParser/llvmAsmParser.y
diff -u llvm/lib/AsmParser/llvmAsmParser.y:1.155 llvm/lib/AsmParser/llvmAsmParser.y:1.156
--- llvm/lib/AsmParser/llvmAsmParser.y:1.155	Mon Feb  9 12:53:54 2004
+++ llvm/lib/AsmParser/llvmAsmParser.y	Mon Feb  9 15:03:38 2004
@@ -57,14 +57,14 @@
 // destroyed when the function is completed.
 //
 typedef std::vector<Value *> ValueList;           // Numbered defs
-static void ResolveDefinitions(std::vector<ValueList> &LateResolvers,
-                               std::vector<ValueList> *FutureLateResolvers = 0);
+static void ResolveDefinitions(std::map<unsigned,ValueList> &LateResolvers,
+                               std::map<unsigned,ValueList> *FutureLateResolvers = 0);
 
 static struct PerModuleInfo {
   Module *CurrentModule;
-  std::vector<ValueList>    Values;     // Module level numbered definitions
-  std::vector<ValueList>    LateResolveValues;
-  std::vector<PATypeHolder> Types;
+  std::map<unsigned,ValueList> Values;  // Module level numbered definitions
+  std::map<unsigned,ValueList> LateResolveValues;
+  std::vector<PATypeHolder>    Types;
   std::map<ValID, PATypeHolder> LateResolveTypes;
 
   // GlobalRefs - This maintains a mapping between <Type, ValID>'s and forward
@@ -142,8 +142,8 @@
 static struct PerFunctionInfo {
   Function *CurrentFunction;     // Pointer to current function being created
 
-  std::vector<ValueList> Values;      // Keep track of numbered definitions
-  std::vector<ValueList> LateResolveValues;
+  std::map<unsigned,ValueList> Values;   // Keep track of numbered definitions
+  std::map<unsigned,ValueList> LateResolveValues;
   std::vector<PATypeHolder> Types;
   std::map<ValID, PATypeHolder> LateResolveTypes;
   SymbolTable LocalSymtab;
@@ -170,11 +170,11 @@
       FID = ValID::create((char*)CurrentFunction->getName().c_str());
     } else {
       unsigned Slot = CurrentFunction->getType()->getUniqueID();
-      assert(CurModule.Values.size() > Slot && "Function not inserted?");
       // Figure out which slot number if is...
+      ValueList &List = CurModule.Values[Slot];
       for (unsigned i = 0; ; ++i) {
-        assert(i < CurModule.Values[Slot].size() && "Function not found!");
-        if (CurModule.Values[Slot][i] == CurrentFunction) {
+        assert(i < List.size() && "Function not found!");
+        if (List[i] == CurrentFunction) {
           FID = ValID::create((int)i);
           break;
         }
@@ -198,16 +198,15 @@
 //===----------------------------------------------------------------------===//
 
 static int InsertValue(Value *D,
-                       std::vector<ValueList> &ValueTab = CurFun.Values) {
+                       std::map<unsigned,ValueList> &ValueTab = CurFun.Values) {
   if (D->hasName()) return -1;           // Is this a numbered definition?
 
   // Yes, insert the value into the value table...
   unsigned type = D->getType()->getUniqueID();
-  if (ValueTab.size() <= type)
-    ValueTab.resize(type+1, ValueList());
   //printf("Values[%d][%d] = %d\n", type, ValueTab[type].size(), D);
-  ValueTab[type].push_back(D);
-  return ValueTab[type].size()-1;
+  ValueList &List = ValueTab[type];
+  List.push_back(D);
+  return List.size()-1;
 }
 
 // TODO: FIXME when Type are not const
@@ -297,20 +296,21 @@
     unsigned Num = (unsigned)D.Num;
 
     // Module constants occupy the lowest numbered slots...
-    if (type < CurModule.Values.size()) {
-      if (Num < CurModule.Values[type].size()) 
-        return CurModule.Values[type][Num];
-
-      Num -= CurModule.Values[type].size();
+    std::map<unsigned,ValueList>::iterator VI = CurModule.Values.find(type);
+    if (VI != CurModule.Values.end()) {
+      if (Num < VI->second.size()) 
+        return VI->second[Num];
+      Num -= VI->second.size();
     }
 
     // Make sure that our type is within bounds
-    if (CurFun.Values.size() <= type) return 0;
+    VI = CurFun.Values.find(type);
+    if (VI == CurFun.Values.end()) return 0;
 
     // Check that the number is within bounds...
-    if (CurFun.Values[type].size() <= Num) return 0;
+    if (VI->second.size() <= Num) return 0;
   
-    return CurFun.Values[type][Num];
+    return VI->second[Num];
   }
 
   case ValID::NameVal: {                // Is it a named definition?
@@ -415,18 +415,20 @@
 // time (forward branches, phi functions for loops, etc...) resolve the 
 // defs now...
 //
-static void ResolveDefinitions(std::vector<ValueList> &LateResolvers,
-                               std::vector<ValueList> *FutureLateResolvers) {
+static void ResolveDefinitions(std::map<unsigned,ValueList> &LateResolvers,
+                               std::map<unsigned,ValueList> *FutureLateResolvers) {
   // Loop over LateResolveDefs fixing up stuff that couldn't be resolved
-  for (unsigned ty = 0; ty < LateResolvers.size(); ty++) {
-    while (!LateResolvers[ty].empty()) {
-      Value *V = LateResolvers[ty].back();
+  for (std::map<unsigned,ValueList>::iterator LRI = LateResolvers.begin(),
+         E = LateResolvers.end(); LRI != E; ++LRI) {
+    ValueList &List = LRI->second;
+    while (!List.empty()) {
+      Value *V = List.back();
+      List.pop_back();
       assert(!isa<Type>(V) && "Types should be in LateResolveTypes!");
-
-      LateResolvers[ty].pop_back();
       ValID &DID = getValIDFromPlaceHolder(V);
 
-      Value *TheRealValue = getValNonImprovising(Type::getUniqueIDType(ty),DID);
+      Value *TheRealValue =
+        getValNonImprovising(Type::getUniqueIDType(LRI->first), DID);
       if (TheRealValue) {
         V->replaceAllUsesWith(TheRealValue);
         delete V;
@@ -662,7 +664,7 @@
   if (TypeToResolve) {
     UR_OUT("  * Resolving upreference for "
            << UpRefs[i].second->getDescription() << "\n";
-           std::string OldName = UpRefs[i].UpRefTy->getDescription());
+           std::string OldName = TypeToResolve->getDescription());
     TypeToResolve->refineAbstractTypeTo(Ty);
   }
 





More information about the llvm-commits mailing list