From: Chris Lattner Date: Wed, 19 Mar 2003 20:54:26 +0000 (+0000) Subject: * Bug fixes: X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=52e20b0977c1882fc13cd571239102db9461e9a8;p=llvm * Bug fixes: - Fix problems where the constant table would not get updated when resolving constants causes other constants to change. Changes to the V2 bytecode format - Null values are implicitly encoded instead of explicitly, this makes things more compact! - More compactly represent ConstantPointerRefs - Bytecode files are represented as: Header|GlobalTypes|GlobalVars/Function Protos|Constants|Functions|SymTab instead of Header|GlobalTypes|Constants|GlobalVars/Function Protos|Functions|SymTab which makes a lot of things simpler. Changes to the reader: - Function loading code is much simpler. We now no longer make function PlaceHolderHelper objects to be replaced with real functions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@5748 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Bytecode/Reader/ConstantReader.cpp b/lib/Bytecode/Reader/ConstantReader.cpp index 838c6e83b6e..d2818ef3164 100644 --- a/lib/Bytecode/Reader/ConstantReader.cpp +++ b/lib/Bytecode/Reader/ConstantReader.cpp @@ -316,7 +316,11 @@ bool BytecodeParser::parseConstantValue(const uchar *&Buf, const uchar *EndBuf, case Type::PointerTyID: { const PointerType *PT = cast(Ty); unsigned SubClass; - if (read_vbr(Buf, EndBuf, SubClass)) return true; + if (HasImplicitZeroInitializer) + SubClass = 1; + else + if (read_vbr(Buf, EndBuf, SubClass)) return true; + switch (SubClass) { case 0: // ConstantPointerNull value... V = ConstantPointerNull::get(PT); @@ -333,6 +337,10 @@ bool BytecodeParser::parseConstantValue(const uchar *&Buf, const uchar *EndBuf, if (Val) { if (!(GV = dyn_cast(Val))) return true; BCR_TRACE(5, "Value Found in ValueTable!\n"); + } else if (RevisionNum > 0) { + // Revision #0 could have forward references to globals that were wierd. + // We got rid of this in subsequent revs. + return true; } else { // Nope... find or create a forward ref. for it GlobalRefsType::iterator I = GlobalRefs.find(std::make_pair(PT, Slot)); @@ -341,12 +349,12 @@ bool BytecodeParser::parseConstantValue(const uchar *&Buf, const uchar *EndBuf, GV = cast(I->second); } else { BCR_TRACE(5, "Creating new forward ref to a global variable!\n"); - - // Create a placeholder for the global variable reference... + + // Create a placeholder for the global variable reference... GlobalVariable *GVar = new GlobalVariable(PT->getElementType(), false, true); - // Keep track of the fact that we have a forward ref to recycle it + // Keep track of the fact that we have a forward ref to recycle it GlobalRefs.insert(std::make_pair(std::make_pair(PT, Slot), GVar)); // Must temporarily push this value into the module table... @@ -354,6 +362,7 @@ bool BytecodeParser::parseConstantValue(const uchar *&Buf, const uchar *EndBuf, GV = GVar; } } + V = ConstantPointerRef::get(GV); break; } @@ -375,6 +384,11 @@ bool BytecodeParser::parseConstantValue(const uchar *&Buf, const uchar *EndBuf, return false; } +bool BytecodeParser::ParseGlobalTypes(const uchar *&Buf, const uchar *EndBuf) { + ValueTable T; + return ParseConstantPool(Buf, EndBuf, T, ModuleTypeValues); +} + bool BytecodeParser::ParseConstantPool(const uchar *&Buf, const uchar *EndBuf, ValueTable &Tab, TypeValuesListTy &TypeTab) { @@ -391,20 +405,19 @@ bool BytecodeParser::ParseConstantPool(const uchar *&Buf, const uchar *EndBuf, if (parseTypeConstants(Buf, EndBuf, TypeTab, NumEntries)) return true; } else { for (unsigned i = 0; i < NumEntries; ++i) { - Constant *I; + Constant *C; int Slot; - if (parseConstantValue(Buf, EndBuf, Ty, I)) return true; - assert(I && "parseConstantValue returned NULL!"); - BCR_TRACE(4, "Read Constant: '" << I << "'\n"); - if ((Slot = insertValue(I, Tab)) < 0) return true; + if (parseConstantValue(Buf, EndBuf, Ty, C)) return true; + assert(C && "parseConstantValue returned NULL!"); + BCR_TRACE(4, "Read Constant: '" << *C << "'\n"); + if ((Slot = insertValue(C, Tab)) == -1) return true; // If we are reading a function constant table, make sure that we adjust // the slot number to be the real global constant number. // - if (&Tab != &ModuleValues) - Slot += ModuleValues[Typ].size(); - - ResolveReferencesToValue(I, (unsigned)Slot); + if (&Tab != &ModuleValues && Typ < ModuleValues.size()) + Slot += ModuleValues[Typ]->size(); + ResolveReferencesToValue(C, (unsigned)Slot); } } } diff --git a/lib/Bytecode/Reader/Reader.cpp b/lib/Bytecode/Reader/Reader.cpp index 48e14dd7ced..805b7e7292b 100644 --- a/lib/Bytecode/Reader/Reader.cpp +++ b/lib/Bytecode/Reader/Reader.cpp @@ -55,23 +55,44 @@ const Type *BytecodeParser::getType(unsigned ID) { return cast_or_null(V); } -int BytecodeParser::insertValue(Value *Val, std::vector &ValueTab) { +int BytecodeParser::insertValue(Value *Val, ValueTable &ValueTab) { + assert((!HasImplicitZeroInitializer || !isa(Val) || + Val->getType()->isPrimitiveType() || + !cast(Val)->isNullValue()) && + "Cannot read null values from bytecode!"); unsigned type; if (getTypeSlot(Val->getType(), type)) return -1; assert(type != Type::TypeTyID && "Types should never be insertValue'd!"); - while (ValueTab.size() <= type) { - ValueTab.push_back(ValueList()); - if (HasImplicitZeroInitializer) // add a zero initializer if appropriate - ValueTab.back().push_back( - Constant::getNullValue(getType(ValueTab.size()-1))); + if (ValueTab.size() <= type) { + unsigned OldSize = ValueTab.size(); + ValueTab.resize(type+1); + while (OldSize != type+1) + ValueTab[OldSize++] = new ValueList(); } //cerr << "insertValue Values[" << type << "][" << ValueTab[type].size() // << "] = " << Val << "\n"; - ValueTab[type].push_back(Val); + ValueTab[type]->push_back(Val); - return ValueTab[type].size()-1; + bool HasOffset = HasImplicitZeroInitializer && + !Val->getType()->isPrimitiveType(); + + return ValueTab[type]->size()-1 + HasOffset; +} + + +void BytecodeParser::setValueTo(ValueTable &ValueTab, unsigned Slot, + Value *Val) { + assert(&ValueTab == &ModuleValues && "Can only setValueTo on Module values!"); + unsigned type; + if (getTypeSlot(Val->getType(), type)) + assert(0 && "getTypeSlot failed!"); + + assert((!HasImplicitZeroInitializer || Slot != 0) && + "Cannot change zero init"); + assert(type < ValueTab.size() && Slot <= ValueTab[type]->size()); + ValueTab[type]->setOperand(Slot-HasImplicitZeroInitializer, Val); } Value *BytecodeParser::getValue(const Type *Ty, unsigned oNum, bool Create) { @@ -102,25 +123,25 @@ Value *BytecodeParser::getValue(const Type *Ty, unsigned oNum, bool Create) { return 0; } + if (HasImplicitZeroInitializer && type >= FirstDerivedTyID) { + if (Num == 0) + return Constant::getNullValue(Ty); + --Num; + } + if (type < ModuleValues.size()) { - if (Num < ModuleValues[type].size()) - return ModuleValues[type][Num]; - Num -= ModuleValues[type].size(); + if (Num < ModuleValues[type]->size()) + return ModuleValues[type]->getOperand(Num); + Num -= ModuleValues[type]->size(); } - if (Values.size() > type && Values[type].size() > Num) - return Values[type][Num]; + if (Values.size() > type && Values[type]->size() > Num) + return Values[type]->getOperand(Num); if (!Create) return 0; // Do not create a placeholder? Value *d = 0; switch (Ty->getPrimitiveID()) { - case Type::FunctionTyID: - std::cerr << "Creating function pholder! : " << type << ":" << oNum << " " - << Ty->getName() << "\n"; - d = new FunctionPHolder(Ty, oNum); - if (insertValue(d, LateResolveModuleValues) == -1) return 0; - return d; case Type::LabelTyID: d = new BBPHolder(Ty, oNum); break; @@ -144,8 +165,10 @@ Constant *BytecodeParser::getConstantValue(const Type *Ty, unsigned Slot) { if (Value *V = getValue(Ty, Slot, false)) return dyn_cast(V); // If we already have the value parsed... - GlobalRefsType::iterator I = GlobalRefs.find(std::make_pair(Ty, Slot)); - if (I != GlobalRefs.end()) { + std::pair Key(Ty, Slot); + GlobalRefsType::iterator I = GlobalRefs.lower_bound(Key); + + if (I != GlobalRefs.end() && I->first == Key) { BCR_TRACE(5, "Previous forward ref found!\n"); return cast(I->second); } else { @@ -155,29 +178,28 @@ Constant *BytecodeParser::getConstantValue(const Type *Ty, unsigned Slot) { Constant *C = new ConstPHolder(Ty, Slot); // Keep track of the fact that we have a forward ref to recycle it - GlobalRefs.insert(std::make_pair(std::make_pair(Ty, Slot), C)); + GlobalRefs.insert(I, std::make_pair(Key, C)); return C; } } - bool BytecodeParser::postResolveValues(ValueTable &ValTab) { bool Error = false; - for (unsigned ty = 0; ty < ValTab.size(); ++ty) { - ValueList &DL = ValTab[ty]; - unsigned Size; - while ((Size = DL.size())) { - unsigned IDNumber = getValueIDNumberFromPlaceHolder(DL[Size-1]); + while (!ValTab.empty()) { + ValueList &DL = *ValTab.back(); + ValTab.pop_back(); - Value *D = DL[Size-1]; + while (!DL.empty()) { + Value *D = DL.back(); + unsigned IDNumber = getValueIDNumberFromPlaceHolder(D); DL.pop_back(); Value *NewDef = getValue(D->getType(), IDNumber, false); if (NewDef == 0) { Error = true; // Unresolved thinger std::cerr << "Unresolvable reference found: <" - << D->getType()->getDescription() << ">:" << IDNumber <<"!\n"; + << *D->getType() << ">:" << IDNumber <<"!\n"; } else { // Fixup all of the uses of this placeholder def... D->replaceAllUsesWith(NewDef); @@ -187,6 +209,7 @@ bool BytecodeParser::postResolveValues(ValueTable &ValTab) { delete D; // memory, 'cause otherwise we can't remove all uses! } } + delete &DL; } return Error; @@ -235,15 +258,15 @@ bool BytecodeParser::ParseSymbolTable(const uchar *&Buf, const uchar *EndBuf, if (read(Buf, EndBuf, Name, false)) // Not aligned... return true; - Value *D = getValue(Ty, slot, false); // Find mapping... - if (D == 0) { + Value *V = getValue(Ty, slot, false); // Find mapping... + if (V == 0) { BCR_TRACE(3, "FAILED LOOKUP: Slot #" << slot << "\n"); return true; } - BCR_TRACE(4, "Map: '" << Name << "' to #" << slot << ":" << D; - if (!isa(D)) std::cerr << "\n"); + BCR_TRACE(4, "Map: '" << Name << "' to #" << slot << ":" << *V; + if (!isa(V)) std::cerr << "\n"); - D->setName(Name, ST); + V->setName(Name, ST); } } @@ -259,52 +282,40 @@ void BytecodeParser::ResolveReferencesToValue(Value *NewV, unsigned Slot) { BCR_TRACE(3, "Mutating forward refs!\n"); Value *VPH = I->second; // Get the placeholder... - // Loop over all of the uses of the Value. What they are depends - // on what NewV is. Replacing a use of the old reference takes the - // use off the use list, so loop with !use_empty(), not the use_iterator. - while (!VPH->use_empty()) { - Constant *C = cast(VPH->use_back()); - unsigned numReplaced = C->mutateReferences(VPH, NewV); - assert(numReplaced > 0 && "Supposed user wasn't really a user?"); - - if (GlobalValue* GVal = dyn_cast(NewV)) { - // Remove the placeholder GlobalValue from the module... - GVal->getParent()->getGlobalList().remove(cast(VPH)); - } - } + VPH->replaceAllUsesWith(NewV); + + // If this is a global variable being resolved, remove the placeholder from + // the module... + if (GlobalValue* GVal = dyn_cast(NewV)) + GVal->getParent()->getGlobalList().remove(cast(VPH)); delete VPH; // Delete the old placeholder GlobalRefs.erase(I); // Remove the map entry for it } + bool BytecodeParser::ParseFunction(const uchar *&Buf, const uchar *EndBuf) { // Clear out the local values table... - Values.clear(); if (FunctionSignatureList.empty()) { Error = "Function found, but FunctionSignatureList empty!"; return true; // Unexpected function! } - const PointerType *PMTy = FunctionSignatureList.back().first; // PtrMeth - const FunctionType *MTy = dyn_cast(PMTy->getElementType()); - if (MTy == 0) return true; // Not ptr to function! - unsigned isInternal; if (read_vbr(Buf, EndBuf, isInternal)) return true; - unsigned MethSlot = FunctionSignatureList.back().second; + Function *F = FunctionSignatureList.back().first; + unsigned FunctionSlot = FunctionSignatureList.back().second; FunctionSignatureList.pop_back(); - Function *M = new Function(MTy, isInternal != 0); + F->setInternalLinkage(isInternal != 0); - BCR_TRACE(2, "FUNCTION TYPE: " << MTy << "\n"); - - const FunctionType::ParamTypes &Params = MTy->getParamTypes(); - Function::aiterator AI = M->abegin(); + const FunctionType::ParamTypes &Params =F->getFunctionType()->getParamTypes(); + Function::aiterator AI = F->abegin(); for (FunctionType::ParamTypes::const_iterator It = Params.begin(); It != Params.end(); ++It, ++AI) { if (insertValue(AI, Values) == -1) { Error = "Error reading function arguments!\n"; - delete M; return true; + return true; } } @@ -313,34 +324,31 @@ bool BytecodeParser::ParseFunction(const uchar *&Buf, const uchar *EndBuf) { const unsigned char *OldBuf = Buf; if (readBlock(Buf, EndBuf, Type, Size)) { Error = "Error reading Function level block!"; - delete M; return true; + return true; } switch (Type) { case BytecodeFormat::ConstantPool: BCR_TRACE(2, "BLOCK BytecodeFormat::ConstantPool: {\n"); - if (ParseConstantPool(Buf, Buf+Size, Values, FunctionTypeValues)) { - delete M; return true; - } + if (ParseConstantPool(Buf, Buf+Size, Values, FunctionTypeValues)) + return true; break; case BytecodeFormat::BasicBlock: { BCR_TRACE(2, "BLOCK BytecodeFormat::BasicBlock: {\n"); BasicBlock *BB; if (ParseBasicBlock(Buf, Buf+Size, BB) || - insertValue(BB, Values) == -1) { - delete M; return true; // Parse error... :( - } + insertValue(BB, Values) == -1) + return true; // Parse error... :( - M->getBasicBlockList().push_back(BB); + F->getBasicBlockList().push_back(BB); break; } case BytecodeFormat::SymbolTable: BCR_TRACE(2, "BLOCK BytecodeFormat::SymbolTable: {\n"); - if (ParseSymbolTable(Buf, Buf+Size, &M->getSymbolTable())) { - delete M; return true; - } + if (ParseSymbolTable(Buf, Buf+Size, &F->getSymbolTable())) + return true; break; default: @@ -353,41 +361,21 @@ bool BytecodeParser::ParseFunction(const uchar *&Buf, const uchar *EndBuf) { if (align32(Buf, EndBuf)) { Error = "Error aligning Function level block!"; - delete M; // Malformed bc file, read past end of block. - return true; + return true; // Malformed bc file, read past end of block. } } - if (postResolveValues(LateResolveValues) || - postResolveValues(LateResolveModuleValues)) { + if (postResolveValues(LateResolveValues)) { Error = "Error resolving function values!"; - delete M; return true; // Unresolvable references! + return true; // Unresolvable references! } - Value *FunctionPHolder = getValue(PMTy, MethSlot, false); - assert(FunctionPHolder && "Something is broken, no placeholder found!"); - assert(isa(FunctionPHolder) && "Not a function?"); - - unsigned type; // Type slot - assert(!getTypeSlot(MTy, type) && "How can meth type not exist?"); - getTypeSlot(PMTy, type); - - TheModule->getFunctionList().push_back(M); - - // Replace placeholder with the real function pointer... - ModuleValues[type][MethSlot] = M; + ResolveReferencesToValue(F, FunctionSlot); // Clear out function level types... FunctionTypeValues.clear(); - // If anyone is using the placeholder make them use the real function instead - FunctionPHolder->replaceAllUsesWith(M); - - // We don't need the placeholder anymore! - delete FunctionPHolder; - - ResolveReferencesToValue(M, MethSlot); - + freeTable(Values); return false; } @@ -409,40 +397,25 @@ bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End){ return true; } - const PointerType *PTy = cast(Ty); - const Type *ElTy = PTy->getElementType(); - - Constant *Initializer = 0; - if (VarType & 2) { // Does it have an initalizer? - // Do not improvise... values must have been stored in the constant pool, - // which should have been read before now. - // - unsigned InitSlot; - if (read_vbr(Buf, End, InitSlot)) return true; - - Value *V = getValue(ElTy, InitSlot, false); - if (V == 0) return true; - Initializer = cast(V); - } + const Type *ElTy = cast(Ty)->getElementType(); // Create the global variable... GlobalVariable *GV = new GlobalVariable(ElTy, VarType & 1, VarType & 4, - Initializer); + 0, "", TheModule); int DestSlot = insertValue(GV, ModuleValues); if (DestSlot == -1) return true; - - TheModule->getGlobalList().push_back(GV); - + BCR_TRACE(2, "Global Variable of type: " << *Ty << "\n"); ResolveReferencesToValue(GV, (unsigned)DestSlot); - BCR_TRACE(2, "Global Variable of type: " << PTy->getDescription() - << " into slot #" << DestSlot << "\n"); - + if (VarType & 2) { // Does it have an initalizer? + unsigned InitSlot; + if (read_vbr(Buf, End, InitSlot)) return true; + GlobalInits.push_back(std::make_pair(GV, InitSlot)); + } if (read_vbr(Buf, End, VarType)) return true; } - // Read the function signatures for all of the functions that are coming, and - // create fillers in the Value tables. + // Read the function objects for all of the functions that are coming unsigned FnSignature; if (read_vbr(Buf, End, FnSignature)) return true; while (FnSignature != Type::VoidTyID) { // List is terminated by Void @@ -462,20 +435,16 @@ bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End){ // this placeholder is replaced. // Insert the placeholder... - Value *Val = new FunctionPHolder(Ty, 0); - if (insertValue(Val, ModuleValues) == -1) return true; - - // Figure out which entry of its typeslot it went into... - unsigned TypeSlot; - if (getTypeSlot(Val->getType(), TypeSlot)) return true; + Function *Func = new Function(cast(Ty), false, "", TheModule); + int DestSlot = insertValue(Func, ModuleValues); + if (DestSlot == -1) return true; + ResolveReferencesToValue(Func, (unsigned)DestSlot); - unsigned SlotNo = ModuleValues[TypeSlot].size()-1; - - // Keep track of this information in a linked list that is emptied as - // functions are loaded... + // Keep track of this information in a list that is emptied as functions are + // loaded... // - FunctionSignatureList.push_back( - std::make_pair(cast(Val->getType()), SlotNo)); + FunctionSignatureList.push_back(std::make_pair(Func, DestSlot)); + if (read_vbr(Buf, End, FnSignature)) return true; BCR_TRACE(2, "Function of type: " << Ty << "\n"); } @@ -505,12 +474,17 @@ bool BytecodeParser::ParseVersionInfo(const uchar *&Buf, const uchar *EndBuf) { switch (RevisionNum) { case 0: // Initial revision + // Version #0 didn't have any of the flags stored correctly, and in fact as + // only valid with a 14 in the flags values. Also, it does not support + // encoding zero initializers for arrays compactly. + // if (Version != 14) return true; // Unknown revision 0 flags? FirstDerivedTyID = 14; HasImplicitZeroInitializer = false; isBigEndian = hasLongPointers = true; break; case 1: + // Version #1 has two bit fields: isBigEndian and hasLongPointers FirstDerivedTyID = 14; break; default: @@ -544,20 +518,26 @@ bool BytecodeParser::ParseModule(const uchar *Buf, const uchar *EndBuf) { const unsigned char *OldBuf = Buf; if (readBlock(Buf, EndBuf, Type, Size)) return true; switch (Type) { - case BytecodeFormat::ConstantPool: - BCR_TRACE(1, "BLOCK BytecodeFormat::ConstantPool: {\n"); - if (ParseConstantPool(Buf, Buf+Size, ModuleValues, ModuleTypeValues)) - return true; + case BytecodeFormat::GlobalTypePlane: + BCR_TRACE(1, "BLOCK BytecodeFormat::GlobalTypePlane: {\n"); + if (ParseGlobalTypes(Buf, Buf+Size)) return true; break; case BytecodeFormat::ModuleGlobalInfo: BCR_TRACE(1, "BLOCK BytecodeFormat::ModuleGlobalInfo: {\n"); - if (ParseModuleGlobalInfo(Buf, Buf+Size)) return true; + if (ParseModuleGlobalInfo(Buf, Buf+Size)) return true; + break; + + case BytecodeFormat::ConstantPool: + BCR_TRACE(1, "BLOCK BytecodeFormat::ConstantPool: {\n"); + if (ParseConstantPool(Buf, Buf+Size, ModuleValues, ModuleTypeValues)) + return true; break; case BytecodeFormat::Function: { BCR_TRACE(1, "BLOCK BytecodeFormat::Function: {\n"); - if (ParseFunction(Buf, Buf+Size)) return true; // Error parsing function + if (ParseFunction(Buf, Buf+Size)) + return true; // Error parsing function break; } @@ -577,6 +557,21 @@ bool BytecodeParser::ParseModule(const uchar *Buf, const uchar *EndBuf) { if (align32(Buf, EndBuf)) return true; } + // After the module constant pool has been read, we can safely initialize + // global variables... + while (!GlobalInits.empty()) { + GlobalVariable *GV = GlobalInits.back().first; + unsigned Slot = GlobalInits.back().second; + GlobalInits.pop_back(); + + // Look up the initializer value... + if (Value *V = getValue(GV->getType()->getElementType(), Slot, false)) { + if (GV->hasInitializer()) return true; + GV->setInitializer(cast(V)); + } else + return true; + } + if (!FunctionSignatureList.empty()) { // Expected more functions! Error = "Function expected, but bytecode stream at end!"; return true; @@ -592,7 +587,6 @@ static inline Module *Error(std::string *ErrorStr, const char *Message) { } Module *BytecodeParser::ParseBytecode(const uchar *Buf, const uchar *EndBuf) { - LateResolveValues.clear(); unsigned Sig; // Read and check signature... if (read(Buf, EndBuf, Sig) || diff --git a/lib/Bytecode/Reader/ReaderInternals.h b/lib/Bytecode/Reader/ReaderInternals.h index 09a21d71e4b..3e571f2ee8c 100644 --- a/lib/Bytecode/Reader/ReaderInternals.h +++ b/lib/Bytecode/Reader/ReaderInternals.h @@ -18,7 +18,8 @@ #define TRACE_LEVEL 0 #if TRACE_LEVEL // ByteCodeReading_TRACEer -#define BCR_TRACE(n, X) if (n < TRACE_LEVEL) std::cerr << std::string(n*2, ' ') << X +#define BCR_TRACE(n, X) \ + if (n < TRACE_LEVEL) std::cerr << std::string(n*2, ' ') << X #else #define BCR_TRACE(n, X) #endif @@ -45,6 +46,11 @@ public: // Define this in case we don't see a ModuleGlobalInfo block. FirstDerivedTyID = Type::FirstDerivedTyID; } + ~BytecodeParser() { + freeTable(Values); + freeTable(LateResolveValues); + freeTable(ModuleValues); + } Module *ParseBytecode(const uchar *Buf, const uchar *EndBuf); @@ -55,6 +61,23 @@ public: } private: // All of this data is transient across calls to ParseBytecode + struct ValueList : public User { + ValueList() : User(Type::TypeTy, Value::TypeVal) { + } + ~ValueList() {} + + // vector compatibility methods + unsigned size() const { return getNumOperands(); } + void push_back(Value *V) { Operands.push_back(Use(V, this)); } + Value *back() const { return Operands.back(); } + void pop_back() { Operands.pop_back(); } + bool empty() const { return Operands.empty(); } + + virtual void print(std::ostream& OS) const { + OS << "Bytecode Reader UseHandle!"; + } + }; + Module *TheModule; // Current Module being read into... // Information about the module, extracted from the bytecode revision number. @@ -63,18 +86,16 @@ private: // All of this data is transient across calls to ParseBytecode bool HasImplicitZeroInitializer; // Is entry 0 of every slot implicity zeros? bool isBigEndian, hasLongPointers;// Information about the target compiled for - typedef std::vector ValueList; - typedef std::vector ValueTable; + typedef std::vector ValueTable; ValueTable Values, LateResolveValues; - ValueTable ModuleValues, LateResolveModuleValues; + ValueTable ModuleValues; // GlobalRefs - This maintains a mapping between 's and forward // references to global values or constants. Such values may be referenced // before they are defined, and if so, the temporary object that they // represent is held here. // - typedef std::map, - Value*> GlobalRefsType; + typedef std::map, Value*> GlobalRefsType; GlobalRefsType GlobalRefs; // TypesLoaded - This vector mirrors the Values[TypeTyID] plane. It is used @@ -84,14 +105,27 @@ private: // All of this data is transient across calls to ParseBytecode TypeValuesListTy ModuleTypeValues; TypeValuesListTy FunctionTypeValues; - // When the ModuleGlobalInfo section is read, we load the type of each - // function and the 'ModuleValues' slot that it lands in. We then load a - // placeholder into its slot to reserve it. When the function is loaded, this - // placeholder is replaced. + // When the ModuleGlobalInfo section is read, we create a function object for + // each function in the module. When the function is loaded, this function is + // filled in. + // + std::vector > FunctionSignatureList; + + // Constant values are read in after global variables. Because of this, we + // must defer setting the initializers on global variables until after module + // level constants have been read. In the mean time, this list keeps track of + // what we must do. // - std::vector > FunctionSignatureList; + std::vector > GlobalInits; private: + void freeTable(ValueTable &Tab) { + while (!Tab.empty()) { + delete Tab.back(); + Tab.pop_back(); + } + } + bool ParseModule (const uchar * Buf, const uchar *End); bool ParseVersionInfo (const uchar *&Buf, const uchar *End); bool ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End); @@ -102,6 +136,7 @@ private: BasicBlock *BB /*HACK*/); bool ParseRawInst (const uchar *&Buf, const uchar *End, RawInst &); + bool ParseGlobalTypes(const uchar *&Buf, const uchar *EndBuf); bool ParseConstantPool(const uchar *&Buf, const uchar *EndBuf, ValueTable &Tab, TypeValuesListTy &TypeTab); bool parseConstantValue(const uchar *&Buf, const uchar *End, @@ -114,7 +149,8 @@ private: const Type *getType(unsigned ID); Constant *getConstantValue(const Type *Ty, unsigned num); - int insertValue(Value *D, std::vector &D); // -1 = Failure + int insertValue(Value *V, ValueTable &Table); // -1 = Failure + void setValueTo(ValueTable &D, unsigned Slot, Value *V); bool postResolveValues(ValueTable &ValTab); bool getTypeSlot(const Type *Ty, unsigned &Slot); @@ -152,12 +188,6 @@ struct BBPlaceHolderHelper : public BasicBlock { } }; -struct FunctionPlaceHolderHelper : public Function { - FunctionPlaceHolderHelper(const Type *Ty) - : Function(cast(Ty), true) { - } -}; - struct ConstantPlaceHolderHelper : public Constant { ConstantPlaceHolderHelper(const Type *Ty) : Constant(Ty) {} @@ -166,7 +196,6 @@ struct ConstantPlaceHolderHelper : public Constant { typedef PlaceholderDef ValPHolder; typedef PlaceholderDef BBPHolder; -typedef PlaceholderDef FunctionPHolder; typedef PlaceholderDef ConstPHolder; @@ -177,7 +206,6 @@ static inline unsigned getValueIDNumberFromPlaceHolder(Value *Val) { // else discriminate by type switch (Val->getType()->getPrimitiveID()) { case Type::LabelTyID: return ((BBPHolder*)Val)->getID(); - case Type::FunctionTyID: return ((FunctionPHolder*)Val)->getID(); default: return ((ValPHolder*)Val)->getID(); } }