X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FBitcode%2FReader%2FBitcodeReader.h;h=34e96b07b42bc1b8b9abd150b1db487e9d46a7ce;hp=f8fc079c73d9bfb58f640e3884e51d73518b4829;hb=a1514e24cc24b050f53a12650e047799358833a1;hpb=34711747a1d2c8713e69333bacef1c880810e371 diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h index f8fc079c73d..34e96b07b42 100644 --- a/lib/Bitcode/Reader/BitcodeReader.h +++ b/lib/Bitcode/Reader/BitcodeReader.h @@ -14,27 +14,27 @@ #ifndef BITCODE_READER_H #define BITCODE_READER_H -#include "llvm/GVMaterializer.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/Attributes.h" -#include "llvm/Type.h" -#include "llvm/OperandTraits.h" #include "llvm/Bitcode/BitstreamReader.h" #include "llvm/Bitcode/LLVMBitCodes.h" +#include "llvm/GVMaterializer.h" +#include "llvm/OperandTraits.h" #include "llvm/Support/ValueHandle.h" -#include "llvm/ADT/DenseMap.h" +#include "llvm/Type.h" #include namespace llvm { class MemoryBuffer; class LLVMContext; - + //===----------------------------------------------------------------------===// // BitcodeReaderValueList Class //===----------------------------------------------------------------------===// class BitcodeReaderValueList { std::vector ValuePtrs; - + /// ResolveConstants - As we resolve forward-referenced constants, we add /// information about them to this vector. This allows us to resolve them in /// bulk instead of resolving each reference at a time. See the code in @@ -44,9 +44,9 @@ class BitcodeReaderValueList { /// number that holds the resolved value. typedef std::vector > ResolveConstantsTy; ResolveConstantsTy ResolveConstants; - LLVMContext& Context; + LLVMContext &Context; public: - BitcodeReaderValueList(LLVMContext& C) : Context(C) {} + BitcodeReaderValueList(LLVMContext &C) : Context(C) {} ~BitcodeReaderValueList() { assert(ResolveConstants.empty() && "Constants not resolved?"); } @@ -57,17 +57,17 @@ public: void push_back(Value *V) { ValuePtrs.push_back(V); } - + void clear() { assert(ResolveConstants.empty() && "Constants not resolved?"); ValuePtrs.clear(); } - + Value *operator[](unsigned i) const { assert(i < ValuePtrs.size()); return ValuePtrs[i]; } - + Value *back() const { return ValuePtrs.back(); } void pop_back() { ValuePtrs.pop_back(); } bool empty() const { return ValuePtrs.empty(); } @@ -75,12 +75,12 @@ public: assert(N <= size() && "Invalid shrinkTo request!"); ValuePtrs.resize(N); } - - Constant *getConstantFwdRef(unsigned Idx, const Type *Ty); - Value *getValueFwdRef(unsigned Idx, const Type *Ty); - + + Constant *getConstantFwdRef(unsigned Idx, Type *Ty); + Value *getValueFwdRef(unsigned Idx, Type *Ty); + void AssignValue(Value *V, unsigned Idx); - + /// ResolveConstantForwardRefs - Once all constants are read, this method bulk /// resolves any forward references. void ResolveConstantForwardRefs(); @@ -93,7 +93,7 @@ public: class BitcodeReaderMDValueList { std::vector MDValuePtrs; - + LLVMContext &Context; public: BitcodeReaderMDValueList(LLVMContext& C) : Context(C) {} @@ -106,12 +106,12 @@ public: Value *back() const { return MDValuePtrs.back(); } void pop_back() { MDValuePtrs.pop_back(); } bool empty() const { return MDValuePtrs.empty(); } - + Value *operator[](unsigned i) const { assert(i < MDValuePtrs.size()); return MDValuePtrs[i]; } - + void shrinkTo(unsigned N) { assert(N <= size() && "Invalid shrinkTo request!"); MDValuePtrs.resize(N); @@ -126,77 +126,93 @@ class BitcodeReader : public GVMaterializer { Module *TheModule; MemoryBuffer *Buffer; bool BufferOwned; - BitstreamReader StreamFile; + OwningPtr StreamFile; BitstreamCursor Stream; - + DataStreamer *LazyStreamer; + uint64_t NextUnreadBit; + bool SeenValueSymbolTable; + const char *ErrorString; - - std::vector TypeList; + + std::vector TypeList; BitcodeReaderValueList ValueList; BitcodeReaderMDValueList MDValueList; SmallVector InstructionList; + SmallVector, 64> UseListRecords; std::vector > GlobalInits; std::vector > AliasInits; - + /// MAttributes - The set of 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 MAttributes; - + /// FunctionBBs - While parsing a function body, this is a list of the basic /// blocks for the function. std::vector FunctionBBs; - + // When reading the module header, this list is populated with functions that // have bodies later in the file. std::vector FunctionsWithBodies; - // When intrinsic functions are encountered which require upgrading they are + // When intrinsic functions are encountered which require upgrading they are // stored here with their replacement function. typedef std::vector > UpgradedIntrinsicMap; UpgradedIntrinsicMap UpgradedIntrinsics; // Map the bitcode's custom MDKind ID to the Module's MDKind ID. DenseMap MDKindMap; - - // After the module header has been read, the FunctionsWithBodies list is - // reversed. This keeps track of whether we've done this yet. - bool HasReversedFunctionsWithBodies; - + + // Several operations happen after the module header has been read, but + // before function bodies are processed. This keeps track of whether + // we've done this yet. + bool SeenFirstFunctionBody; + /// DeferredFunctionInfo - When function bodies are initially scanned, this /// map contains info about where to find deferred function body in the /// stream. DenseMap DeferredFunctionInfo; - + /// BlockAddrFwdRefs - These are blockaddr references to basic blocks. These /// are resolved lazily when functions are loaded. typedef std::pair BlockAddrRefTy; DenseMap > BlockAddrFwdRefs; - /// LLVM2_7MetadataDetected - True if metadata produced by LLVM 2.7 or - /// earlier was detected, in which case we behave slightly differently, - /// for compatibility. - /// FIXME: Remove in LLVM 3.0. - bool LLVM2_7MetadataDetected; - + /// UseRelativeIDs - Indicates that we are using a new encoding for + /// instruction operands where most operands in the current + /// FUNCTION_BLOCK are encoded relative to the instruction number, + /// for a more compact encoding. Some instruction operands are not + /// relative to the instruction ID: basic block numbers, and types. + /// Once the old style function blocks have been phased out, we would + /// not need this flag. + bool UseRelativeIDs; + public: explicit BitcodeReader(MemoryBuffer *buffer, LLVMContext &C) : Context(C), TheModule(0), Buffer(buffer), BufferOwned(false), + LazyStreamer(0), NextUnreadBit(0), SeenValueSymbolTable(false), ErrorString(0), ValueList(C), MDValueList(C), - LLVM2_7MetadataDetected(false) { - HasReversedFunctionsWithBodies = false; + SeenFirstFunctionBody(false), UseRelativeIDs(false) { + } + explicit BitcodeReader(DataStreamer *streamer, LLVMContext &C) + : Context(C), TheModule(0), Buffer(0), BufferOwned(false), + LazyStreamer(streamer), NextUnreadBit(0), SeenValueSymbolTable(false), + ErrorString(0), ValueList(C), MDValueList(C), + SeenFirstFunctionBody(false), UseRelativeIDs(false) { } ~BitcodeReader() { FreeState(); } - + + void materializeForwardReferencedFunctions(); + void FreeState(); - + /// setBufferOwned - If this is true, the reader will destroy the MemoryBuffer /// when the reader is destroyed. void setBufferOwned(bool Owned) { BufferOwned = Owned; } - + virtual bool isMaterializable(const GlobalValue *GV) const; virtual bool isDematerializable(const GlobalValue *GV) const; virtual bool Materialize(GlobalValue *GV, std::string *ErrInfo = 0); @@ -208,7 +224,7 @@ public: return true; } const char *getErrorString() const { return ErrorString; } - + /// @brief Main interface to parsing a bitcode buffer. /// @returns true if an error occurred. bool ParseBitcodeInto(Module *M); @@ -216,13 +232,15 @@ public: /// @brief Cheap mechanism to just extract module triple /// @returns true if an error occurred. bool ParseTriple(std::string &Triple); + + static uint64_t decodeSignRotatedValue(uint64_t V); + private: - const Type *getTypeByID(unsigned ID, bool isTypeTable = false); - Value *getFnValueByID(unsigned ID, const Type *Ty) { - if (Ty == Type::getMetadataTy(Context)) + Type *getTypeByID(unsigned ID); + Value *getFnValueByID(unsigned ID, Type *Ty) { + if (Ty && Ty->isMetadataTy()) return MDValueList.getValueFwdRef(ID); - else - return ValueList.getValueFwdRef(ID, Ty); + return ValueList.getValueFwdRef(ID, Ty); } BasicBlock *getBasicBlock(unsigned ID) const { if (ID >= FunctionBBs.size()) return 0; // Invalid ID @@ -233,7 +251,7 @@ private: return MAttributes[i-1]; return AttrListPtr(); } - + /// getValueTypePair - Read a value/type pair out of the specified record from /// slot 'Slot'. Increment Slot past the number of slots used in the record. /// Return true on failure. @@ -241,6 +259,9 @@ private: unsigned InstNum, Value *&ResVal) { if (Slot == Record.size()) return true; unsigned ValNo = (unsigned)Record[Slot++]; + // Adjust the ValNo, if it was encoded relative to the InstNum. + if (UseRelativeIDs) + ValNo = InstNum - ValNo; if (ValNo < InstNum) { // If this is not a forward reference, just return the value we already // have. @@ -249,34 +270,76 @@ private: } else if (Slot == Record.size()) { return true; } - + unsigned TypeNo = (unsigned)Record[Slot++]; ResVal = getFnValueByID(ValNo, getTypeByID(TypeNo)); return ResVal == 0; } - bool getValue(SmallVector &Record, unsigned &Slot, - const Type *Ty, Value *&ResVal) { - if (Slot == Record.size()) return true; - unsigned ValNo = (unsigned)Record[Slot++]; - ResVal = getFnValueByID(ValNo, Ty); + + /// popValue - Read a value out of the specified record from slot 'Slot'. + /// Increment Slot past the number of slots used by the value in the record. + /// Return true if there is an error. + bool popValue(SmallVector &Record, unsigned &Slot, + unsigned InstNum, Type *Ty, Value *&ResVal) { + if (getValue(Record, Slot, InstNum, Ty, ResVal)) + return true; + // All values currently take a single record slot. + ++Slot; + return false; + } + + /// getValue -- Like popValue, but does not increment the Slot number. + bool getValue(SmallVector &Record, unsigned Slot, + unsigned InstNum, Type *Ty, Value *&ResVal) { + ResVal = getValue(Record, Slot, InstNum, Ty); return ResVal == 0; } - - bool ParseModule(); + /// getValue -- Version of getValue that returns ResVal directly, + /// or 0 if there is an error. + Value *getValue(SmallVector &Record, unsigned Slot, + unsigned InstNum, Type *Ty) { + if (Slot == Record.size()) return 0; + unsigned ValNo = (unsigned)Record[Slot]; + // Adjust the ValNo, if it was encoded relative to the InstNum. + if (UseRelativeIDs) + ValNo = InstNum - ValNo; + return getFnValueByID(ValNo, Ty); + } + + /// getValueSigned -- Like getValue, but decodes signed VBRs. + Value *getValueSigned(SmallVector &Record, unsigned Slot, + unsigned InstNum, Type *Ty) { + if (Slot == Record.size()) return 0; + unsigned ValNo = (unsigned)decodeSignRotatedValue(Record[Slot]); + // Adjust the ValNo, if it was encoded relative to the InstNum. + if (UseRelativeIDs) + ValNo = InstNum - ValNo; + return getFnValueByID(ValNo, Ty); + } + + bool ParseModule(bool Resume); bool ParseAttributeBlock(); bool ParseTypeTable(); - bool ParseTypeSymbolTable(); + bool ParseTypeTableBody(); + bool ParseValueSymbolTable(); bool ParseConstants(); bool RememberAndSkipFunctionBody(); bool ParseFunctionBody(Function *F); + bool GlobalCleanup(); bool ResolveGlobalAndAliasInits(); bool ParseMetadata(); bool ParseMetadataAttachment(); bool ParseModuleTriple(std::string &Triple); + bool ParseUseLists(); + bool InitStream(); + bool InitStreamFromBuffer(); + bool InitLazyStream(); + bool FindFunctionInStream(Function *F, + DenseMap::iterator DeferredFunctionInfoIterator); }; - + } // End llvm namespace #endif