[llvm-commits] CVS: llvm/lib/Bytecode/Writer/SlotCalculator.cpp SlotCalculator.h

Chris Lattner sabre at nondot.org
Fri Feb 9 21:45:25 PST 2007



Changes in directory llvm/lib/Bytecode/Writer:

SlotCalculator.cpp updated: 1.102 -> 1.103
SlotCalculator.h updated: 1.43 -> 1.44
---
Log message:

Clone and specialize CreateSlotIfNeeded into CreateFunctionValueSlot to handle
function-local values.  This speeds up bcwriting a small 2.2% (10.384->10.156s
on 447.dealII), but paves the way for more important changes.


---
Diffs of the changes:  (+101 -63)

 SlotCalculator.cpp |  163 ++++++++++++++++++++++++++++++++---------------------
 SlotCalculator.h   |    1 
 2 files changed, 101 insertions(+), 63 deletions(-)


Index: llvm/lib/Bytecode/Writer/SlotCalculator.cpp
diff -u llvm/lib/Bytecode/Writer/SlotCalculator.cpp:1.102 llvm/lib/Bytecode/Writer/SlotCalculator.cpp:1.103
--- llvm/lib/Bytecode/Writer/SlotCalculator.cpp:1.102	Fri Feb  9 23:18:35 2007
+++ llvm/lib/Bytecode/Writer/SlotCalculator.cpp	Fri Feb  9 23:45:09 2007
@@ -201,34 +201,110 @@
     CreateSlotIfNeeded(VI->second);
 }
 
+void SlotCalculator::CreateSlotIfNeeded(const Value *V) {
+  // Check to see if it's already in!
+  if (NodeMap.count(V)) return;
+
+  const Type *Ty = V->getType();
+  assert(Ty != Type::VoidTy && "Can't insert void values!");
+  
+  if (const Constant *C = dyn_cast<Constant>(V)) {
+    if (isa<GlobalValue>(C)) {
+      // Initializers for globals are handled explicitly elsewhere.
+    } else if (isa<ConstantArray>(C) && cast<ConstantArray>(C)->isString()) {
+      // Do not index the characters that make up constant strings.  We emit
+      // constant strings as special entities that don't require their
+      // individual characters to be emitted.
+      assert(ModuleLevel.empty() &&
+             "How can a constant string be directly accessed in a function?");
+      // Otherwise, this IS a string: remember it.
+      if (!C->isNullValue())
+        ConstantStrings.push_back(cast<ConstantArray>(C));
+    } else {
+      // This makes sure that if a constant has uses (for example an array of
+      // const ints), that they are inserted also.
+      for (User::const_op_iterator I = C->op_begin(), E = C->op_end();
+           I != E; ++I)
+        CreateSlotIfNeeded(*I);
+    }
+  }
+
+  unsigned TyPlane = getOrCreateTypeSlot(Ty);
+  if (Table.size() <= TyPlane)    // Make sure we have the type plane allocated.
+    Table.resize(TyPlane+1, TypePlane());
+  
+  // If this is the first value to get inserted into the type plane, make sure
+  // to insert the implicit null value.
+  if (Table[TyPlane].empty()) {
+    // Label's and opaque types can't have a null value.
+    if (Ty != Type::LabelTy && !isa<OpaqueType>(Ty)) {
+      Value *ZeroInitializer = Constant::getNullValue(Ty);
+      
+      // If we are pushing zeroinit, it will be handled below.
+      if (V != ZeroInitializer) {
+        Table[TyPlane].push_back(ZeroInitializer);
+        NodeMap[ZeroInitializer] = 0;
+      }
+    }
+  }
+  
+  // Insert node into table and NodeMap...
+  NodeMap[V] = Table[TyPlane].size();
+  Table[TyPlane].push_back(V);
+  
+  SC_DEBUG("  Inserting value [" << TyPlane << "] = " << *V << " slot=" <<
+           NodeMap[V] << "\n");
+}
+
+
+unsigned SlotCalculator::getOrCreateTypeSlot(const Type *Ty) {
+  std::map<const Type*, unsigned>::iterator TyIt = TypeMap.find(Ty);
+  if (TyIt != TypeMap.end()) return TyIt->second;
+
+  // Insert into TypeMap.
+  unsigned ResultSlot = TypeMap[Ty] = Types.size();
+  Types.push_back(Ty);
+  SC_DEBUG("  Inserting type [" << ResultSlot << "] = " << *Ty << "\n" );
+  
+  // Loop over any contained types in the definition, ensuring they are also
+  // inserted.
+  for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end();
+       I != E; ++I)
+    getOrCreateTypeSlot(*I);
+
+  return ResultSlot;
+}
+
+
+
 void SlotCalculator::incorporateFunction(const Function *F) {
   assert((ModuleLevel.empty() ||
           ModuleTypeLevel == 0) && "Module already incorporated!");
-
+  
   SC_DEBUG("begin processFunction!\n");
-
+  
   // Update the ModuleLevel entries to be accurate.
   ModuleLevel.resize(getNumPlanes());
   for (unsigned i = 0, e = getNumPlanes(); i != e; ++i)
     ModuleLevel[i] = getPlane(i).size();
   ModuleTypeLevel = Types.size();
-
+  
   // Iterate over function arguments, adding them to the value table...
   for(Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end();
       I != E; ++I)
-    CreateSlotIfNeeded(I);
-
+    CreateFunctionValueSlot(I);
+  
   SC_DEBUG("Inserting Instructions:\n");
-
+  
   // Add all of the instructions to the type planes...
   for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
-    CreateSlotIfNeeded(BB);
+    CreateFunctionValueSlot(BB);
     for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I) {
       if (I->getType() != Type::VoidTy)
-        CreateSlotIfNeeded(I);
+        CreateFunctionValueSlot(I);
     }
   }
-
+  
   SC_DEBUG("end processFunction!\n");
 }
 
@@ -236,17 +312,17 @@
   assert((ModuleLevel.size() != 0 ||
           ModuleTypeLevel != 0) && "Module not incorporated!");
   unsigned NumModuleTypes = ModuleLevel.size();
-
+  
   SC_DEBUG("begin purgeFunction!\n");
-
+  
   // Next, remove values from existing type planes
   for (unsigned i = 0; i != NumModuleTypes; ++i) {
     // Size of plane before function came
     unsigned ModuleLev = getModuleLevel(i);
     assert(int(ModuleLev) >= 0 && "BAD!");
-
+    
     TypePlane &Plane = getPlane(i);
-
+    
     assert(ModuleLev <= Plane.size() && "module levels higher than elements?");
     while (Plane.size() != ModuleLev) {
       assert(!isa<GlobalValue>(Plane.back()) &&
@@ -255,11 +331,11 @@
       Plane.pop_back();                  // Shrink plane
     }
   }
-
+  
   // We don't need this state anymore, free it up.
   ModuleLevel.clear();
   ModuleTypeLevel = 0;
-
+  
   // Finally, remove any type planes defined by the function...
   while (Table.size() > NumModuleTypes) {
     TypePlane &Plane = Table.back();
@@ -271,41 +347,20 @@
       NodeMap.erase(Plane.back());   // Erase from nodemap
       Plane.pop_back();              // Shrink plane
     }
-
+    
     Table.pop_back();                // Nuke the plane, we don't like it.
   }
-
+  
   SC_DEBUG("end purgeFunction!\n");
 }
 
-void SlotCalculator::CreateSlotIfNeeded(const Value *V) {
-  // Check to see if it's already in!
-  if (NodeMap.count(V)) return;
-
+void SlotCalculator::CreateFunctionValueSlot(const Value *V) {
+  assert(!NodeMap.count(V) && "Function-local value can't be inserted!");
+  
   const Type *Ty = V->getType();
   assert(Ty != Type::VoidTy && "Can't insert void values!");
+  assert(!isa<Constant>(V) && "Not a function-local value!");
   
-  if (const Constant *C = dyn_cast<Constant>(V)) {
-    if (isa<GlobalValue>(C)) {
-      // Initializers for globals are handled explicitly elsewhere.
-    } else if (isa<ConstantArray>(C) && cast<ConstantArray>(C)->isString()) {
-      // Do not index the characters that make up constant strings.  We emit
-      // constant strings as special entities that don't require their
-      // individual characters to be emitted.
-      assert(ModuleLevel.empty() &&
-             "How can a constant string be directly accessed in a function?");
-      // Otherwise, this IS a string: remember it.
-      if (!C->isNullValue())
-        ConstantStrings.push_back(cast<ConstantArray>(C));
-    } else {
-      // This makes sure that if a constant has uses (for example an array of
-      // const ints), that they are inserted also.
-      for (User::const_op_iterator I = C->op_begin(), E = C->op_end();
-           I != E; ++I)
-        CreateSlotIfNeeded(*I);
-    }
-  }
-
   unsigned TyPlane = getOrCreateTypeSlot(Ty);
   if (Table.size() <= TyPlane)    // Make sure we have the type plane allocated.
     Table.resize(TyPlane+1, TypePlane());
@@ -326,28 +381,10 @@
   }
   
   // Insert node into table and NodeMap...
-  unsigned DestSlot = NodeMap[V] = Table[TyPlane].size();
+  NodeMap[V] = Table[TyPlane].size();
   Table[TyPlane].push_back(V);
   
   SC_DEBUG("  Inserting value [" << TyPlane << "] = " << *V << " slot=" <<
-           DestSlot << "\n");
-}
+           NodeMap[V] << "\n");
+}  
 
-
-unsigned SlotCalculator::getOrCreateTypeSlot(const Type *Ty) {
-  std::map<const Type*, unsigned>::iterator TyIt = TypeMap.find(Ty);
-  if (TyIt != TypeMap.end()) return TyIt->second;
-
-  // Insert into TypeMap.
-  unsigned ResultSlot = TypeMap[Ty] = Types.size();
-  Types.push_back(Ty);
-  SC_DEBUG("  Inserting type [" << ResultSlot << "] = " << *Ty << "\n" );
-  
-  // Loop over any contained types in the definition, ensuring they are also
-  // inserted.
-  for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end();
-       I != E; ++I)
-    getOrCreateTypeSlot(*I);
-
-  return ResultSlot;
-}


Index: llvm/lib/Bytecode/Writer/SlotCalculator.h
diff -u llvm/lib/Bytecode/Writer/SlotCalculator.h:1.43 llvm/lib/Bytecode/Writer/SlotCalculator.h:1.44
--- llvm/lib/Bytecode/Writer/SlotCalculator.h:1.43	Fri Feb  9 23:18:35 2007
+++ llvm/lib/Bytecode/Writer/SlotCalculator.h	Fri Feb  9 23:45:09 2007
@@ -114,6 +114,7 @@
 
 private:
   void CreateSlotIfNeeded(const Value *V);
+  void CreateFunctionValueSlot(const Value *V);
   unsigned getOrCreateTypeSlot(const Type *T);
 
   // processModule - Process all of the module level function declarations and






More information about the llvm-commits mailing list