[llvm-commits] CVS: llvm/lib/Bitcode/Reader/BitcodeReader.cpp BitcodeReader.h
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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