[llvm-commits] CVS: llvm/lib/Bitcode/Reader/BitcodeReader.cpp BitcodeReader.h

Chris Lattner sabre at nondot.org
Mon Apr 30 22:52:40 PDT 2007



Changes in directory llvm/lib/Bitcode/Reader:

BitcodeReader.cpp updated: 1.19 -> 1.20
BitcodeReader.h updated: 1.13 -> 1.14
---
Log message:

implement materializeModule, force deallocation of vector memory when we 
are done with them, start implementing ParseFunctionBody



---
Diffs of the changes:  (+107 -15)

 BitcodeReader.cpp |  105 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 BitcodeReader.h   |   17 ++++----
 2 files changed, 107 insertions(+), 15 deletions(-)


Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.19 llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.20
--- llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.19	Tue May  1 00:01:34 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp	Tue May  1 00:52:21 2007
@@ -659,9 +659,10 @@
   }
 }
 
-/// ParseFunction - When we see the block for a function body, remember where it
-/// is and then skip it.  This lets us lazily deserialize the functions.
-bool BitcodeReader::ParseFunction() {
+/// RememberAndSkipFunctionBody - When we see the block for a function body,
+/// remember where it is and then skip it.  This lets us lazily deserialize the
+/// functions.
+bool BitcodeReader::RememberAndSkipFunctionBody() {
   // Get the function we are talking about.
   if (FunctionsWithBodies.empty())
     return Error("Insufficient function protos");
@@ -701,13 +702,21 @@
   while (!Stream.AtEndOfStream()) {
     unsigned Code = Stream.ReadCode();
     if (Code == bitc::END_BLOCK) {
+      if (Stream.ReadBlockEnd())
+        return Error("Error at end of module block");
+
+      // Patch the initializers for globals and aliases up.
       ResolveGlobalAndAliasInits();
       if (!GlobalInits.empty() || !AliasInits.empty())
         return Error("Malformed global initializer set");
       if (!FunctionsWithBodies.empty())
         return Error("Too few function bodies found");
-      if (Stream.ReadBlockEnd())
-        return Error("Error at end of module block");
+
+      // Force deallocation of memory for these vectors to favor the client that
+      // want lazy deserialization.
+      std::vector<std::pair<GlobalVariable*, unsigned> >().swap(GlobalInits);
+      std::vector<std::pair<GlobalAlias*, unsigned> >().swap(AliasInits);
+      std::vector<Function*>().swap(FunctionsWithBodies);
       return false;
     }
     
@@ -741,7 +750,7 @@
           HasReversedFunctionsWithBodies = true;
         }
         
-        if (ParseFunction())
+        if (RememberAndSkipFunctionBody())
           return true;
         break;
       }
@@ -956,6 +965,90 @@
   F->setLinkage((GlobalValue::LinkageTypes)DFII->second.second);
   DeferredFunctionInfo.erase(DFII);
   
+  if (ParseFunctionBody(F)) {
+    if (ErrInfo) *ErrInfo = ErrorString;
+    return true;
+  }
+  
+  return false;
+}
+
+Module *BitcodeReader::materializeModule(std::string *ErrInfo) {
+  DenseMap<Function*, std::pair<uint64_t, unsigned> >::iterator I = 
+    DeferredFunctionInfo.begin();
+  while (!DeferredFunctionInfo.empty()) {
+    Function *F = (*I++).first;
+    assert(F->hasNotBeenReadFromBytecode() &&
+           "Deserialized function found in map!");
+    if (materializeFunction(F, ErrInfo))
+      return 0;
+  }
+  return TheModule;
+}
+
+
+/// ParseFunctionBody - Lazily parse the specified function body block.
+bool BitcodeReader::ParseFunctionBody(Function *F) {
+  if (Stream.EnterSubBlock())
+    return Error("Malformed block record");
+  
+  unsigned ModuleValueListSize = ValueList.size();
+  
+  // Add all the function arguments to the value table.
+  for(Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I)
+    ValueList.push_back(I);
+  
+  // Read all the records.
+  SmallVector<uint64_t, 64> Record;
+  while (1) {
+    unsigned Code = Stream.ReadCode();
+    if (Code == bitc::END_BLOCK) {
+      if (Stream.ReadBlockEnd())
+        return Error("Error at end of function block");
+      break;
+    }
+    
+    if (Code == bitc::ENTER_SUBBLOCK) {
+      switch (Stream.ReadSubBlockID()) {
+      default:  // Skip unknown content.
+        if (Stream.SkipBlock())
+          return Error("Malformed block record");
+        break;
+      case bitc::CONSTANTS_BLOCK_ID:
+        if (ParseConstants()) return true;
+        break;
+      case bitc::VALUE_SYMTAB_BLOCK_ID:
+        if (ParseValueSymbolTable()) return true;
+        break;
+      }
+      continue;
+    }
+    
+    if (Code == bitc::DEFINE_ABBREV) {
+      Stream.ReadAbbrevRecord();
+      continue;
+    }
+    
+    // Read a record.
+    Record.clear();
+    switch (Stream.ReadRecord(Code, Record)) {
+    default:  // Default behavior: unknown constant
+    case bitc::FUNC_CODE_DECLAREBLOCKS:     // DECLAREBLOCKS: [nblocks]
+      if (Record.size() < 1)
+        return Error("Invalid FUNC_CODE_DECLAREBLOCKS record");
+      // Create all the basic blocks for the function.
+      FunctionBBs.resize(Record.size());
+      for (unsigned i = 0, e = FunctionBBs.size(); i != e; ++i)
+        FunctionBBs[i] = new BasicBlock("", F);
+      break;
+    }
+  }
+  
+  
+  // Trim the value list down to the size it was before we parsed this function.
+  ValueList.shrinkTo(ModuleValueListSize);
+  std::vector<BasicBlock*>().swap(FunctionBBs);
+  
   return false;
 }
 


Index: llvm/lib/Bitcode/Reader/BitcodeReader.h
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.h:1.13 llvm/lib/Bitcode/Reader/BitcodeReader.h:1.14
--- llvm/lib/Bitcode/Reader/BitcodeReader.h:1.13	Tue May  1 00:01:34 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.h	Tue May  1 00:52:21 2007
@@ -44,7 +44,7 @@
   void pop_back() { Uses.pop_back(); --NumOperands; }
   bool empty() const { return NumOperands == 0; }
   void shrinkTo(unsigned N) {
-    assert(N < NumOperands && "Invalid shrinkTo request!");
+    assert(N <= NumOperands && "Invalid shrinkTo request!");
     Uses.resize(N);
     NumOperands = N;
   }
@@ -69,6 +69,10 @@
   std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
   std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits;
   
+  /// FunctionBBs - While parsing a function body, this is a list of the basic
+  /// blocks for the function.
+  std::vector<BasicBlock*> FunctionBBs;
+  
   // When reading the module header, this list is populated with functions that
   // have bodies later in the file.
   std::vector<Function*> FunctionsWithBodies;
@@ -96,13 +100,7 @@
   }
   
   virtual bool materializeFunction(Function *F, std::string *ErrInfo = 0);
-  
-  virtual Module *materializeModule(std::string *ErrInfo = 0) {
-    // FIXME: TODO
-    //if (ParseAllFunctionBodies(ErrMsg))
-    //  return 0;
-    return TheModule;
-  }
+  virtual Module *materializeModule(std::string *ErrInfo = 0);
   
   bool Error(const char *Str) {
     ErrorString = Str;
@@ -121,7 +119,8 @@
   bool ParseTypeSymbolTable();
   bool ParseValueSymbolTable();
   bool ParseConstants();
-  bool ParseFunction();
+  bool RememberAndSkipFunctionBody();
+  bool ParseFunctionBody(Function *F);
   bool ResolveGlobalAndAliasInits();
 };
   






More information about the llvm-commits mailing list