[llvm-commits] CVS: llvm/lib/Bytecode/Reader/Reader.cpp ReaderInternals.h

Chris Lattner lattner at cs.uiuc.edu
Wed Nov 19 11:28:02 PST 2003


Changes in directory llvm/lib/Bytecode/Reader:

Reader.cpp updated: 1.89 -> 1.90
ReaderInternals.h updated: 1.67 -> 1.68

---
Log message:

* Finegrainify namespacification
* Strength reduce several data structures which were left over from the 
  "bad old days"
* Minor efficiency improvements
* Major efficiency improvement: In BytecodeParser::insertValue, do not allocate
  a new ValueTab entry just because some value exists with a large type.  This
  dramatically reduces the number of allocations/deallocations performed by the
  bytecode reader, and speeds up parsing of Kimwitu++ from 34s to 17s.  This is
  to help address PR127


---
Diffs of the changes:  (+47 -73)

Index: llvm/lib/Bytecode/Reader/Reader.cpp
diff -u llvm/lib/Bytecode/Reader/Reader.cpp:1.89 llvm/lib/Bytecode/Reader/Reader.cpp:1.90
--- llvm/lib/Bytecode/Reader/Reader.cpp:1.89	Wed Nov 19 00:01:12 2003
+++ llvm/lib/Bytecode/Reader/Reader.cpp	Wed Nov 19 11:27:18 2003
@@ -12,7 +12,6 @@
 // Note that this library should be as fast as possible, reentrant, and 
 // threadsafe!!
 //
-// TODO: Return error messages to caller instead of printing them out directly.
 // TODO: Allow passing in an option to ignore the symbol table
 //
 //===----------------------------------------------------------------------===//
@@ -31,8 +30,7 @@
 #include "Config/sys/types.h"
 #include <algorithm>
 #include <memory>
-
-namespace llvm {
+using namespace llvm;
 
 static inline void ALIGN32(const unsigned char *&begin,
                            const unsigned char *end) {
@@ -83,24 +81,20 @@
   throw std::string("Illegal type reference!");
 }
 
-unsigned BytecodeParser::insertValue(Value *Val, ValueTable &ValueTab) {
-  return insertValue(Val, getTypeSlot(Val->getType()), ValueTab);
-}
-
 unsigned BytecodeParser::insertValue(Value *Val, unsigned type,
                                      ValueTable &ValueTab) {
   assert((!isa<Constant>(Val) || Val->getType()->isPrimitiveType() ||
           !cast<Constant>(Val)->isNullValue()) &&
          "Cannot read null values from bytecode!");
   assert(type != Type::TypeTyID && "Types should never be insertValue'd!");
- 
+
   if (ValueTab.size() <= type) {
     unsigned OldSize = ValueTab.size();
     ValueTab.resize(type+1);
-    while (OldSize != type+1)
-      ValueTab[OldSize++] = new ValueList();
   }
 
+  if (!ValueTab[type]) ValueTab[type] = new ValueList();
+
   //cerr << "insertValue Values[" << type << "][" << ValueTab[type].size() 
   //   << "] = " << Val << "\n";
   ValueTab[type]->push_back(Val);
@@ -110,10 +104,6 @@
 }
 
 
-Value *BytecodeParser::getValue(const Type *Ty, unsigned oNum, bool Create) {
-  return getValue(getTypeSlot(Ty), oNum, Create);
-}
-
 Value *BytecodeParser::getValue(unsigned type, unsigned oNum, bool Create) {
   assert(type != Type::TypeTyID && "getValue() cannot get types!");
   assert(type != Type::LabelTyID && "getValue() cannot get blocks!");
@@ -125,13 +115,13 @@
     --Num;
   }
 
-  if (type < ModuleValues.size()) {
+  if (type < ModuleValues.size() && ModuleValues[type]) {
     if (Num < ModuleValues[type]->size())
       return ModuleValues[type]->getOperand(Num);
     Num -= ModuleValues[type]->size();
   }
 
-  if (Values.size() > type && Values[type]->size() > Num)
+  if (Values.size() > type && Values[type] && Num < Values[type]->size())
     return Values[type]->getOperand(Num);
 
   if (!Create) return 0;  // Do not create a placeholder?
@@ -181,11 +171,11 @@
 
   const Type *Ty = getType(TypeSlot);
   std::pair<const Type*, unsigned> Key(Ty, Slot);
-  GlobalRefsType::iterator I = GlobalRefs.lower_bound(Key);
+  ConstantRefsType::iterator I = ConstantFwdRefs.lower_bound(Key);
 
-  if (I != GlobalRefs.end() && I->first == Key) {
+  if (I != ConstantFwdRefs.end() && I->first == Key) {
     BCR_TRACE(5, "Previous forward ref found!\n");
-    return cast<Constant>(I->second);
+    return I->second;
   } else {
     // Create a placeholder for the constant reference and
     // keep track of the fact that we have a forward ref to recycle it
@@ -193,7 +183,7 @@
     Constant *C = new ConstPHolder(Ty, Slot);
     
     // Keep track of the fact that we have a forward ref to recycle it
-    GlobalRefs.insert(I, std::make_pair(Key, C));
+    ConstantFwdRefs.insert(I, std::make_pair(Key, C));
     return C;
   }
 }
@@ -265,22 +255,16 @@
   if (Buf > EndBuf) throw std::string("Tried to read past end of buffer.");
 }
 
-void BytecodeParser::ResolveReferencesToValue(Value *NewV, unsigned Slot) {
-  GlobalRefsType::iterator I = GlobalRefs.find(std::make_pair(NewV->getType(),
-                                                              Slot));
-  if (I == GlobalRefs.end()) return;   // Never forward referenced?
+void BytecodeParser::ResolveReferencesToConstant(Constant *NewV, unsigned Slot){
+  ConstantRefsType::iterator I =
+    ConstantFwdRefs.find(std::make_pair(NewV->getType(), Slot));
+  if (I == ConstantFwdRefs.end()) return;   // Never forward referenced?
 
   BCR_TRACE(3, "Mutating forward refs!\n");
-  Value *VPH = I->second;   // Get the placeholder...
-  VPH->replaceAllUsesWith(NewV);
-
-  // If this is a global variable being resolved, remove the placeholder from
-  // the module...
-  if (GlobalValue* GVal = dyn_cast<GlobalValue>(NewV))
-    GVal->getParent()->getGlobalList().remove(cast<GlobalVariable>(VPH));
-
-  delete VPH;                         // Delete the old placeholder
-  GlobalRefs.erase(I);                // Remove the map entry for it
+  Value *PH = I->second;   // Get the placeholder...
+  PH->replaceAllUsesWith(NewV);
+  delete PH;                               // Delete the old placeholder
+  ConstantFwdRefs.erase(I);                // Remove the map entry for it
 }
 
 void BytecodeParser::ParseFunction(const unsigned char *&Buf,
@@ -288,30 +272,24 @@
   if (FunctionSignatureList.empty())
     throw std::string("FunctionSignatureList empty!");
 
-  Function *F = FunctionSignatureList.back().first;
-  unsigned FunctionSlot = FunctionSignatureList.back().second;
+  Function *F = FunctionSignatureList.back();
   FunctionSignatureList.pop_back();
 
   // Save the information for future reading of the function
-  LazyFunctionInfo *LFI = new LazyFunctionInfo();
-  LFI->Buf = Buf; LFI->EndBuf = EndBuf; LFI->FunctionSlot = FunctionSlot;
-  LazyFunctionLoadMap[F] = LFI;
+  LazyFunctionLoadMap[F] = LazyFunctionInfo(Buf, EndBuf);
   // Pretend we've `parsed' this function
   Buf = EndBuf;
 }
 
 void BytecodeParser::materializeFunction(Function* F) {
   // Find {start, end} pointers and slot in the map. If not there, we're done.
-  std::map<Function*, LazyFunctionInfo*>::iterator Fi =
+  std::map<Function*, LazyFunctionInfo>::iterator Fi =
     LazyFunctionLoadMap.find(F);
   if (Fi == LazyFunctionLoadMap.end()) return;
-  
-  LazyFunctionInfo *LFI = Fi->second;
-  const unsigned char *Buf = LFI->Buf;
-  const unsigned char *EndBuf = LFI->EndBuf;
-  unsigned FunctionSlot = LFI->FunctionSlot;
+
+  const unsigned char *Buf = Fi->second.Buf;
+  const unsigned char *EndBuf = Fi->second.EndBuf;
   LazyFunctionLoadMap.erase(Fi);
-  delete LFI;
 
   GlobalValue::LinkageTypes Linkage = GlobalValue::ExternalLinkage;
 
@@ -344,7 +322,7 @@
   Function::aiterator AI = F->abegin();
   for (FunctionType::ParamTypes::const_iterator It = Params.begin();
        It != Params.end(); ++It, ++AI)
-    insertValue(AI, Values);
+    insertValue(AI, getTypeSlot(AI->getType()), Values);
 
   // Keep track of how many basic blocks we have read in...
   unsigned BlockNum = 0;
@@ -355,11 +333,10 @@
     readBlock(Buf, EndBuf, Type, Size);
 
     switch (Type) {
-    case BytecodeFormat::ConstantPool: {
+    case BytecodeFormat::ConstantPool:
       BCR_TRACE(2, "BLOCK BytecodeFormat::ConstantPool: {\n");
       ParseConstantPool(Buf, Buf+Size, Values, FunctionTypeValues);
       break;
-    }
 
     case BytecodeFormat::BasicBlock: {
       BCR_TRACE(2, "BLOCK BytecodeFormat::BasicBlock: {\n");
@@ -368,11 +345,10 @@
       break;
     }
 
-    case BytecodeFormat::SymbolTable: {
+    case BytecodeFormat::SymbolTable:
       BCR_TRACE(2, "BLOCK BytecodeFormat::SymbolTable: {\n");
       ParseSymbolTable(Buf, Buf+Size, &F->getSymbolTable(), F);
       break;
-    }
 
     default:
       BCR_TRACE(2, "BLOCK <unknown>:ignored! {\n");
@@ -392,6 +368,7 @@
     throw std::string("Illegal basic block operand reference");
   ParsedBasicBlocks.clear();
 
+
   // Resolve forward references.  Replace any uses of a forward reference value
   // with the real value.
 
@@ -483,7 +460,7 @@
     GlobalVariable *GV = new GlobalVariable(ElTy, VarType & 1, Linkage,
                                             0, "", TheModule);
     BCR_TRACE(2, "Global Variable of type: " << *Ty << "\n");
-    ResolveReferencesToValue(GV, insertValue(GV, SlotNo, ModuleValues));
+    insertValue(GV, SlotNo, ModuleValues);
 
     if (VarType & 2) { // Does it have an initializer?
       unsigned InitSlot;
@@ -514,13 +491,12 @@
     // Insert the placeholder...
     Function *Func = new Function(cast<FunctionType>(Ty),
                                   GlobalValue::InternalLinkage, "", TheModule);
-    unsigned DestSlot = insertValue(Func, FnSignature, ModuleValues);
-    ResolveReferencesToValue(Func, DestSlot);
+    insertValue(Func, FnSignature, ModuleValues);
 
     // Keep track of this information in a list that is emptied as functions are
     // loaded...
     //
-    FunctionSignatureList.push_back(std::make_pair(Func, DestSlot));
+    FunctionSignatureList.push_back(Func);
 
     if (read_vbr(Buf, End, FnSignature)) throw Error_readvbr;
     BCR_TRACE(2, "Function of type: " << Ty << "\n");
@@ -642,7 +618,6 @@
       BCR_TRACE(1, "BLOCK BytecodeFormat::SymbolTable: {\n");
       ParseSymbolTable(Buf, Buf+Size, &TheModule->getSymbolTable(), 0);
       break;
-
     default:
       Buf += Size;
       if (OldBuf > Buf) throw std::string("Expected Module Block!");
@@ -660,7 +635,9 @@
     GlobalInits.pop_back();
 
     // Look up the initializer value...
-    if (Value *V = getValue(GV->getType()->getElementType(), Slot, false)) {
+    // FIXME: Preserve this type ID!
+    unsigned TypeSlot = getTypeSlot(GV->getType()->getElementType());
+    if (Value *V = getValue(TypeSlot, Slot, false)) {
       if (GV->hasInitializer()) 
         throw std::string("Global *already* has an initializer?!");
       GV->setInitializer(cast<Constant>(V));
@@ -696,5 +673,3 @@
     throw;
   }
 }
-
-} // End llvm namespace


Index: llvm/lib/Bytecode/Reader/ReaderInternals.h
diff -u llvm/lib/Bytecode/Reader/ReaderInternals.h:1.67 llvm/lib/Bytecode/Reader/ReaderInternals.h:1.68
--- llvm/lib/Bytecode/Reader/ReaderInternals.h:1.67	Wed Nov 19 00:01:12 2003
+++ llvm/lib/Bytecode/Reader/ReaderInternals.h	Wed Nov 19 11:27:18 2003
@@ -37,7 +37,8 @@
 
 struct LazyFunctionInfo {
   const unsigned char *Buf, *EndBuf;
-  unsigned FunctionSlot;
+  LazyFunctionInfo(const unsigned char *B = 0, const unsigned char *EB = 0)
+    : Buf(B), EndBuf(EB) {}
 };
 
 class BytecodeParser : public ModuleProvider {
@@ -104,13 +105,13 @@
 
   std::vector<BasicBlock*> ParsedBasicBlocks;
 
-  // GlobalRefs - This maintains a mapping between <Type, Slot #>'s and forward
-  // references to global values or constants.  Such values may be referenced
-  // before they are defined, and if so, the temporary object that they
-  // represent is held here.
+  // ConstantFwdRefs - This maintains a mapping between <Type, Slot #>'s and
+  // forward references to constants.  Such values may be referenced before they
+  // are defined, and if so, the temporary object that they represent is held
+  // here.
   //
-  typedef std::map<std::pair<const Type *, unsigned>, Value*>  GlobalRefsType;
-  GlobalRefsType GlobalRefs;
+  typedef std::map<std::pair<const Type*,unsigned>, Constant*> ConstantRefsType;
+  ConstantRefsType ConstantFwdRefs;
 
   // TypesLoaded - This vector mirrors the Values[TypeTyID] plane.  It is used
   // to deal with forward references to types.
@@ -123,7 +124,7 @@
   // each function in the module.  When the function is loaded, this function is
   // filled in.
   //
-  std::vector<std::pair<Function*, unsigned> > FunctionSignatureList;
+  std::vector<Function*> FunctionSignatureList;
 
   // Constant values are read in after global variables.  Because of this, we
   // must defer setting the initializers on global variables until after module
@@ -136,7 +137,7 @@
   // information about each function: its begin and end pointer in the buffer
   // and its FunctionSlot.
   // 
-  std::map<Function*, LazyFunctionInfo*> LazyFunctionLoadMap;
+  std::map<Function*, LazyFunctionInfo> LazyFunctionLoadMap;
   
 private:
   void freeTable(ValueTable &Tab) {
@@ -169,14 +170,13 @@
                          ValueTable &Tab, TypeValuesListTy &TypeTab);
   Constant *parseConstantValue(const unsigned char *&Buf,
                                const unsigned char *End,
-                               const Type *Ty);
+                               unsigned TypeID);
   void parseTypeConstants(const unsigned char *&Buf,
                           const unsigned char *EndBuf,
                           TypeValuesListTy &Tab, unsigned NumEntries);
   const Type *parseTypeConstant(const unsigned char *&Buf,
                                 const unsigned char *EndBuf);
 
-  Value      *getValue(const Type *Ty, unsigned num, bool Create = true);
   Value      *getValue(unsigned TypeID, unsigned num, bool Create = true);
   const Type *getType(unsigned ID);
   BasicBlock *getBasicBlock(unsigned ID);
@@ -185,13 +185,12 @@
     return getConstantValue(getTypeSlot(Ty), num);
   }
 
-  unsigned insertValue(Value *V, ValueTable &Table);
   unsigned insertValue(Value *V, unsigned Type, ValueTable &Table);
 
   unsigned getTypeSlot(const Type *Ty);
 
-  // resolve all references to the placeholder (if any) for the given value
-  void ResolveReferencesToValue(Value *Val, unsigned Slot);
+  // resolve all references to the placeholder (if any) for the given constant
+  void ResolveReferencesToConstant(Constant *C, unsigned Slot);
 };
 
 template<class SuperType>





More information about the llvm-commits mailing list