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

2007-05-17 Thread Chris Lattner


Changes in directory llvm/lib/Bitcode/Reader:

BitcodeReader.cpp updated: 1.49 -> 1.50
BitcodeReader.h updated: 1.20 -> 1.21
---
Log message:

Fix PR1434: http://llvm.org/PR1434  and test/Linker/link-archive.ll, this is a 
regression from 1.9.


---
Diffs of the changes:  (+91 -54)

 BitcodeReader.cpp |  135 --
 BitcodeReader.h   |   10 +++-
 2 files changed, 91 insertions(+), 54 deletions(-)


Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.49 
llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.50
--- llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.49  Tue May 15 01:29:44 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp   Thu May 17 23:02:46 2007
@@ -24,8 +24,15 @@
 #include "llvm/Support/MemoryBuffer.h"
 using namespace llvm;
 
-BitcodeReader::~BitcodeReader() {
+void BitcodeReader::FreeState() {
   delete Buffer;
+  Buffer = 0;
+  std::vector().swap(TypeList);
+  ValueList.clear();
+  std::vector().swap(ParamAttrs);
+  std::vector().swap(FunctionBBs);
+  std::vector().swap(FunctionsWithBodies);
+  DeferredFunctionInfo.clear();
 }
 
 
//===--===//
@@ -1102,53 +1109,6 @@
 }
 
 
-bool BitcodeReader::materializeFunction(Function *F, std::string *ErrInfo) {
-  // If it already is material, ignore the request.
-  if (!F->hasNotBeenReadFromBytecode()) return false;
-
-  DenseMap >::iterator DFII = 
-DeferredFunctionInfo.find(F);
-  assert(DFII != DeferredFunctionInfo.end() && "Deferred function not found!");
-  
-  // Move the bit stream to the saved position of the deferred function body 
and
-  // restore the real linkage type for the function.
-  Stream.JumpToBit(DFII->second.first);
-  F->setLinkage((GlobalValue::LinkageTypes)DFII->second.second);
-  
-  if (ParseFunctionBody(F)) {
-if (ErrInfo) *ErrInfo = ErrorString;
-return true;
-  }
-  
-  return false;
-}
-
-void BitcodeReader::dematerializeFunction(Function *F) {
-  // If this function isn't materialized, or if it is a proto, this is a noop.
-  if (F->hasNotBeenReadFromBytecode() || F->isDeclaration())
-return;
-  
-  assert(DeferredFunctionInfo.count(F) && "No info to read function later?");
-  
-  // Just forget the function body, we can remat it later.
-  F->deleteBody();
-  F->setLinkage(GlobalValue::GhostLinkage);
-}
-
-
-Module *BitcodeReader::materializeModule(std::string *ErrInfo) {
-  for (DenseMap >::iterator I = 
-   DeferredFunctionInfo.begin(), E = DeferredFunctionInfo.end(); I != E;
-   ++I) {
-Function *F = I->first;
-if (F->hasNotBeenReadFromBytecode() &&
-materializeFunction(F, ErrInfo))
-  return 0;
-  }
-  return TheModule;
-}
-
-
 /// ParseFunctionBody - Lazily parse the specified function body block.
 bool BitcodeReader::ParseFunctionBody(Function *F) {
   if (Stream.EnterSubBlock(bitc::FUNCTION_BLOCK_ID))
@@ -1597,6 +1557,69 @@
   return false;
 }
 
+//===--===//
+// ModuleProvider implementation
+//===--===//
+
+
+bool BitcodeReader::materializeFunction(Function *F, std::string *ErrInfo) {
+  // If it already is material, ignore the request.
+  if (!F->hasNotBeenReadFromBytecode()) return false;
+  
+  DenseMap >::iterator DFII = 
+DeferredFunctionInfo.find(F);
+  assert(DFII != DeferredFunctionInfo.end() && "Deferred function not found!");
+  
+  // Move the bit stream to the saved position of the deferred function body 
and
+  // restore the real linkage type for the function.
+  Stream.JumpToBit(DFII->second.first);
+  F->setLinkage((GlobalValue::LinkageTypes)DFII->second.second);
+  
+  if (ParseFunctionBody(F)) {
+if (ErrInfo) *ErrInfo = ErrorString;
+return true;
+  }
+  
+  return false;
+}
+
+void BitcodeReader::dematerializeFunction(Function *F) {
+  // If this function isn't materialized, or if it is a proto, this is a noop.
+  if (F->hasNotBeenReadFromBytecode() || F->isDeclaration())
+return;
+  
+  assert(DeferredFunctionInfo.count(F) && "No info to read function later?");
+  
+  // Just forget the function body, we can remat it later.
+  F->deleteBody();
+  F->setLinkage(GlobalValue::GhostLinkage);
+}
+
+
+Module *BitcodeReader::materializeModule(std::string *ErrInfo) {
+  for (DenseMap >::iterator I = 
+   DeferredFunctionInfo.begin(), E = DeferredFunctionInfo.end(); I != E;
+   ++I) {
+Function *F = I->first;
+if (F->hasNotBeenReadFromBytecode() &&
+materializeFunction(F, ErrInfo))
+  return 0;
+  }
+  return TheModule;
+}
+
+
+/// This method is provided by the parent ModuleProvde class and overriden
+/// here. It simply releases the module from its provided and frees up our
+/// state.
+/// @brief Release our hold on the generated module
+Module *BitcodeReader::releaseModule(std::string *ErrInfo) {
+  // Since we're losing

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

2007-05-14 Thread Chris Lattner


Changes in directory llvm/lib/Bitcode/Reader:

BitcodeReader.cpp updated: 1.48 -> 1.49
BitcodeReader.h updated: 1.19 -> 1.20
---
Log message:

implement the ModuleProvider::dematerializeFunction hook


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

 BitcodeReader.cpp |   27 +++
 BitcodeReader.h   |3 ++-
 2 files changed, 21 insertions(+), 9 deletions(-)


Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.48 
llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.49
--- llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.48  Tue May  8 00:38:01 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp   Tue May 15 01:29:44 2007
@@ -1114,7 +1114,6 @@
   // restore the real linkage type for the function.
   Stream.JumpToBit(DFII->second.first);
   F->setLinkage((GlobalValue::LinkageTypes)DFII->second.second);
-  DeferredFunctionInfo.erase(DFII);
   
   if (ParseFunctionBody(F)) {
 if (ErrInfo) *ErrInfo = ErrorString;
@@ -1124,14 +1123,26 @@
   return false;
 }
 
+void BitcodeReader::dematerializeFunction(Function *F) {
+  // If this function isn't materialized, or if it is a proto, this is a noop.
+  if (F->hasNotBeenReadFromBytecode() || F->isDeclaration())
+return;
+  
+  assert(DeferredFunctionInfo.count(F) && "No info to read function later?");
+  
+  // Just forget the function body, we can remat it later.
+  F->deleteBody();
+  F->setLinkage(GlobalValue::GhostLinkage);
+}
+
+
 Module *BitcodeReader::materializeModule(std::string *ErrInfo) {
-  DenseMap >::iterator I = 
-DeferredFunctionInfo.begin();
-  while (!DeferredFunctionInfo.empty()) {
-Function *F = (*I++).first;
-assert(F->hasNotBeenReadFromBytecode() &&
-   "Deserialized function found in map!");
-if (materializeFunction(F, ErrInfo))
+  for (DenseMap >::iterator I = 
+   DeferredFunctionInfo.begin(), E = DeferredFunctionInfo.end(); I != E;
+   ++I) {
+Function *F = I->first;
+if (F->hasNotBeenReadFromBytecode() &&
+materializeFunction(F, ErrInfo))
   return 0;
   }
   return TheModule;


Index: llvm/lib/Bitcode/Reader/BitcodeReader.h
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.h:1.19 
llvm/lib/Bitcode/Reader/BitcodeReader.h:1.20
--- llvm/lib/Bitcode/Reader/BitcodeReader.h:1.19Sat May  5 22:23:14 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.h Tue May 15 01:29:44 2007
@@ -123,7 +123,8 @@
   
   virtual bool materializeFunction(Function *F, std::string *ErrInfo = 0);
   virtual Module *materializeModule(std::string *ErrInfo = 0);
-  
+  virtual void dematerializeFunction(Function *F);
+
   bool Error(const char *Str) {
 ErrorString = Str;
 return true;



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


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

2007-05-05 Thread Chris Lattner


Changes in directory llvm/lib/Bitcode/Reader:

BitcodeReader.cpp updated: 1.39 -> 1.40
BitcodeReader.h updated: 1.17 -> 1.18
---
Log message:

stop encoding type/value pairs when the type is implied by the value.
This shrinks the function block of kc++ from 1055K to 906K


---
Diffs of the changes:  (+97 -75)

 BitcodeReader.cpp |  144 +-
 BitcodeReader.h   |   28 ++
 2 files changed, 97 insertions(+), 75 deletions(-)


Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.39 
llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.40
--- llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.39  Sat May  5 13:57:30 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp   Sat May  5 19:00:00 2007
@@ -1168,23 +1168,20 @@
   break;
 }
 case bitc::FUNC_CODE_INST_GEP: { // GEP: [n x operands]
-  if (Record.size() < 2 || (Record.size() & 1))
-return Error("Invalid GEP record");
-  const Type *OpTy = getTypeByID(Record[0]);
-  Value *Op = getFnValueByID(Record[1], OpTy);
-  if (OpTy == 0 || Op == 0)
+  unsigned OpNum = 0;
+  Value *BasePtr;
+  if (getValueTypePair(Record, OpNum, NextValueNo, BasePtr))
 return Error("Invalid GEP record");
 
   SmallVector GEPIdx;
-  for (unsigned i = 1, e = Record.size()/2; i != e; ++i) {
-const Type *IdxTy = getTypeByID(Record[i*2]);
-Value *Idx = getFnValueByID(Record[i*2+1], IdxTy);
-if (IdxTy == 0 || Idx == 0)
+  while (OpNum != Record.size()) {
+Value *Op;
+if (getValueTypePair(Record, OpNum, NextValueNo, Op))
   return Error("Invalid GEP record");
-GEPIdx.push_back(Idx);
+GEPIdx.push_back(Op);
   }
 
-  I = new GetElementPtrInst(Op, &GEPIdx[0], GEPIdx.size());
+  I = new GetElementPtrInst(BasePtr, &GEPIdx[0], GEPIdx.size());
   break;
 }
   
@@ -1242,16 +1239,17 @@
 }
   
 case bitc::FUNC_CODE_INST_CMP: { // CMP: [opty, opval, opval, pred]
-  if (Record.size() < 4) return Error("Invalid CMP record");
-  const Type *OpTy = getTypeByID(Record[0]);
-  Value *LHS = getFnValueByID(Record[1], OpTy);
-  Value *RHS = getFnValueByID(Record[2], OpTy);
-  if (OpTy == 0 || LHS == 0 || RHS == 0)
+  unsigned OpNum = 0;
+  Value *LHS, *RHS;
+  if (getValueTypePair(Record, OpNum, NextValueNo, LHS) ||
+  getValue(Record, OpNum, LHS->getType(), RHS) ||
+  OpNum+1 != Record.size())
 return Error("Invalid CMP record");
-  if (OpTy->isFPOrFPVector())
-I = new FCmpInst((FCmpInst::Predicate)Record[3], LHS, RHS);
+  
+  if (LHS->getType()->isFPOrFPVector())
+I = new FCmpInst((FCmpInst::Predicate)Record[OpNum], LHS, RHS);
   else
-I = new ICmpInst((ICmpInst::Predicate)Record[3], LHS, RHS);
+I = new ICmpInst((ICmpInst::Predicate)Record[OpNum], LHS, RHS);
   break;
 }
 
@@ -1259,16 +1257,15 @@
   if (Record.size() == 0) {
 I = new ReturnInst();
 break;
-  }
-  if (Record.size() == 2) {
-const Type *OpTy = getTypeByID(Record[0]);
-Value *Op = getFnValueByID(Record[1], OpTy);
-if (!OpTy || !Op)
+  } else {
+unsigned OpNum = 0;
+Value *Op;
+if (getValueTypePair(Record, OpNum, NextValueNo, Op) ||
+OpNum != Record.size())
   return Error("Invalid RET record");
 I = new ReturnInst(Op);
 break;
   }
-  return Error("Invalid RET record");
 case bitc::FUNC_CODE_INST_BR: { // BR: [bb#, bb#, opval] or [bb#]
   if (Record.size() != 1 && Record.size() != 3)
 return Error("Invalid BR record");
@@ -1312,46 +1309,42 @@
 }
   
 case bitc::FUNC_CODE_INST_INVOKE: { // INVOKE: [cc,fnty, op0,op1,op2, ...]
-  if (Record.size() < 5)
-return Error("Invalid INVOKE record");
+  if (Record.size() < 3) return Error("Invalid INVOKE record");
   unsigned CCInfo = Record[0];
-  const PointerType *CalleeTy =
-dyn_cast_or_null(getTypeByID(Record[1]));
-  Value *Callee = getFnValueByID(Record[2], CalleeTy);
-  BasicBlock *NormalBB = getBasicBlock(Record[3]);
-  BasicBlock *UnwindBB = getBasicBlock(Record[4]);
-  if (CalleeTy == 0 || Callee == 0 || NormalBB == 0 || UnwindBB == 0)
+  BasicBlock *NormalBB = getBasicBlock(Record[1]);
+  BasicBlock *UnwindBB = getBasicBlock(Record[2]);
+  
+  unsigned OpNum = 3;
+  Value *Callee;
+  if (getValueTypePair(Record, OpNum, NextValueNo, Callee))
 return Error("Invalid INVOKE record");
   
-  const FunctionType *FTy =
+  const PointerType *CalleeTy = dyn_cast(Callee->getType());
+  const FunctionType *FTy = !CalleeTy ? 0 :
 dyn_cast(CalleeTy->getElementType());
 
   // Check that the right number of fixed parameters are here.
-  if (FTy == 0 || Record.size() < 5+FTy->getNum

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

2007-05-03 Thread Chris Lattner


Changes in directory llvm/lib/Bitcode/Reader:

BitcodeReader.cpp updated: 1.32 -> 1.33
BitcodeReader.h updated: 1.16 -> 1.17
---
Log message:

add support for reading the param attrs block


---
Diffs of the changes:  (+82 -0)

 BitcodeReader.cpp |   69 ++
 BitcodeReader.h   |   13 ++
 2 files changed, 82 insertions(+)


Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.32 
llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.33
--- llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.32  Thu May  3 22:02:54 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp   Thu May  3 22:30:17 2007
@@ -17,6 +17,7 @@
 #include "llvm/DerivedTypes.h"
 #include "llvm/Instructions.h"
 #include "llvm/Module.h"
+#include "llvm/ParameterAttributes.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -26,6 +27,9 @@
   delete Buffer;
 }
 
+//===--===//
+//  Helper functions to implement forward reference resolution, etc.
+//===--===//
 
 /// ConvertToString - Convert a string from a record into an std::string, 
return
 /// true on failure.
@@ -173,6 +177,67 @@
   return TypeList.back().get();
 }
 
+//===--===//
+//  Functions for parsing blocks from the bitcode file
+//===--===//
+
+bool BitcodeReader::ParseParamAttrBlock() {
+  if (Stream.EnterSubBlock())
+return Error("Malformed block record");
+  
+  if (!ParamAttrs.empty())
+return Error("Multiple PARAMATTR blocks found!");
+  
+  SmallVector Record;
+  
+  ParamAttrsVector Attrs;
+  
+  // Read all the records.
+  while (1) {
+unsigned Code = Stream.ReadCode();
+if (Code == bitc::END_BLOCK) {
+  if (Stream.ReadBlockEnd())
+return Error("Error at end of PARAMATTR block");
+  return false;
+}
+
+if (Code == bitc::ENTER_SUBBLOCK) {
+  // No known subblocks, always skip them.
+  Stream.ReadSubBlockID();
+  if (Stream.SkipBlock())
+return Error("Malformed block record");
+  continue;
+}
+
+if (Code == bitc::DEFINE_ABBREV) {
+  Stream.ReadAbbrevRecord();
+  continue;
+}
+
+// Read a record.
+Record.clear();
+switch (Stream.ReadRecord(Code, Record)) {
+default:  // Default behavior: ignore.
+  break;
+case bitc::PARAMATTR_CODE_ENTRY: { // ENTRY: [paramidx0, attr0, ...]
+  if (Record.size() & 1)
+return Error("Invalid ENTRY record");
+
+  ParamAttrsWithIndex PAWI;
+  for (unsigned i = 0, e = Record.size(); i != e; i += 2) {
+PAWI.index = Record[i];
+PAWI.attrs = Record[i+1];
+Attrs.push_back(PAWI);
+  }
+  ParamAttrs.push_back(ParamAttrsList::get(Attrs));
+  Attrs.clear();
+  break;
+}
+}
+  }
+}
+
+
 bool BitcodeReader::ParseTypeTable() {
   if (Stream.EnterSubBlock())
 return Error("Malformed block record");
@@ -742,6 +807,10 @@
 if (Stream.SkipBlock())
   return Error("Malformed block record");
 break;
+  case bitc::PARAMATTR_BLOCK_ID:
+if (ParseParamAttrBlock())
+  return true;
+break;
   case bitc::TYPE_BLOCK_ID:
 if (ParseTypeTable())
   return true;


Index: llvm/lib/Bitcode/Reader/BitcodeReader.h
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.h:1.16 
llvm/lib/Bitcode/Reader/BitcodeReader.h:1.17
--- llvm/lib/Bitcode/Reader/BitcodeReader.h:1.16Wed May  2 00:46:45 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.h Thu May  3 22:30:17 2007
@@ -24,6 +24,7 @@
 
 namespace llvm {
   class MemoryBuffer;
+  class ParamAttrsList;
   
 class BitcodeReaderValueList : public User {
   std::vector Uses;
@@ -85,6 +86,11 @@
   std::vector > GlobalInits;
   std::vector > AliasInits;
   
+  /// ParamAttrs - The set of parameter attributes by index.  Index zero in the
+  /// file is for null, and is thus not represented here.  As such all indices
+  /// are off by one.
+  std::vector ParamAttrs;
+  
   /// FunctionBBs - While parsing a function body, this is a list of the basic
   /// blocks for the function.
   std::vector FunctionBBs;
@@ -136,8 +142,15 @@
 if (ID >= FunctionBBs.size()) return 0; // Invalid ID
 return FunctionBBs[ID];
   }
+  const ParamAttrsList *getParamAttrs(unsigned i) const {
+if (i-1 < ParamAttrs.size())
+  return ParamAttrs[i-1];
+return 0;
+  }
+
   
   bool ParseModule(const std::string &ModuleID);
+  bool ParseParamAttrBlock();
   bool ParseTypeTable();
   bool ParseTypeSymbolTable();
   bool ParseValueSymbolTable();



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mail

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

2007-05-01 Thread Chris Lattner


Changes in directory llvm/lib/Bitcode/Reader:

BitcodeReader.cpp updated: 1.23 -> 1.24
BitcodeReader.h updated: 1.15 -> 1.16
---
Log message:

add reader logic for terminator instrs.


---
Diffs of the changes:  (+93 -8)

 BitcodeReader.cpp |   97 +-
 BitcodeReader.h   |4 ++
 2 files changed, 93 insertions(+), 8 deletions(-)


Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.23 
llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.24
--- llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.23  Wed May  2 00:16:49 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp   Wed May  2 00:46:45 2007
@@ -1090,7 +1090,7 @@
   if (OpTy == 0 || Op == 0)
 return Error("Invalid GEP record");
 
-  SmallVector GEPIdx;
+  SmallVector GEPIdx;
   for (unsigned i = 1, e = Record.size()/2; i != e; ++i) {
 const Type *IdxTy = getTypeByID(Record[i*2]);
 Value *Idx = getFnValueByID(Record[i*2+1], IdxTy);
@@ -1183,19 +1183,100 @@
 break;
   }
   return Error("Invalid RET record");
-#if 0
-case bitc::FUNC_CODE_INST_BR:
-  // BR: [opval, bb#, bb#] or [bb#]
-case bitc::FUNC_CODE_INST_SWITCH:
-  // SWITCH: [opty, opval, n, n x ops]
-case bitc::FUNC_CODE_INST_INVOKE:
-  // INVOKE: [fnty, op0,op1,op2, ...]
+case bitc::FUNC_CODE_INST_BR: { // BR: [bb#, bb#, opval] or [bb#]
+  if (Record.size() != 1 || Record.size() != 3)
+return Error("Invalid BR record");
+  BasicBlock *TrueDest = getBasicBlock(Record[0]);
+  if (TrueDest == 0)
+return Error("Invalid BR record");
+
+  if (Record.size() == 1)
+I = new BranchInst(TrueDest);
+  else {
+BasicBlock *FalseDest = getBasicBlock(Record[1]);
+Value *Cond = getFnValueByID(Record[2], Type::Int1Ty);
+if (FalseDest == 0 || Cond == 0)
+  return Error("Invalid BR record");
+I = new BranchInst(TrueDest, FalseDest, Cond);
+  }
+  break;
+}
+case bitc::FUNC_CODE_INST_SWITCH: { // SWITCH: [opty, opval, n, n x ops]
+  if (Record.size() < 3 || (Record.size() & 1) == 0)
+return Error("Invalid SWITCH record");
+  const Type *OpTy = getTypeByID(Record[0]);
+  Value *Cond = getFnValueByID(Record[1], OpTy);
+  BasicBlock *Default = getBasicBlock(Record[2]);
+  if (OpTy == 0 || Cond == 0 || Default == 0)
+return Error("Invalid SWITCH record");
+  unsigned NumCases = (Record.size()-3)/2;
+  SwitchInst *SI = new SwitchInst(Cond, Default, NumCases);
+  for (unsigned i = 0, e = NumCases; i != e; ++i) {
+ConstantInt *CaseVal = 
+  dyn_cast_or_null(getFnValueByID(Record[3+i*2], OpTy));
+BasicBlock *DestBB = getBasicBlock(Record[1+3+i*2]);
+if (CaseVal == 0 || DestBB == 0) {
+  delete SI;
+  return Error("Invalid SWITCH record!");
+}
+SI->addCase(CaseVal, DestBB);
+  }
+  I = SI;
+  break;
+}
+  
+case bitc::FUNC_CODE_INST_INVOKE: { // INVOKE: [fnty, op0,op1,op2, ...]
+  if (Record.size() < 4)
+return Error("Invalid INVOKE record");
+  const PointerType *CalleeTy =
+dyn_cast_or_null(getTypeByID(Record[0]));
+  Value *Callee = getFnValueByID(Record[1], CalleeTy);
+  BasicBlock *NormalBB = getBasicBlock(Record[2]);
+  BasicBlock *UnwindBB = getBasicBlock(Record[3]);
+  if (CalleeTy == 0 || Callee == 0 || NormalBB == 0 || UnwindBB == 0)
+return Error("Invalid INVOKE record");
+  
+  const FunctionType *FTy =
+dyn_cast(CalleeTy->getElementType());
+
+  // Check that the right number of fixed parameters are here.
+  if (FTy == 0 || Record.size() < 4+FTy->getNumParams())
+return Error("Invalid INVOKE record");
+
+  SmallVector Ops;
+  for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i) {
+Ops.push_back(getFnValueByID(Record[4+i], FTy->getParamType(4+i)));
+if (Ops.back() == 0)
+  return Error("Invalid INVOKE record");
+  }
+  
+  unsigned FirstVarargParam = 4+FTy->getNumParams();
+  if (FTy->isVarArg()) {
+// Read type/value pairs for varargs params.
+if ((Record.size()-FirstVarargParam) & 1)
+  return Error("Invalid INVOKE record");
+
+for (unsigned i = FirstVarargParam, e = Record.size(); i != e; i += 2) 
{
+  const Type *ArgTy = getTypeByID(Record[i]);
+  Ops.push_back(getFnValueByID(Record[i+1], ArgTy));
+  if (Ops.back() == 0 || ArgTy == 0)
+return Error("Invalid INVOKE record");
+}
+  } else {
+if (Record.size() != FirstVarargParam)
+  return Error("Invalid INVOKE record");
+  }
+  
+  I = new InvokeInst(Callee, NormalBB, UnwindBB, &Ops[0], Ops.size());
+  break;
+}
 case bitc::FUNC_CODE_INST_UNWIND: // UNWIND
   I = new UnwindInst();
  

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

2007-05-01 Thread Chris Lattner


Changes in directory llvm/lib/Bitcode/Reader:

BitcodeReader.cpp updated: 1.20 -> 1.21
BitcodeReader.h updated: 1.14 -> 1.15
---
Log message:

handle function-level forward references, read binops.


---
Diffs of the changes:  (+147 -22)

 BitcodeReader.cpp |  150 ++
 BitcodeReader.h   |   19 ++
 2 files changed, 147 insertions(+), 22 deletions(-)


Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.20 
llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.21
--- llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.20  Tue May  1 00:52:21 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp   Tue May  1 02:01:57 2007
@@ -15,6 +15,7 @@
 #include "BitcodeReader.h"
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
+#include "llvm/Instructions.h"
 #include "llvm/Module.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/MathExtras.h"
@@ -125,10 +126,9 @@
 NumOperands = Idx+1;
   }
 
-  if (Uses[Idx]) {
-assert(Ty == getOperand(Idx)->getType() &&
-   "Type mismatch in constant table!");
-return cast(getOperand(Idx));
+  if (Value *V = Uses[Idx]) {
+assert(Ty == V->getType() && "Type mismatch in constant table!");
+return cast(V);
   }
 
   // Create and return a placeholder, which will later be RAUW'd.
@@ -137,6 +137,25 @@
   return C;
 }
 
+Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, const Type *Ty) {
+  if (Idx >= size()) {
+// Insert a bunch of null values.
+Uses.resize(Idx+1);
+OperandList = &Uses[0];
+NumOperands = Idx+1;
+  }
+  
+  if (Value *V = Uses[Idx]) {
+assert((Ty == 0 || Ty == V->getType()) && "Type mismatch in value table!");
+return V;
+  }
+  
+  // Create and return a placeholder, which will later be RAUW'd.
+  Value *V = new Argument(Ty);
+  Uses[Idx].init(V, this);
+  return V;
+}
+
 
 const Type *BitcodeReader::getTypeByID(unsigned ID, bool isTypeTable) {
   // If the TypeID is in range, return it.
@@ -151,7 +170,6 @@
   return TypeList.back().get();
 }
 
-
 bool BitcodeReader::ParseTypeTable() {
   if (Stream.EnterSubBlock())
 return Error("Malformed block record");
@@ -643,18 +661,7 @@
 }
 }
 
-if (NextCstNo == ValueList.size())
-  ValueList.push_back(V);
-else if (ValueList[NextCstNo] == 0)
-  ValueList.initVal(NextCstNo, V);
-else {
-  // If there was a forward reference to this constant, 
-  Value *OldV = ValueList[NextCstNo];
-  ValueList.setOperand(NextCstNo, V);
-  OldV->replaceAllUsesWith(V);
-  delete OldV;
-}
-
+ValueList.AssignValue(V, NextCstNo);
 ++NextCstNo;
   }
 }
@@ -998,6 +1005,8 @@
   for(Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I)
 ValueList.push_back(I);
   
+  unsigned NextValueNo = ValueList.size();
+  
   // Read all the records.
   SmallVector Record;
   while (1) {
@@ -1016,6 +1025,7 @@
 break;
   case bitc::CONSTANTS_BLOCK_ID:
 if (ParseConstants()) return true;
+NextValueNo = ValueList.size();
 break;
   case bitc::VALUE_SYMTAB_BLOCK_ID:
 if (ParseValueSymbolTable()) return true;
@@ -1031,19 +1041,115 @@
 
 // Read a record.
 Record.clear();
+Instruction *I = 0;
+BasicBlock *CurBB = 0;
+unsigned CurBBNo = 0;
 switch (Stream.ReadRecord(Code, Record)) {
-default:  // Default behavior: unknown constant
+default: // Default behavior: reject
+  return Error("Unknown instruction");
 case bitc::FUNC_CODE_DECLAREBLOCKS: // DECLAREBLOCKS: [nblocks]
-  if (Record.size() < 1)
-return Error("Invalid FUNC_CODE_DECLAREBLOCKS record");
+  if (Record.size() < 1 || Record[0] == 0)
+return Error("Invalid 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;
-}
+  CurBB = FunctionBBs[0];
+  continue;
+  
+case bitc::FUNC_CODE_INST_BINOP: {
+  // BINOP:  [opcode, ty, opval, opval]
+  if (Record.size() < 4) return Error("Invalid BINOP record");
+  const Type *Ty = getTypeByID(Record[1]);
+  int Opc = GetDecodedBinaryOpcode(Record[0], Ty);
+  Value *LHS = getFnValueByID(Record[2], Ty);
+  Value *RHS = getFnValueByID(Record[3], Ty);
+  if (Opc == -1 || Ty == 0 || LHS == 0 || RHS == 0)
+ return Error("Invalid BINOP record");
+  I = BinaryOperator::create((Instruction::BinaryOps)Opc, LHS, RHS);
+  break;
+}
+#if 0
+case bitc::FUNC_CODE_INST_CAST:
+  // CAST:   [opcode, ty, opty, opval]
+case bitc::FUNC_CODE_INST_GEP:
+  // GEP:[n, n x operands]
+case bitc::FUNC_CODE_INST_SELECT:
+  // SELECT: [ty, opval, opval, opval]
+case bitc::FUNC_CODE_INST_EXTRACTELT:
+  // EXTRACTELT: [op

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

2007-04-30 Thread Chris Lattner


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 >().swap(GlobalInits);
+  std::vector >().swap(AliasInits);
+  std::vector().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 >::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 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 va

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

2007-04-30 Thread Chris Lattner


Changes in directory llvm/lib/Bitcode/Reader:

BitcodeReader.cpp updated: 1.18 -> 1.19
BitcodeReader.h updated: 1.12 -> 1.13
---
Log message:

The stream to read from is now an ivar


---
Diffs of the changes:  (+18 -20)

 BitcodeReader.cpp |   25 -
 BitcodeReader.h   |   13 ++---
 2 files changed, 18 insertions(+), 20 deletions(-)


Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.18 
llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.19
--- llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.18  Mon Apr 30 23:59:48 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp   Tue May  1 00:01:34 2007
@@ -152,7 +152,7 @@
 }
 
 
-bool BitcodeReader::ParseTypeTable(BitstreamReader &Stream) {
+bool BitcodeReader::ParseTypeTable() {
   if (Stream.EnterSubBlock())
 return Error("Malformed block record");
   
@@ -298,7 +298,7 @@
 }
 
 
-bool BitcodeReader::ParseTypeSymbolTable(BitstreamReader &Stream) {
+bool BitcodeReader::ParseTypeSymbolTable() {
   if (Stream.EnterSubBlock())
 return Error("Malformed block record");
   
@@ -346,7 +346,7 @@
   }
 }
 
-bool BitcodeReader::ParseValueSymbolTable(BitstreamReader &Stream) {
+bool BitcodeReader::ParseValueSymbolTable() {
   if (Stream.EnterSubBlock())
 return Error("Malformed block record");
 
@@ -444,7 +444,7 @@
 }
 
 
-bool BitcodeReader::ParseConstants(BitstreamReader &Stream) {
+bool BitcodeReader::ParseConstants() {
   if (Stream.EnterSubBlock())
 return Error("Malformed block record");
 
@@ -661,7 +661,7 @@
 
 /// 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(BitstreamReader &Stream) {
+bool BitcodeReader::ParseFunction() {
   // Get the function we are talking about.
   if (FunctionsWithBodies.empty())
 return Error("Insufficient function protos");
@@ -683,8 +683,7 @@
   return false;
 }
 
-bool BitcodeReader::ParseModule(BitstreamReader &Stream,
-const std::string &ModuleID) {
+bool BitcodeReader::ParseModule(const std::string &ModuleID) {
   // Reject multiple MODULE_BLOCK's in a single bitstream.
   if (TheModule)
 return Error("Multiple MODULE_BLOCKs in same stream");
@@ -719,19 +718,19 @@
   return Error("Malformed block record");
 break;
   case bitc::TYPE_BLOCK_ID:
-if (ParseTypeTable(Stream))
+if (ParseTypeTable())
   return true;
 break;
   case bitc::TYPE_SYMTAB_BLOCK_ID:
-if (ParseTypeSymbolTable(Stream))
+if (ParseTypeSymbolTable())
   return true;
 break;
   case bitc::VALUE_SYMTAB_BLOCK_ID:
-if (ParseValueSymbolTable(Stream))
+if (ParseValueSymbolTable())
   return true;
 break;
   case bitc::CONSTANTS_BLOCK_ID:
-if (ParseConstants(Stream) || ResolveGlobalAndAliasInits())
+if (ParseConstants() || ResolveGlobalAndAliasInits())
   return true;
 break;
   case bitc::FUNCTION_BLOCK_ID:
@@ -742,7 +741,7 @@
   HasReversedFunctionsWithBodies = true;
 }
 
-if (ParseFunction(Stream))
+if (ParseFunction())
   return true;
 break;
   }
@@ -932,7 +931,7 @@
 
 // We only know the MODULE subblock ID.
 if (BlockID == bitc::MODULE_BLOCK_ID) {
-  if (ParseModule(Stream, Buffer->getBufferIdentifier()))
+  if (ParseModule(Buffer->getBufferIdentifier()))
 return true;
 } else if (Stream.SkipBlock()) {
   return Error("Malformed block record");


Index: llvm/lib/Bitcode/Reader/BitcodeReader.h
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.h:1.12 
llvm/lib/Bitcode/Reader/BitcodeReader.h:1.13
--- llvm/lib/Bitcode/Reader/BitcodeReader.h:1.12Mon Apr 30 23:59:48 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.h Tue May  1 00:01:34 2007
@@ -23,7 +23,6 @@
 #include 
 
 namespace llvm {
-  class BitstreamReader;
   class MemoryBuffer;
   
 class BitcodeReaderValueList : public User {
@@ -117,12 +116,12 @@
 private:
   const Type *getTypeByID(unsigned ID, bool isTypeTable = false);
   
-  bool ParseModule(BitstreamReader &Stream, const std::string &ModuleID);
-  bool ParseTypeTable(BitstreamReader &Stream);
-  bool ParseTypeSymbolTable(BitstreamReader &Stream);
-  bool ParseValueSymbolTable(BitstreamReader &Stream);
-  bool ParseConstants(BitstreamReader &Stream);
-  bool ParseFunction(BitstreamReader &Stream);
+  bool ParseModule(const std::string &ModuleID);
+  bool ParseTypeTable();
+  bool ParseTypeSymbolTable();
+  bool ParseValueSymbolTable();
+  bool ParseConstants();
+  bool ParseFunction();
   bool ResolveGlobalAndAliasInits();
 };
   



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


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

2007-04-30 Thread Chris Lattner


Changes in directory llvm/lib/Bitcode/Reader:

BitcodeReader.cpp updated: 1.17 -> 1.18
BitcodeReader.h updated: 1.11 -> 1.12
---
Log message:

implement scafolding for lazy deserialization of function bodies


---
Diffs of the changes:  (+85 -7)

 BitcodeReader.cpp |   65 --
 BitcodeReader.h   |   27 ++
 2 files changed, 85 insertions(+), 7 deletions(-)


Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.17 
llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.18
--- llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.17  Sun Apr 29 15:56:48 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp   Mon Apr 30 23:59:48 2007
@@ -13,7 +13,6 @@
 
 #include "llvm/Bitcode/ReaderWriter.h"
 #include "BitcodeReader.h"
-#include "llvm/Bitcode/BitstreamReader.h"
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Module.h"
@@ -660,6 +659,30 @@
   }
 }
 
+/// 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(BitstreamReader &Stream) {
+  // Get the function we are talking about.
+  if (FunctionsWithBodies.empty())
+return Error("Insufficient function protos");
+  
+  Function *Fn = FunctionsWithBodies.back();
+  FunctionsWithBodies.pop_back();
+  
+  // Save the current stream state.
+  uint64_t CurBit = Stream.GetCurrentBitNo();
+  DeferredFunctionInfo[Fn] = std::make_pair(CurBit, Fn->getLinkage());
+  
+  // Set the functions linkage to GhostLinkage so we know it is lazily
+  // deserialized.
+  Fn->setLinkage(GlobalValue::GhostLinkage);
+  
+  // Skip over the function block for now.
+  if (Stream.SkipBlock())
+return Error("Malformed block record");
+  return false;
+}
+
 bool BitcodeReader::ParseModule(BitstreamReader &Stream,
 const std::string &ModuleID) {
   // Reject multiple MODULE_BLOCK's in a single bitstream.
@@ -682,6 +705,8 @@
   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");
   return false;
@@ -709,6 +734,17 @@
 if (ParseConstants(Stream) || ResolveGlobalAndAliasInits())
   return true;
 break;
+  case bitc::FUNCTION_BLOCK_ID:
+// If this is the first function body we've seen, reverse the
+// FunctionsWithBodies list.
+if (!HasReversedFunctionsWithBodies) {
+  std::reverse(FunctionsWithBodies.begin(), FunctionsWithBodies.end());
+  HasReversedFunctionsWithBodies = true;
+}
+
+if (ParseFunction(Stream))
+  return true;
+break;
   }
   continue;
 }
@@ -819,6 +855,7 @@
 "", TheModule);
 
   Func->setCallingConv(Record[1]);
+  bool isProto = Record[2];
   Func->setLinkage(GetDecodedLinkage(Record[3]));
   Func->setAlignment((1 << Record[4]) >> 1);
   if (Record[5]) {
@@ -829,6 +866,11 @@
   Func->setVisibility(GetDecodedVisibility(Record[6]));
   
   ValueList.push_back(Func);
+  
+  // If this is a function with a body, remember the prototype we are
+  // creating now, so that we can match up the body with them later.
+  if (!isProto)
+FunctionsWithBodies.push_back(Func);
   break;
 }
 // ALIAS: [alias type, aliasee val#, linkage]
@@ -867,7 +909,7 @@
 return Error("Bitcode stream should be a multiple of 4 bytes in length");
   
   unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart();
-  BitstreamReader Stream(BufPtr, BufPtr+Buffer->getBufferSize());
+  Stream.init(BufPtr, BufPtr+Buffer->getBufferSize());
   
   // Sniff for the signature.
   if (Stream.Read(8) != 'B' ||
@@ -900,6 +942,25 @@
   return false;
 }
 
+
+bool BitcodeReader::materializeFunction(Function *F, std::string *ErrInfo) {
+  // If it already is material, ignore the request.
+  if (!F->hasNotBeenReadFromBytecode()) return false;
+
+  DenseMap >::iterator DFII = 
+DeferredFunctionInfo.find(F);
+  assert(DFII != DeferredFunctionInfo.end() && "Deferred function not found!");
+  
+  // Move the bit stream to the saved position of the deferred function body 
and
+  // restore the real linkage type for the function.
+  Stream.JumpToBit(DFII->second.first);
+  F->setLinkage((GlobalValue::LinkageTypes)DFII->second.second);
+  DeferredFunctionInfo.erase(DFII);
+  
+  return false;
+}
+
+
 
//===--===//
 // External interface
 
//===--===//


Index: llvm/lib/Bitcode/Reader/BitcodeRea

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

2007-04-29 Thread Chris Lattner


Changes in directory llvm/lib/Bitcode/Reader:

BitcodeReader.cpp updated: 1.15 -> 1.16
BitcodeReader.h updated: 1.10 -> 1.11
ReaderWrappers.cpp (r1.2) removed
---
Log message:

Switch the bitcode reader interface to take a MemoryBuffer instead of knowing
anything about disk I/O itself.  This greatly simplifies its interface -
eliminating the need for the ReaderWrappers.cpp file.

This adds a new option to llvm-dis (-bitcode) which instructs it to read
the input file as bitcode.  Until/unless the bytecode reader is taught to
read from MemoryBuffer, there is no way to handle stdin reading without it.

I don't plan to switch the bytecode reader over, I'd rather delete it :),
so the option will stay around temporarily.



---
Diffs of the changes:  (+62 -10)

 BitcodeReader.cpp |   55 +-
 BitcodeReader.h   |   17 +++-
 2 files changed, 62 insertions(+), 10 deletions(-)


Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.15 
llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.16
--- llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.15  Sat Apr 28 09:57:59 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp   Sun Apr 29 02:54:31 2007
@@ -11,6 +11,7 @@
 //
 
//===--===//
 
+#include "llvm/Bitcode/ReaderWriter.h"
 #include "BitcodeReader.h"
 #include "llvm/Bitcode/BitstreamReader.h"
 #include "llvm/Constants.h"
@@ -18,8 +19,14 @@
 #include "llvm/Module.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/MathExtras.h"
+#include "llvm/Support/MemoryBuffer.h"
 using namespace llvm;
 
+BitcodeReader::~BitcodeReader() {
+  delete Buffer;
+}
+
+
 /// ConvertToString - Convert a string from a record into an std::string, 
return
 /// true on failure.
 template
@@ -852,14 +859,14 @@
 }
 
 
-bool BitcodeReader::ParseBitcode(unsigned char *Buf, unsigned Length,
- const std::string &ModuleID) {
+bool BitcodeReader::ParseBitcode() {
   TheModule = 0;
   
-  if (Length & 3)
+  if (Buffer->getBufferSize() & 3)
 return Error("Bitcode stream should be a multiple of 4 bytes in length");
   
-  BitstreamReader Stream(Buf, Buf+Length);
+  unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart();
+  BitstreamReader Stream(BufPtr, BufPtr+Buffer->getBufferSize());
   
   // Sniff for the signature.
   if (Stream.Read(8) != 'B' ||
@@ -882,7 +889,7 @@
 
 // We only know the MODULE subblock ID.
 if (BlockID == bitc::MODULE_BLOCK_ID) {
-  if (ParseModule(Stream, ModuleID))
+  if (ParseModule(Stream, Buffer->getBufferIdentifier()))
 return true;
 } else if (Stream.SkipBlock()) {
   return Error("Malformed block record");
@@ -891,3 +898,41 @@
   
   return false;
 }
+
+//===--===//
+// External interface
+//===--===//
+
+/// getBitcodeModuleProvider - lazy function-at-a-time loading from a file.
+///
+ModuleProvider *llvm::getBitcodeModuleProvider(MemoryBuffer *Buffer,
+   std::string *ErrMsg) {
+  BitcodeReader *R = new BitcodeReader(Buffer);
+  if (R->ParseBitcode()) {
+if (ErrMsg)
+  *ErrMsg = R->getErrorString();
+
+// Don't let the BitcodeReader dtor delete 'Buffer'.
+R->releaseMemoryBuffer();
+delete R;
+return 0;
+  }
+  return R;
+}
+
+/// ParseBitcodeFile - Read the specified bitcode file, returning the module.
+/// If an error occurs, return null and fill in *ErrMsg if non-null.
+Module *llvm::ParseBitcodeFile(MemoryBuffer *Buffer, std::string *ErrMsg){
+  BitcodeReader *R;
+  R = static_cast(getBitcodeModuleProvider(Buffer, ErrMsg));
+  if (!R) return 0;
+  
+  // Read the whole module, get a pointer to it, tell ModuleProvider not to
+  // delete it when its dtor is run.
+  Module *M = R->releaseModule(ErrMsg);
+  
+  // Don't let the BitcodeReader dtor delete 'Buffer'.
+  R->releaseMemoryBuffer();
+  delete R;
+  return M;
+}


Index: llvm/lib/Bitcode/Reader/BitcodeReader.h
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.h:1.10 
llvm/lib/Bitcode/Reader/BitcodeReader.h:1.11
--- llvm/lib/Bitcode/Reader/BitcodeReader.h:1.10Wed Apr 25 22:27:58 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.h Sun Apr 29 02:54:31 2007
@@ -22,6 +22,7 @@
 
 namespace llvm {
   class BitstreamReader;
+  class MemoryBuffer;
   
 class BitcodeReaderValueList : public User {
   std::vector Uses;
@@ -57,6 +58,7 @@
   
 
 class BitcodeReader : public ModuleProvider {
+  MemoryBuffer *Buffer;
   const char *ErrorString;
   
   std::vector TypeList;
@@ -64,10 +66,16 @@
   std::vector > GlobalInits;
   std::vector > AliasInits;
 public:
-  BitcodeReader() : ErrorString(0) {}
-  virtual ~BitcodeReader() {}
+  BitcodeReader(MemoryBuffer *buffer) : Buffer(buffer), ErrorString(0) {}
+  ~Bitcode

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

2007-04-25 Thread Chris Lattner


Changes in directory llvm/lib/Bitcode/Reader:

BitcodeReader.cpp updated: 1.13 -> 1.14
BitcodeReader.h updated: 1.9 -> 1.10
---
Log message:

move some code around, fix a bug in the reader reading globalinits (which
I just introduced), stub out function reading, purge aggregate values from
the value table before reading functions.


---
Diffs of the changes:  (+16 -3)

 BitcodeReader.cpp |   14 +++---
 BitcodeReader.h   |5 +
 2 files changed, 16 insertions(+), 3 deletions(-)


Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.13 
llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.14
--- llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.13  Wed Apr 25 21:46:40 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp   Wed Apr 25 22:27:58 2007
@@ -408,10 +408,10 @@
   AliasInitWorklist.swap(AliasInits);
 
   while (!GlobalInitWorklist.empty()) {
-unsigned ValID = GlobalInits.back().second;
+unsigned ValID = GlobalInitWorklist.back().second;
 if (ValID >= ValueList.size()) {
   // Not ready to resolve this yet, it requires something later in the 
file.
-  GlobalInitWorklist.push_back(GlobalInits.back());
+  GlobalInits.push_back(GlobalInitWorklist.back());
 } else {
   if (Constant *C = dyn_cast(ValueList[ValID]))
 GlobalInitWorklist.back().first->setInitializer(C);
@@ -826,7 +826,7 @@
   break;
 }
 // ALIAS: [alias type, aliasee val#, linkage]
-case bitc::MODULE_CODE_ALIAS:
+case bitc::MODULE_CODE_ALIAS: {
   if (Record.size() < 3)
 return Error("Invalid MODULE_ALIAS record");
   const Type *Ty = getTypeByID(Record[0]);
@@ -839,6 +839,14 @@
   AliasInits.push_back(std::make_pair(NewGA, Record[1]));
   break;
 }
+/// MODULE_CODE_PURGEVALS: [numvals]
+case bitc::MODULE_CODE_PURGEVALS:
+  // Trim down the value list to the specified size.
+  if (Record.size() < 1 || Record[0] > ValueList.size())
+return Error("Invalid MODULE_PURGEVALS record");
+  ValueList.shrinkTo(Record[0]);
+  break;
+}
 Record.clear();
   }
   


Index: llvm/lib/Bitcode/Reader/BitcodeReader.h
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.h:1.9 
llvm/lib/Bitcode/Reader/BitcodeReader.h:1.10
--- llvm/lib/Bitcode/Reader/BitcodeReader.h:1.9 Wed Apr 25 21:46:40 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.h Wed Apr 25 22:27:58 2007
@@ -41,6 +41,11 @@
   Value *back() const { return Uses.back(); }
   void pop_back() { Uses.pop_back(); --NumOperands; }
   bool empty() const { return NumOperands == 0; }
+  void shrinkTo(unsigned N) {
+assert(N < NumOperands && "Invalid shrinkTo request!");
+Uses.resize(N);
+NumOperands = N;
+  }
   virtual void print(std::ostream&) const {}
   
   Constant *getConstantFwdRef(unsigned Idx, const Type *Ty);



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


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

2007-04-25 Thread Chris Lattner


Changes in directory llvm/lib/Bitcode/Reader:

BitcodeReader.cpp updated: 1.12 -> 1.13
BitcodeReader.h updated: 1.8 -> 1.9
---
Log message:

add bitcode alias support



---
Diffs of the changes:  (+59 -17)

 BitcodeReader.cpp |   74 +-
 BitcodeReader.h   |2 +
 2 files changed, 59 insertions(+), 17 deletions(-)


Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.12 
llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.13
--- llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.12  Tue Apr 24 13:15:21 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp   Wed Apr 25 21:46:40 2007
@@ -398,6 +398,47 @@
   return 1ULL << 63;
 }
 
+/// ResolveGlobalAndAliasInits - Resolve all of the initializers for global
+/// values and aliases that we can.
+bool BitcodeReader::ResolveGlobalAndAliasInits() {
+  std::vector > GlobalInitWorklist;
+  std::vector > AliasInitWorklist;
+  
+  GlobalInitWorklist.swap(GlobalInits);
+  AliasInitWorklist.swap(AliasInits);
+
+  while (!GlobalInitWorklist.empty()) {
+unsigned ValID = GlobalInits.back().second;
+if (ValID >= ValueList.size()) {
+  // Not ready to resolve this yet, it requires something later in the 
file.
+  GlobalInitWorklist.push_back(GlobalInits.back());
+} else {
+  if (Constant *C = dyn_cast(ValueList[ValID]))
+GlobalInitWorklist.back().first->setInitializer(C);
+  else
+return Error("Global variable initializer is not a constant!");
+}
+GlobalInitWorklist.pop_back(); 
+  }
+
+  while (!AliasInitWorklist.empty()) {
+unsigned ValID = AliasInitWorklist.back().second;
+if (ValID >= ValueList.size()) {
+  AliasInits.push_back(AliasInitWorklist.back());
+} else {
+  if (Constant *C = dyn_cast(ValueList[ValID]))
+AliasInitWorklist.back().first->setAliasee(
+// FIXME:
+cast(C));
+  else
+return Error("Alias initializer is not a constant!");
+}
+AliasInitWorklist.pop_back(); 
+  }
+  return false;
+}
+
+
 bool BitcodeReader::ParseConstants(BitstreamReader &Stream) {
   if (Stream.EnterSubBlock())
 return Error("Malformed block record");
@@ -410,20 +451,6 @@
   while (1) {
 unsigned Code = Stream.ReadCode();
 if (Code == bitc::END_BLOCK) {
-  // If there are global var inits to process, do so now.
-  if (!GlobalInits.empty()) {
-while (!GlobalInits.empty()) {
-  unsigned ValID = GlobalInits.back().second;
-  if (ValID >= ValueList.size())
-return Error("Invalid value ID for global var init!");
-  if (Constant *C = dyn_cast(ValueList[ValID]))
-GlobalInits.back().first->setInitializer(C);
-  else
-return Error("Global variable initializer is not a constant!");
-  GlobalInits.pop_back(); 
-}
-  }
-  
   if (NextCstNo != ValueList.size())
 return Error("Invalid constant reference!");
   
@@ -646,7 +673,8 @@
   while (!Stream.AtEndOfStream()) {
 unsigned Code = Stream.ReadCode();
 if (Code == bitc::END_BLOCK) {
-  if (!GlobalInits.empty())
+  ResolveGlobalAndAliasInits();
+  if (!GlobalInits.empty() || !AliasInits.empty())
 return Error("Malformed global initializer set");
   if (Stream.ReadBlockEnd())
 return Error("Error at end of module block");
@@ -672,7 +700,7 @@
   return true;
 break;
   case bitc::CONSTANTS_BLOCK_ID:
-if (ParseConstants(Stream))
+if (ParseConstants(Stream) || ResolveGlobalAndAliasInits())
   return true;
 break;
   }
@@ -795,9 +823,21 @@
   Func->setVisibility(GetDecodedVisibility(Record[6]));
   
   ValueList.push_back(Func);
-  // TODO: remember initializer/global pair for later substitution.
   break;
 }
+// ALIAS: [alias type, aliasee val#, linkage]
+case bitc::MODULE_CODE_ALIAS:
+  if (Record.size() < 3)
+return Error("Invalid MODULE_ALIAS record");
+  const Type *Ty = getTypeByID(Record[0]);
+  if (!isa(Ty))
+return Error("Function not a pointer type!");
+  
+  GlobalAlias *NewGA = new GlobalAlias(Ty, GetDecodedLinkage(Record[2]),
+   "", 0, TheModule);
+  ValueList.push_back(NewGA);
+  AliasInits.push_back(std::make_pair(NewGA, Record[1]));
+  break;
 }
 Record.clear();
   }


Index: llvm/lib/Bitcode/Reader/BitcodeReader.h
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.h:1.8 
llvm/lib/Bitcode/Reader/BitcodeReader.h:1.9
--- llvm/lib/Bitcode/Reader/BitcodeReader.h:1.8 Tue Apr 24 13:15:21 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.h Wed Apr 25 21:46:40 2007
@@ -57,6 +57,7 @@
   std::vector TypeList;
   BitcodeReaderValueList ValueList;
   std::vector > GlobalInits;
+  std::vector > AliasInits;
 public:
   BitcodeRead

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

2007-04-24 Thread Chris Lattner


Changes in directory llvm/lib/Bitcode/Reader:

BitcodeReader.cpp updated: 1.11 -> 1.12
BitcodeReader.h updated: 1.7 -> 1.8
ReaderWrappers.cpp updated: 1.1 -> 1.2
---
Log message:

ensure that every error return sets a message (and goes through Error, for
easy breakpointing).

Fix bugs reading constantexpr geps.  We now can disassemble kc++ global 
initializers.


---
Diffs of the changes:  (+37 -19)

 BitcodeReader.cpp  |   54 ++---
 BitcodeReader.h|1 
 ReaderWrappers.cpp |1 
 3 files changed, 37 insertions(+), 19 deletions(-)


Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.11 
llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.12
--- llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.11  Tue Apr 24 12:22:05 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp   Tue Apr 24 13:15:21 2007
@@ -161,7 +161,9 @@
 if (Code == bitc::END_BLOCK) {
   if (NumRecords != TypeList.size())
 return Error("Invalid type forward reference in TYPE_BLOCK");
-  return Stream.ReadBlockEnd();
+  if (Stream.ReadBlockEnd())
+return Error("Error at end of type table block");
+  return false;
 }
 
 if (Code == bitc::ENTER_SUBBLOCK) {
@@ -299,8 +301,11 @@
   std::string TypeName;
   while (1) {
 unsigned Code = Stream.ReadCode();
-if (Code == bitc::END_BLOCK)
-  return Stream.ReadBlockEnd();
+if (Code == bitc::END_BLOCK) {
+  if (Stream.ReadBlockEnd())
+return Error("Error at end of type symbol table block");
+  return false;
+}
 
 if (Code == bitc::ENTER_SUBBLOCK) {
   // No known subblocks, always skip them.
@@ -344,9 +349,11 @@
   SmallString<128> ValueName;
   while (1) {
 unsigned Code = Stream.ReadCode();
-if (Code == bitc::END_BLOCK)
-  return Stream.ReadBlockEnd();
-
+if (Code == bitc::END_BLOCK) {
+  if (Stream.ReadBlockEnd())
+return Error("Error at end of value symbol table block");
+  return false;
+}
 if (Code == bitc::ENTER_SUBBLOCK) {
   // No known subblocks, always skip them.
   Stream.ReadSubBlockID();
@@ -420,7 +427,9 @@
   if (NextCstNo != ValueList.size())
 return Error("Invalid constant reference!");
   
-  return Stream.ReadBlockEnd();
+  if (Stream.ReadBlockEnd())
+return Error("Error at end of constants block");
+  return false;
 }
 
 if (Code == bitc::ENTER_SUBBLOCK) {
@@ -515,21 +524,25 @@
 case bitc::CST_CODE_CE_BINOP: {  // CE_BINOP: [opcode, opval, opval]
   if (Record.size() < 3) return Error("Invalid CE_BINOP record");
   int Opc = GetDecodedBinaryOpcode(Record[0], CurTy);
-  if (Opc < 0) return UndefValue::get(CurTy);  // Unknown binop.
-  
-  Constant *LHS = ValueList.getConstantFwdRef(Record[1], CurTy);
-  Constant *RHS = ValueList.getConstantFwdRef(Record[2], CurTy);
-  V = ConstantExpr::get(Opc, LHS, RHS);
+  if (Opc < 0) {
+V = UndefValue::get(CurTy);  // Unknown binop.
+  } else {
+Constant *LHS = ValueList.getConstantFwdRef(Record[1], CurTy);
+Constant *RHS = ValueList.getConstantFwdRef(Record[2], CurTy);
+V = ConstantExpr::get(Opc, LHS, RHS);
+  }
   break;
 }  
 case bitc::CST_CODE_CE_CAST: {  // CE_CAST: [opcode, opty, opval]
   if (Record.size() < 3) return Error("Invalid CE_CAST record");
   int Opc = GetDecodedCastOpcode(Record[0]);
-  if (Opc < 0) return UndefValue::get(CurTy);  // Unknown cast.
-  
-  const Type *OpTy = getTypeByID(Record[1]);
-  Constant *Op = ValueList.getConstantFwdRef(Record[2], OpTy);
-  V = ConstantExpr::getCast(Opc, Op, CurTy);
+  if (Opc < 0) {
+V = UndefValue::get(CurTy);  // Unknown cast.
+  } else {
+const Type *OpTy = getTypeByID(Record[1]);
+Constant *Op = ValueList.getConstantFwdRef(Record[2], OpTy);
+V = ConstantExpr::getCast(Opc, Op, CurTy);
+  }
   break;
 }  
 case bitc::CST_CODE_CE_GEP: {  // CE_GEP:[n x operands]
@@ -540,7 +553,8 @@
 if (!ElTy) return Error("Invalid CE_GEP record");
 Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], ElTy));
   }
-  return ConstantExpr::getGetElementPtr(Elts[0], &Elts[1], Elts.size()-1);
+  V = ConstantExpr::getGetElementPtr(Elts[0], &Elts[1], Elts.size()-1);
+  break;
 }
 case bitc::CST_CODE_CE_SELECT:  // CE_SELECT: [opval#, opval#, opval#]
   if (Record.size() < 3) return Error("Invalid CE_SELECT record");
@@ -634,7 +648,9 @@
 if (Code == bitc::END_BLOCK) {
   if (!GlobalInits.empty())
 return Error("Malformed global initializer set");
-  return Stream.ReadBlockEnd();
+  if (Stream.ReadBlockEnd())
+return Error("Error at end of module block");
+  return false;
 }
 
 if (Code == bitc::ENTER_SUBBLOCK) {


Index: llvm/lib/Bitcode/Reader/BitcodeRea

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

2007-04-23 Thread Chris Lattner


Changes in directory llvm/lib/Bitcode/Reader:

BitcodeReader.cpp updated: 1.8 -> 1.9
BitcodeReader.h updated: 1.6 -> 1.7
---
Log message:

implement support for reading aggregate constants, including handling forward
constant references, etc.


---
Diffs of the changes:  (+108 -5)

 BitcodeReader.cpp |   78 +-
 BitcodeReader.h   |   35 +---
 2 files changed, 108 insertions(+), 5 deletions(-)


Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.8 
llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.9
--- llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.8   Mon Apr 23 23:04:35 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp   Tue Apr 24 00:48:56 2007
@@ -55,6 +55,39 @@
   }
 }
 
+namespace {
+  /// @brief A class for maintaining the slot number definition
+  /// as a placeholder for the actual definition for forward constants defs.
+  class ConstantPlaceHolder : public ConstantExpr {
+ConstantPlaceHolder();   // DO NOT IMPLEMENT
+void operator=(const ConstantPlaceHolder &); // DO NOT IMPLEMENT
+public:
+  Use Op;
+  ConstantPlaceHolder(const Type *Ty)
+: ConstantExpr(Ty, Instruction::UserOp1, &Op, 1),
+  Op(UndefValue::get(Type::Int32Ty), this) {
+}
+  };
+}
+
+Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx,
+const Type *Ty) {
+  if (Idx >= size()) {
+// Insert a bunch of null values.
+Uses.resize(Idx+1);
+OperandList = &Uses[0];
+NumOperands = Idx+1;
+  }
+
+  if (Uses[Idx])
+return cast(getOperand(Idx));
+
+  // Create and return a placeholder, which will later be RAUW'd.
+  Constant *C = new ConstantPlaceHolder(Ty);
+  Uses[Idx].init(C, this);
+  return C;
+}
+
 
 const Type *BitcodeReader::getTypeByID(unsigned ID, bool isTypeTable) {
   // If the TypeID is in range, return it.
@@ -324,6 +357,7 @@
   
   // Read all the records for this value table.
   const Type *CurTy = Type::Int32Ty;
+  unsigned NextCstNo = ValueList.size();
   while (1) {
 unsigned Code = Stream.ReadCode();
 if (Code == bitc::END_BLOCK) {
@@ -341,6 +375,9 @@
 }
   }
   
+  if (NextCstNo != ValueList.size())
+return Error("Invalid constant reference!");
+  
   return Stream.ReadBlockEnd();
 }
 
@@ -403,9 +440,48 @@
   else
 V = UndefValue::get(CurTy);
   break;
+  
+case bitc::CST_CODE_AGGREGATE: {// AGGREGATE: [n, n x value number]
+  if (Record.empty() || Record.size() < Record[0]+1)
+return Error("Invalid CST_AGGREGATE record");
+  
+  unsigned Size = Record[0];
+  std::vector Elts;
+  
+  if (const StructType *STy = dyn_cast(CurTy)) {
+for (unsigned i = 0; i != Size; ++i)
+  Elts.push_back(ValueList.getConstantFwdRef(Record[i+1],
+ STy->getElementType(i)));
+V = ConstantStruct::get(STy, Elts);
+  } else if (const ArrayType *ATy = dyn_cast(CurTy)) {
+const Type *EltTy = ATy->getElementType();
+for (unsigned i = 0; i != Size; ++i)
+  Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], EltTy));
+V = ConstantArray::get(ATy, Elts);
+  } else if (const VectorType *VTy = dyn_cast(CurTy)) {
+const Type *EltTy = VTy->getElementType();
+for (unsigned i = 0; i != Size; ++i)
+  Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], EltTy));
+V = ConstantVector::get(Elts);
+  } else {
+V = UndefValue::get(CurTy);
+  }
+}
+}
+
+if (NextCstNo == ValueList.size())
+  ValueList.push_back(V);
+else if (ValueList[NextCstNo] == 0)
+  ValueList.initVal(NextCstNo, V);
+else {
+  // If there was a forward reference to this constant, 
+  Value *OldV = ValueList[NextCstNo];
+  ValueList.setOperand(NextCstNo, V);
+  OldV->replaceAllUsesWith(V);
+  delete OldV;
 }
 
-ValueList.push_back(V);
+++NextCstNo;
   }
 }
 


Index: llvm/lib/Bitcode/Reader/BitcodeReader.h
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.h:1.6 
llvm/lib/Bitcode/Reader/BitcodeReader.h:1.7
--- llvm/lib/Bitcode/Reader/BitcodeReader.h:1.6 Mon Apr 23 22:30:34 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.h Tue Apr 24 00:48:56 2007
@@ -14,21 +14,48 @@
 #ifndef BITCODE_READER_H
 #define BITCODE_READER_H
 
-#include "llvm/Type.h"
 #include "llvm/ModuleProvider.h"
+#include "llvm/Type.h"
+#include "llvm/User.h"
 #include "llvm/Bitcode/LLVMBitCodes.h"
 #include 
 
 namespace llvm {
   class BitstreamReader;
-  class Value;
-  class GlobalVariable;
+  
+class BitcodeReaderValueList : public User {
+  std::vector Uses;
+public:
+  BitcodeReaderValueList() : User(Type::VoidTy, Value::ArgumentVal, 0, 0) {}
+  
+  // vector compatibility methods
+  unsigned size() const { return getNumOperands(); }
+  void push_back(

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

2007-04-23 Thread Chris Lattner


Changes in directory llvm/lib/Bitcode/Reader:

BitcodeReader.cpp updated: 1.6 -> 1.7
BitcodeReader.h updated: 1.5 -> 1.6
---
Log message:

read basic constants: null, undef, integers <= 64bits


---
Diffs of the changes:  (+80 -2)

 BitcodeReader.cpp |   77 ++
 BitcodeReader.h   |5 ++-
 2 files changed, 80 insertions(+), 2 deletions(-)


Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.6 
llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.7
--- llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.6   Mon Apr 23 19:21:45 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp   Mon Apr 23 22:30:34 2007
@@ -13,6 +13,7 @@
 
 #include "BitcodeReader.h"
 #include "llvm/Bitcode/BitstreamReader.h"
+#include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Module.h"
 #include "llvm/ADT/SmallString.h"
@@ -303,6 +304,78 @@
   }
 }
 
+bool BitcodeReader::ParseConstants(BitstreamReader &Stream) {
+  if (Stream.EnterSubBlock())
+return Error("Malformed block record");
+
+  SmallVector Record;
+  
+  // Read all the records for this value table.
+  const Type *CurTy = Type::Int32Ty;
+  while (1) {
+unsigned Code = Stream.ReadCode();
+if (Code == bitc::END_BLOCK) {
+  // If there are global var inits to process, do so now.
+  if (!GlobalInits.empty()) {
+while (!GlobalInits.empty()) {
+  unsigned ValID = GlobalInits.back().second;
+  if (ValID >= ValueList.size())
+return Error("Invalid value ID for global var init!");
+  if (Constant *C = dyn_cast(ValueList[ValID]))
+GlobalInits.back().first->setInitializer(C);
+  else
+return Error("Global variable initializer is not a constant!");
+  GlobalInits.pop_back(); 
+}
+  }
+  
+  return Stream.ReadBlockEnd();
+}
+
+if (Code == bitc::ENTER_SUBBLOCK) {
+  // No known subblocks, always skip them.
+  Stream.ReadSubBlockID();
+  if (Stream.SkipBlock())
+return Error("Malformed block record");
+  continue;
+}
+
+if (Code == bitc::DEFINE_ABBREV) {
+  Stream.ReadAbbrevRecord();
+  continue;
+}
+
+// Read a record.
+Record.clear();
+Value *V = 0;
+switch (Stream.ReadRecord(Code, Record)) {
+default:  // Default behavior: unknown constant
+case bitc::CST_CODE_UNDEF: // UNDEF
+  V = UndefValue::get(CurTy);
+  break;
+case bitc::CST_CODE_SETTYPE:   // SETTYPE: [typeid]
+  if (Record.empty())
+return Error("Malformed CST_SETTYPE record");
+  if (Record[0] >= TypeList.size())
+return Error("Invalid Type ID in CST_SETTYPE record");
+  CurTy = TypeList[Record[0]];
+  continue;
+case bitc::CST_CODE_NULL:  // NULL
+  V = Constant::getNullValue(CurTy);
+  break;
+case bitc::CST_CODE_INTEGER:   // INTEGER: [intval]
+  if (!isa(CurTy))
+return Error("Invalid type for CST_INTEGER");
+  if (Record[0] & 1)
+V = ConstantInt::get(CurTy, -(Record[0]>>1));
+  else
+V = ConstantInt::get(CurTy, Record[0]>>1);
+  break;
+}
+
+ValueList.push_back(V);
+  }
+}
 
 bool BitcodeReader::ParseModule(BitstreamReader &Stream,
 const std::string &ModuleID) {
@@ -346,6 +419,10 @@
 if (ParseValueSymbolTable(Stream))
   return true;
 break;
+  case bitc::CONSTANTS_BLOCK_ID:
+if (ParseConstants(Stream))
+  return true;
+break;
   }
   continue;
 }


Index: llvm/lib/Bitcode/Reader/BitcodeReader.h
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.h:1.5 
llvm/lib/Bitcode/Reader/BitcodeReader.h:1.6
--- llvm/lib/Bitcode/Reader/BitcodeReader.h:1.5 Mon Apr 23 19:18:21 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.h Mon Apr 23 22:30:34 2007
@@ -22,14 +22,14 @@
 namespace llvm {
   class BitstreamReader;
   class Value;
-  class GlobalValue;
+  class GlobalVariable;
 
 class BitcodeReader : public ModuleProvider {
   const char *ErrorString;
   
   std::vector TypeList;
   std::vector ValueList;
-  std::vector > GlobalInits;
+  std::vector > GlobalInits;
 public:
   virtual ~BitcodeReader() {}
   
@@ -64,6 +64,7 @@
   bool ParseTypeTable(BitstreamReader &Stream);
   bool ParseTypeSymbolTable(BitstreamReader &Stream);
   bool ParseValueSymbolTable(BitstreamReader &Stream);
+  bool ParseConstants(BitstreamReader &Stream);
 };
   
 } // End llvm namespace



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


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

2007-04-23 Thread Chris Lattner


Changes in directory llvm/lib/Bitcode/Reader:

BitcodeReader.cpp updated: 1.4 -> 1.5
BitcodeReader.h updated: 1.4 -> 1.5
---
Log message:

track global inits


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

 BitcodeReader.cpp |   10 +++---
 BitcodeReader.h   |2 ++
 2 files changed, 9 insertions(+), 3 deletions(-)


Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.4 
llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.5
--- llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.4   Mon Apr 23 16:26:05 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp   Mon Apr 23 19:18:21 2007
@@ -243,7 +243,7 @@
 switch (Stream.ReadRecord(Code, Record)) {
 default:  // Default behavior: unknown type.
   break;
-case bitc::TST_ENTRY_CODE:// TST_ENTRY: [typeid, namelen, namechar x N]
+case bitc::TST_CODE_ENTRY:// TST_ENTRY: [typeid, namelen, namechar x N]
   if (ConvertToString(Record, 1, TypeName))
 return Error("Invalid TST_ENTRY record");
   unsigned TypeID = Record[0];
@@ -288,7 +288,7 @@
 switch (Stream.ReadRecord(Code, Record)) {
 default:  // Default behavior: unknown type.
   break;
-case bitc::VST_ENTRY_CODE:// VST_ENTRY: [valueid, namelen, namechar x 
N]
+case bitc::TST_CODE_ENTRY:// VST_ENTRY: [valueid, namelen, namechar x 
N]
   if (ConvertToString(Record, 1, ValueName))
 return Error("Invalid TST_ENTRY record");
   unsigned ValueID = Record[0];
@@ -358,6 +358,8 @@
 case bitc::MODULE_CODE_VERSION:  // VERSION: [version#]
   if (Record.size() < 1)
 return Error("Malformed MODULE_CODE_VERSION");
+  if (!GlobalInits.empty())
+return Error("Malformed global initializer set");
   // Only version #0 is supported so far.
   if (Record[0] != 0)
 return Error("Unknown bitstream version!");
@@ -431,7 +433,9 @@
   
   ValueList.push_back(NewGV);
   
-  // TODO: remember initializer/global pair for later substitution.
+  // Remember which value to use for the global initializer.
+  if (unsigned InitID = Record[2])
+GlobalInits.push_back(std::make_pair(NewGV, InitID-1));
   break;
 }
 // FUNCTION:  [type, callingconv, isproto, linkage, alignment, section,


Index: llvm/lib/Bitcode/Reader/BitcodeReader.h
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.h:1.4 
llvm/lib/Bitcode/Reader/BitcodeReader.h:1.5
--- llvm/lib/Bitcode/Reader/BitcodeReader.h:1.4 Mon Apr 23 16:26:05 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.h Mon Apr 23 19:18:21 2007
@@ -22,12 +22,14 @@
 namespace llvm {
   class BitstreamReader;
   class Value;
+  class GlobalValue;
 
 class BitcodeReader : public ModuleProvider {
   const char *ErrorString;
   
   std::vector TypeList;
   std::vector ValueList;
+  std::vector > GlobalInits;
 public:
   virtual ~BitcodeReader() {}
   



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


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

2007-04-23 Thread Chris Lattner


Changes in directory llvm/lib/Bitcode/Reader:

BitcodeReader.cpp updated: 1.3 -> 1.4
BitcodeReader.h updated: 1.3 -> 1.4
---
Log message:

Read global symtab


---
Diffs of the changes:  (+59 -3)

 BitcodeReader.cpp |   59 +++---
 BitcodeReader.h   |3 ++
 2 files changed, 59 insertions(+), 3 deletions(-)


Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.3 
llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.4
--- llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.3   Mon Apr 23 13:58:34 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp   Mon Apr 23 16:26:05 2007
@@ -15,12 +15,14 @@
 #include "llvm/Bitcode/BitstreamReader.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Module.h"
+#include "llvm/ADT/SmallString.h"
 using namespace llvm;
 
 /// ConvertToString - Convert a string from a record into an std::string, 
return
 /// true on failure.
+template
 static bool ConvertToString(SmallVector &Record, unsigned Idx,
-std::string &Result) {
+StrTy &Result) {
   if (Record.size() < Idx+1 || Record.size() < Record[Idx]+Idx+1)
 return true;
   
@@ -255,6 +257,52 @@
   }
 }
 
+bool BitcodeReader::ParseValueSymbolTable(BitstreamReader &Stream) {
+  if (Stream.EnterSubBlock())
+return Error("Malformed block record");
+
+  SmallVector Record;
+  
+  // Read all the records for this value table.
+  SmallString<128> ValueName;
+  while (1) {
+unsigned Code = Stream.ReadCode();
+if (Code == bitc::END_BLOCK)
+  return Stream.ReadBlockEnd();
+
+if (Code == bitc::ENTER_SUBBLOCK) {
+  // No known subblocks, always skip them.
+  Stream.ReadSubBlockID();
+  if (Stream.SkipBlock())
+return Error("Malformed block record");
+  continue;
+}
+
+if (Code == bitc::DEFINE_ABBREV) {
+  Stream.ReadAbbrevRecord();
+  continue;
+}
+
+// Read a record.
+Record.clear();
+switch (Stream.ReadRecord(Code, Record)) {
+default:  // Default behavior: unknown type.
+  break;
+case bitc::VST_ENTRY_CODE:// VST_ENTRY: [valueid, namelen, namechar x 
N]
+  if (ConvertToString(Record, 1, ValueName))
+return Error("Invalid TST_ENTRY record");
+  unsigned ValueID = Record[0];
+  if (ValueID >= ValueList.size())
+return Error("Invalid Value ID in VST_ENTRY record");
+  Value *V = ValueList[ValueID];
+  
+  V->setName(&ValueName[0], ValueName.size());
+  ValueName.clear();
+  break;
+}
+  }
+}
+
 
 bool BitcodeReader::ParseModule(BitstreamReader &Stream,
 const std::string &ModuleID) {
@@ -291,6 +339,10 @@
 if (ParseTypeSymbolTable(Stream))
   return true;
 break;
+  case bitc::VALUE_SYMTAB_BLOCK_ID:
+if (ParseValueSymbolTable(Stream))
+  return true;
+break;
   }
   continue;
 }
@@ -377,7 +429,8 @@
   NewGV->setVisibility(Visibility);
   NewGV->setThreadLocal(isThreadLocal);
   
-  // TODO: Add to value table.
+  ValueList.push_back(NewGV);
+  
   // TODO: remember initializer/global pair for later substitution.
   break;
 }
@@ -407,7 +460,7 @@
   }
   Func->setVisibility(GetDecodedVisibility(Record[6]));
   
-  // TODO: Add to value table.
+  ValueList.push_back(Func);
   // TODO: remember initializer/global pair for later substitution.
   break;
 }


Index: llvm/lib/Bitcode/Reader/BitcodeReader.h
diff -u llvm/lib/Bitcode/Reader/BitcodeReader.h:1.3 
llvm/lib/Bitcode/Reader/BitcodeReader.h:1.4
--- llvm/lib/Bitcode/Reader/BitcodeReader.h:1.3 Sun Apr 22 20:01:37 2007
+++ llvm/lib/Bitcode/Reader/BitcodeReader.h Mon Apr 23 16:26:05 2007
@@ -21,11 +21,13 @@
 
 namespace llvm {
   class BitstreamReader;
+  class Value;
 
 class BitcodeReader : public ModuleProvider {
   const char *ErrorString;
   
   std::vector TypeList;
+  std::vector ValueList;
 public:
   virtual ~BitcodeReader() {}
   
@@ -59,6 +61,7 @@
   bool ParseModule(BitstreamReader &Stream, const std::string &ModuleID);
   bool ParseTypeTable(BitstreamReader &Stream);
   bool ParseTypeSymbolTable(BitstreamReader &Stream);
+  bool ParseValueSymbolTable(BitstreamReader &Stream);
 };
   
 } // End llvm namespace



___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


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

2007-04-21 Thread Chris Lattner


Changes in directory llvm/lib/Bitcode/Reader:

BitcodeReader.cpp added (r1.1)
BitcodeReader.h added (r1.1)
Makefile added (r1.1)
ReaderWrappers.cpp added (r1.1)
---
Log message:

Initial support for reading bitcode files.  They currently only read types,
the type symtab, and global/function protos, and are missing the important
size optimization, but it is a place to start.


---
Diffs of the changes:  (+633 -0)

 BitcodeReader.cpp  |  455 +
 BitcodeReader.h|   66 +++
 Makefile   |   15 +
 ReaderWrappers.cpp |   97 +++
 4 files changed, 633 insertions(+)


Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff -c /dev/null llvm/lib/Bitcode/Reader/BitcodeReader.cpp:1.1
*** /dev/null   Sun Apr 22 01:23:39 2007
--- llvm/lib/Bitcode/Reader/BitcodeReader.cpp   Sun Apr 22 01:23:29 2007
***
*** 0 
--- 1,455 
+ //===- BitcodeReader.cpp - Internal BitcodeReader implementation 
--===//
+ //
+ // The LLVM Compiler Infrastructure
+ //
+ // This file was developed by Chris Lattner and is distributed under
+ // the University of Illinois Open Source License.  See LICENSE.TXT for 
details.
+ //
+ 
//===--===//
+ //
+ // This header defines the BitcodeReader class.
+ //
+ 
//===--===//
+ 
+ #include "BitcodeReader.h"
+ #include "llvm/Bitcode/BitstreamReader.h"
+ #include "llvm/DerivedTypes.h"
+ #include "llvm/Module.h"
+ using namespace llvm;
+ 
+ /// ConvertToString - Convert a string from a record into an std::string, 
return
+ /// true on failure.
+ static bool ConvertToString(SmallVector &Record, unsigned Idx,
+ std::string &Result) {
+   if (Record.size() < Idx+1 || Record.size() < Record[Idx]+Idx+1)
+ return true;
+   
+   for (unsigned i = 0, e = Record[Idx]; i != e; ++i)
+ Result += (char)Record[Idx+i+1];
+   return false;
+ }
+ 
+ static GlobalValue::LinkageTypes GetDecodedLinkage(unsigned Val) {
+   switch (Val) {
+   default: // Map unknown/new linkages to external
+   case 0: return GlobalValue::ExternalLinkage;
+   case 1: return GlobalValue::WeakLinkage;
+   case 2: return GlobalValue::AppendingLinkage;
+   case 3: return GlobalValue::InternalLinkage;
+   case 4: return GlobalValue::LinkOnceLinkage;
+   case 5: return GlobalValue::DLLImportLinkage;
+   case 6: return GlobalValue::DLLExportLinkage;
+   case 7: return GlobalValue::ExternalWeakLinkage;
+   }
+ }
+ 
+ static GlobalValue::VisibilityTypes GetDecodedVisibility(unsigned Val) {
+   switch (Val) {
+   default: // Map unknown visibilities to default.
+   case 0: return GlobalValue::DefaultVisibility;
+   case 1: return GlobalValue::HiddenVisibility;
+   }
+ }
+ 
+ 
+ const Type *BitcodeReader::getTypeByID(unsigned ID, bool isTypeTable) {
+   // If the TypeID is in range, return it.
+   if (ID < TypeList.size())
+ return TypeList[ID].get();
+   if (!isTypeTable) return 0;
+   
+   // The type table allows forward references.  Push as many Opaque types as
+   // needed to get up to ID.
+   while (TypeList.size() <= ID)
+ TypeList.push_back(OpaqueType::get());
+   return TypeList.back().get();
+ }
+ 
+ 
+ bool BitcodeReader::ParseTypeTable(BitstreamReader &Stream) {
+   if (Stream.EnterSubBlock())
+ return Error("Malformed block record");
+   
+   if (!TypeList.empty())
+ return Error("Multiple TYPE_BLOCKs found!");
+ 
+   SmallVector Record;
+   unsigned NumRecords = 0;
+ 
+   // Read all the records for this type table.
+   while (1) {
+ unsigned Code = Stream.ReadCode();
+ if (Code == bitc::END_BLOCK) {
+   if (NumRecords != TypeList.size())
+ return Error("Invalid type forward reference in TYPE_BLOCK");
+   return Stream.ReadBlockEnd();
+ }
+ 
+ if (Code == bitc::ENTER_SUBBLOCK) {
+   // No known subblocks, always skip them.
+   Stream.ReadSubBlockID();
+   if (Stream.SkipBlock())
+ return Error("Malformed block record");
+   continue;
+ }
+ 
+ if (Code == bitc::DEFINE_ABBREVS) {
+   assert(0 && "Abbrevs not implemented yet!");
+ }
+ 
+ // Read a record.
+ Record.clear();
+ const Type *ResultTy = 0;
+ switch (Stream.ReadRecord(Code, Record)) {
+ default:  // Default behavior: unknown type.
+   ResultTy = 0;
+   break;
+ case bitc::TYPE_CODE_NUMENTRY: // TYPE_CODE_NUMENTRY: [numentries]
+   // TYPE_CODE_NUMENTRY contains a count of the number of types in the
+   // type list.  This allows us to reserve space.
+   if (Record.size() < 1)
+ return Error("Invalid TYPE_CODE_NUMENTRY record");
+   TypeList.reserve(Record[0]);
+   continue;
+ case bitc::TYPE_CODE_META:  // TYPE_CODE_META: [metacode]...
+   // No metadata supported yet.
+   if (Record.size() < 1)
+ return Error("Invalid T