X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FBitcode%2FReader%2FBitcodeReader.cpp;h=5ac9bbd58f631b39221d60bda2c5497061a074a3;hb=5db5cae26feaef6b59eff4072df23711f4ddb663;hp=a9adaf4febe50cdb057fe8b812bf2c1445a87d3f;hpb=8ec0aee3b4a0b038732f30226999145d666186f2;p=oota-llvm.git diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index a9adaf4febe..5ac9bbd58f6 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -8,32 +8,380 @@ //===----------------------------------------------------------------------===// #include "llvm/Bitcode/ReaderWriter.h" -#include "BitcodeReader.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Bitcode/BitstreamReader.h" #include "llvm/Bitcode/LLVMBitCodes.h" #include "llvm/IR/AutoUpgrade.h" #include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfo.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/DiagnosticPrinter.h" +#include "llvm/IR/GVMaterializer.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/OperandTraits.h" #include "llvm/IR/Operator.h" +#include "llvm/IR/ValueHandle.h" #include "llvm/Support/DataStream.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" - +#include using namespace llvm; +namespace { enum { SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex }; +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 + /// ResolveConstantForwardRefs for more information about this. + /// + /// The key of this vector is the placeholder constant, the value is the slot + /// number that holds the resolved value. + typedef std::vector > ResolveConstantsTy; + ResolveConstantsTy ResolveConstants; + LLVMContext &Context; +public: + BitcodeReaderValueList(LLVMContext &C) : Context(C) {} + ~BitcodeReaderValueList() { + assert(ResolveConstants.empty() && "Constants not resolved?"); + } + + // vector compatibility methods + unsigned size() const { return ValuePtrs.size(); } + void resize(unsigned N) { ValuePtrs.resize(N); } + 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(); } + void shrinkTo(unsigned N) { + assert(N <= size() && "Invalid shrinkTo request!"); + ValuePtrs.resize(N); + } + + 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(); +}; + +class BitcodeReaderMDValueList { + unsigned NumFwdRefs; + bool AnyFwdRefs; + unsigned MinFwdRef; + unsigned MaxFwdRef; + std::vector MDValuePtrs; + + LLVMContext &Context; +public: + BitcodeReaderMDValueList(LLVMContext &C) + : NumFwdRefs(0), AnyFwdRefs(false), Context(C) {} + + // vector compatibility methods + unsigned size() const { return MDValuePtrs.size(); } + void resize(unsigned N) { MDValuePtrs.resize(N); } + void push_back(Metadata *MD) { MDValuePtrs.emplace_back(MD); } + void clear() { MDValuePtrs.clear(); } + Metadata *back() const { return MDValuePtrs.back(); } + void pop_back() { MDValuePtrs.pop_back(); } + bool empty() const { return MDValuePtrs.empty(); } + + Metadata *operator[](unsigned i) const { + assert(i < MDValuePtrs.size()); + return MDValuePtrs[i]; + } + + void shrinkTo(unsigned N) { + assert(N <= size() && "Invalid shrinkTo request!"); + MDValuePtrs.resize(N); + } + + Metadata *getValueFwdRef(unsigned Idx); + void AssignValue(Metadata *MD, unsigned Idx); + void tryToResolveCycles(); +}; + +class BitcodeReader : public GVMaterializer { + LLVMContext &Context; + DiagnosticHandlerFunction DiagnosticHandler; + Module *TheModule; + std::unique_ptr Buffer; + std::unique_ptr StreamFile; + BitstreamCursor Stream; + DataStreamer *LazyStreamer; + uint64_t NextUnreadBit; + bool SeenValueSymbolTable; + + std::vector TypeList; + BitcodeReaderValueList ValueList; + BitcodeReaderMDValueList MDValueList; + std::vector ComdatList; + SmallVector InstructionList; + + std::vector > GlobalInits; + std::vector > AliasInits; + std::vector > FunctionPrefixes; + std::vector > FunctionPrologues; + + SmallVector InstsWithTBAATag; + + /// 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; + + /// \brief The set of attribute groups. + std::map MAttributeGroups; + + /// 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 + // 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; + + // 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; + + /// When Metadata block is initially scanned when parsing the module, we may + /// choose to defer parsing of the metadata. This vector contains info about + /// which Metadata blocks are deferred. + std::vector DeferredMetadataInfo; + + /// These are basic blocks forward-referenced by block addresses. They are + /// inserted lazily into functions when they're loaded. The basic block ID is + /// its index into the vector. + DenseMap> BasicBlockFwdRefs; + std::deque BasicBlockFwdRefQueue; + + /// 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; + + /// True if all functions will be materialized, negating the need to process + /// (e.g.) blockaddress forward references. + bool WillMaterializeAllForwardRefs; + + /// Functions that have block addresses taken. This is usually empty. + SmallPtrSet BlockAddressesTaken; + + /// True if any Metadata block has been materialized. + bool IsMetadataMaterialized; + + bool StripDebugInfo = false; + +public: + std::error_code Error(BitcodeError E, const Twine &Message); + std::error_code Error(BitcodeError E); + std::error_code Error(const Twine &Message); + + explicit BitcodeReader(MemoryBuffer *buffer, LLVMContext &C, + DiagnosticHandlerFunction DiagnosticHandler); + explicit BitcodeReader(DataStreamer *streamer, LLVMContext &C, + DiagnosticHandlerFunction DiagnosticHandler); + ~BitcodeReader() override { FreeState(); } + + std::error_code materializeForwardReferencedFunctions(); + + void FreeState(); + + void releaseBuffer(); + + bool isDematerializable(const GlobalValue *GV) const override; + std::error_code materialize(GlobalValue *GV) override; + std::error_code MaterializeModule(Module *M) override; + std::vector getIdentifiedStructTypes() const override; + void Dematerialize(GlobalValue *GV) override; + + /// @brief Main interface to parsing a bitcode buffer. + /// @returns true if an error occurred. + std::error_code ParseBitcodeInto(Module *M, + bool ShouldLazyLoadMetadata = false); + + /// @brief Cheap mechanism to just extract module triple + /// @returns true if an error occurred. + ErrorOr parseTriple(); + + static uint64_t decodeSignRotatedValue(uint64_t V); + + /// Materialize any deferred Metadata block. + std::error_code materializeMetadata() override; + + void setStripDebugInfo() override; + +private: + std::vector IdentifiedStructTypes; + StructType *createIdentifiedStructType(LLVMContext &Context, StringRef Name); + StructType *createIdentifiedStructType(LLVMContext &Context); + + Type *getTypeByID(unsigned ID); + Value *getFnValueByID(unsigned ID, Type *Ty) { + if (Ty && Ty->isMetadataTy()) + return MetadataAsValue::get(Ty->getContext(), getFnMetadataByID(ID)); + return ValueList.getValueFwdRef(ID, Ty); + } + Metadata *getFnMetadataByID(unsigned ID) { + return MDValueList.getValueFwdRef(ID); + } + BasicBlock *getBasicBlock(unsigned ID) const { + if (ID >= FunctionBBs.size()) return nullptr; // Invalid ID + return FunctionBBs[ID]; + } + AttributeSet getAttributes(unsigned i) const { + if (i-1 < MAttributes.size()) + return MAttributes[i-1]; + return AttributeSet(); + } + + /// 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. + bool getValueTypePair(SmallVectorImpl &Record, unsigned &Slot, + 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. + ResVal = getFnValueByID(ValNo, nullptr); + return ResVal == nullptr; + } + if (Slot == Record.size()) + return true; + + unsigned TypeNo = (unsigned)Record[Slot++]; + ResVal = getFnValueByID(ValNo, getTypeByID(TypeNo)); + return ResVal == nullptr; + } + + /// 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(SmallVectorImpl &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(SmallVectorImpl &Record, unsigned Slot, + unsigned InstNum, Type *Ty, Value *&ResVal) { + ResVal = getValue(Record, Slot, InstNum, Ty); + return ResVal == nullptr; + } + + /// getValue -- Version of getValue that returns ResVal directly, + /// or 0 if there is an error. + Value *getValue(SmallVectorImpl &Record, unsigned Slot, + unsigned InstNum, Type *Ty) { + if (Slot == Record.size()) return nullptr; + 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(SmallVectorImpl &Record, unsigned Slot, + unsigned InstNum, Type *Ty) { + if (Slot == Record.size()) return nullptr; + 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); + } + + /// Converts alignment exponent (i.e. power of two (or zero)) to the + /// corresponding alignment to use. If alignment is too large, returns + /// a corresponding error code. + std::error_code parseAlignmentValue(uint64_t Exponent, unsigned &Alignment); + std::error_code ParseAttrKind(uint64_t Code, Attribute::AttrKind *Kind); + std::error_code ParseModule(bool Resume, bool ShouldLazyLoadMetadata = false); + std::error_code ParseAttributeBlock(); + std::error_code ParseAttributeGroupBlock(); + std::error_code ParseTypeTable(); + std::error_code ParseTypeTableBody(); + + std::error_code ParseValueSymbolTable(); + std::error_code ParseConstants(); + std::error_code RememberAndSkipFunctionBody(); + /// Save the positions of the Metadata blocks and skip parsing the blocks. + std::error_code rememberAndSkipMetadata(); + std::error_code ParseFunctionBody(Function *F); + std::error_code GlobalCleanup(); + std::error_code ResolveGlobalAndAliasInits(); + std::error_code ParseMetadata(); + std::error_code ParseMetadataAttachment(); + ErrorOr parseModuleTriple(); + std::error_code ParseUseLists(); + std::error_code InitStream(); + std::error_code InitStreamFromBuffer(); + std::error_code InitLazyStream(); + std::error_code FindFunctionInStream( + Function *F, + DenseMap::iterator DeferredFunctionInfoIterator); +}; +} // namespace + BitcodeDiagnosticInfo::BitcodeDiagnosticInfo(std::error_code EC, DiagnosticSeverity Severity, const Twine &Msg) @@ -79,7 +427,7 @@ BitcodeReader::BitcodeReader(MemoryBuffer *buffer, LLVMContext &C, TheModule(nullptr), Buffer(buffer), LazyStreamer(nullptr), NextUnreadBit(0), SeenValueSymbolTable(false), ValueList(C), MDValueList(C), SeenFirstFunctionBody(false), UseRelativeIDs(false), - WillMaterializeAllForwardRefs(false) {} + WillMaterializeAllForwardRefs(false), IsMetadataMaterialized(false) {} BitcodeReader::BitcodeReader(DataStreamer *streamer, LLVMContext &C, DiagnosticHandlerFunction DiagnosticHandler) @@ -87,7 +435,7 @@ BitcodeReader::BitcodeReader(DataStreamer *streamer, LLVMContext &C, TheModule(nullptr), Buffer(nullptr), LazyStreamer(streamer), NextUnreadBit(0), SeenValueSymbolTable(false), ValueList(C), MDValueList(C), SeenFirstFunctionBody(false), UseRelativeIDs(false), - WillMaterializeAllForwardRefs(false) {} + WillMaterializeAllForwardRefs(false), IsMetadataMaterialized(false) {} std::error_code BitcodeReader::materializeForwardReferencedFunctions() { if (WillMaterializeAllForwardRefs) @@ -133,6 +481,7 @@ void BitcodeReader::FreeState() { std::vector().swap(FunctionBBs); std::vector().swap(FunctionsWithBodies); DeferredFunctionInfo.clear(); + DeferredMetadataInfo.clear(); MDKindMap.clear(); assert(BasicBlockFwdRefs.empty() && "Unresolved blockaddress fwd references"); @@ -348,7 +697,7 @@ 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 { - void operator=(const ConstantPlaceHolder &) LLVM_DELETED_FUNCTION; + void operator=(const ConstantPlaceHolder &) = delete; public: // allocate space for exactly one operand void *operator new(size_t s) { @@ -541,9 +890,8 @@ void BitcodeReaderMDValueList::AssignValue(Metadata *MD, unsigned Idx) { } // If there was a forward reference to this value, replace it. - MDTuple *PrevMD = cast(OldMD.get()); + TempMDTuple PrevMD(cast(OldMD.get())); PrevMD->replaceAllUsesWith(MD); - MDNode::deleteTemporary(PrevMD); --NumFwdRefs; } @@ -554,10 +902,18 @@ Metadata *BitcodeReaderMDValueList::getValueFwdRef(unsigned Idx) { if (Metadata *MD = MDValuePtrs[Idx]) return MD; - // Create and return a placeholder, which will later be RAUW'd. - AnyFwdRefs = true; + // Track forward refs to be resolved later. + if (AnyFwdRefs) { + MinFwdRef = std::min(MinFwdRef, Idx); + MaxFwdRef = std::max(MaxFwdRef, Idx); + } else { + AnyFwdRefs = true; + MinFwdRef = MaxFwdRef = Idx; + } ++NumFwdRefs; - Metadata *MD = MDNode::getTemporary(Context, None); + + // Create and return a placeholder, which will later be RAUW'd. + Metadata *MD = MDNode::getTemporary(Context, None).release(); MDValuePtrs[Idx].reset(MD); return MD; } @@ -572,14 +928,18 @@ void BitcodeReaderMDValueList::tryToResolveCycles() { return; // Resolve any cycles. - for (auto &MD : MDValuePtrs) { - auto *N = dyn_cast_or_null(MD); + for (unsigned I = MinFwdRef, E = MaxFwdRef + 1; I != E; ++I) { + auto &MD = MDValuePtrs[I]; + auto *N = dyn_cast_or_null(MD); if (!N) continue; assert(!N->isTemporary() && "Unexpected forward reference"); N->resolveCycles(); } + + // Make sure we return early again until there's another forward ref. + AnyFwdRefs = false; } Type *BitcodeReader::getTypeByID(unsigned ID) { @@ -738,6 +1098,8 @@ static Attribute::AttrKind GetAttrFromCode(uint64_t Code) { return Attribute::NonNull; case bitc::ATTR_KIND_DEREFERENCEABLE: return Attribute::Dereferenceable; + case bitc::ATTR_KIND_DEREFERENCEABLE_OR_NULL: + return Attribute::DereferenceableOrNull; case bitc::ATTR_KIND_NO_RED_ZONE: return Attribute::NoRedZone; case bitc::ATTR_KIND_NO_RETURN: @@ -781,6 +1143,16 @@ static Attribute::AttrKind GetAttrFromCode(uint64_t Code) { } } +std::error_code BitcodeReader::parseAlignmentValue(uint64_t Exponent, + unsigned &Alignment) { + // Note: Alignment in bitcode files is incremented by 1, so that zero + // can be used for default alignment. + if (Exponent > Value::MaxAlignmentExponent + 1) + return Error("Invalid alignment value"); + Alignment = (1 << static_cast(Exponent)) >> 1; + return std::error_code(); +} + std::error_code BitcodeReader::ParseAttrKind(uint64_t Code, Attribute::AttrKind *Kind) { *Kind = GetAttrFromCode(Code); @@ -844,6 +1216,8 @@ std::error_code BitcodeReader::ParseAttributeGroupBlock() { B.addStackAlignmentAttr(Record[++i]); else if (Kind == Attribute::Dereferenceable) B.addDereferenceableAttr(Record[++i]); + else if (Kind == Attribute::DereferenceableOrNull) + B.addDereferenceableOrNullAttr(Record[++i]); } else { // String attribute assert((Record[i] == 3 || Record[i] == 4) && "Invalid attribute group entry"); @@ -950,12 +1324,17 @@ std::error_code BitcodeReader::ParseTypeTableBody() { case bitc::TYPE_CODE_X86_MMX: // X86_MMX ResultTy = Type::getX86_MMXTy(Context); break; - case bitc::TYPE_CODE_INTEGER: // INTEGER: [width] + case bitc::TYPE_CODE_INTEGER: { // INTEGER: [width] if (Record.size() < 1) return Error("Invalid record"); - ResultTy = IntegerType::get(Context, Record[0]); + uint64_t NumBits = Record[0]; + if (NumBits < IntegerType::MIN_INT_BITS || + NumBits > IntegerType::MAX_INT_BITS) + return Error("Bitwidth for integer type out of range"); + ResultTy = IntegerType::get(Context, NumBits); break; + } case bitc::TYPE_CODE_POINTER: { // POINTER: [pointee type] or // [pointee type, address space] if (Record.size() < 1) @@ -1095,8 +1474,10 @@ std::error_code BitcodeReader::ParseTypeTableBody() { if (NumRecords >= TypeList.size()) return Error("Invalid TYPE table"); + if (TypeList[NumRecords]) + return Error( + "Invalid TYPE table: Only named structs can be forward referenced"); assert(ResultTy && "Didn't read a type?"); - assert(!TypeList[NumRecords] && "Already read type?"); TypeList[NumRecords++] = ResultTy; } } @@ -1107,6 +1488,8 @@ std::error_code BitcodeReader::ParseValueSymbolTable() { SmallVector Record; + Triple TT(TheModule->getTargetTriple()); + // Read all the records for this value table. SmallString<128> ValueName; while (1) { @@ -1138,8 +1521,12 @@ std::error_code BitcodeReader::ParseValueSymbolTable() { V->setName(StringRef(ValueName.data(), ValueName.size())); if (auto *GO = dyn_cast(V)) { - if (GO->getComdat() == reinterpret_cast(1)) - GO->setComdat(TheModule->getOrInsertComdat(V->getName())); + if (GO->getComdat() == reinterpret_cast(1)) { + if (TT.isOSBinFormatMachO()) + GO->setComdat(nullptr); + else + GO->setComdat(TheModule->getOrInsertComdat(V->getName())); + } } ValueName.clear(); break; @@ -1159,7 +1546,10 @@ std::error_code BitcodeReader::ParseValueSymbolTable() { } } +static int64_t unrotateSign(uint64_t U) { return U & 1 ? ~(U >> 1) : U >> 1; } + std::error_code BitcodeReader::ParseMetadata() { + IsMetadataMaterialized = true; unsigned NextMDValueNo = MDValueList.size(); if (Stream.EnterSubBlock(bitc::METADATA_BLOCK_ID)) @@ -1167,6 +1557,22 @@ std::error_code BitcodeReader::ParseMetadata() { SmallVector Record; + auto getMD = + [&](unsigned ID) -> Metadata *{ return MDValueList.getValueFwdRef(ID); }; + auto getMDOrNull = [&](unsigned ID) -> Metadata *{ + if (ID) + return getMD(ID - 1); + return nullptr; + }; + auto getMDString = [&](unsigned ID) -> MDString *{ + // This requires that the ID is not really a forward reference. In + // particular, the MDString must already have been resolved. + return cast_or_null(getMDOrNull(ID)); + }; + +#define GET_OR_DISTINCT(CLASS, DISTINCT, ARGS) \ + (DISTINCT ? CLASS::getDistinct ARGS : CLASS::get ARGS) + // Read all the records. while (1) { BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); @@ -1294,16 +1700,269 @@ std::error_code BitcodeReader::ParseMetadata() { if (Record.size() != 5) return Error("Invalid record"); - auto get = Record[0] ? MDLocation::getDistinct : MDLocation::get; unsigned Line = Record[1]; unsigned Column = Record[2]; MDNode *Scope = cast(MDValueList.getValueFwdRef(Record[3])); Metadata *InlinedAt = Record[4] ? MDValueList.getValueFwdRef(Record[4] - 1) : nullptr; - MDValueList.AssignValue(get(Context, Line, Column, Scope, InlinedAt), + MDValueList.AssignValue( + GET_OR_DISTINCT(MDLocation, Record[0], + (Context, Line, Column, Scope, InlinedAt)), + NextMDValueNo++); + break; + } + case bitc::METADATA_GENERIC_DEBUG: { + if (Record.size() < 4) + return Error("Invalid record"); + + unsigned Tag = Record[1]; + unsigned Version = Record[2]; + + if (Tag >= 1u << 16 || Version != 0) + return Error("Invalid record"); + + auto *Header = getMDString(Record[3]); + SmallVector DwarfOps; + for (unsigned I = 4, E = Record.size(); I != E; ++I) + DwarfOps.push_back(Record[I] ? MDValueList.getValueFwdRef(Record[I] - 1) + : nullptr); + MDValueList.AssignValue(GET_OR_DISTINCT(GenericDebugNode, Record[0], + (Context, Tag, Header, DwarfOps)), + NextMDValueNo++); + break; + } + case bitc::METADATA_SUBRANGE: { + if (Record.size() != 3) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(MDSubrange, Record[0], + (Context, Record[1], unrotateSign(Record[2]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_ENUMERATOR: { + if (Record.size() != 3) + return Error("Invalid record"); + + MDValueList.AssignValue(GET_OR_DISTINCT(MDEnumerator, Record[0], + (Context, unrotateSign(Record[1]), + getMDString(Record[2]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_BASIC_TYPE: { + if (Record.size() != 6) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(MDBasicType, Record[0], + (Context, Record[1], getMDString(Record[2]), + Record[3], Record[4], Record[5])), + NextMDValueNo++); + break; + } + case bitc::METADATA_DERIVED_TYPE: { + if (Record.size() != 12) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(MDDerivedType, Record[0], + (Context, Record[1], getMDString(Record[2]), + getMDOrNull(Record[3]), Record[4], + getMDOrNull(Record[5]), getMDOrNull(Record[6]), + Record[7], Record[8], Record[9], Record[10], + getMDOrNull(Record[11]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_COMPOSITE_TYPE: { + if (Record.size() != 16) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(MDCompositeType, Record[0], + (Context, Record[1], getMDString(Record[2]), + getMDOrNull(Record[3]), Record[4], + getMDOrNull(Record[5]), getMDOrNull(Record[6]), + Record[7], Record[8], Record[9], Record[10], + getMDOrNull(Record[11]), Record[12], + getMDOrNull(Record[13]), getMDOrNull(Record[14]), + getMDString(Record[15]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_SUBROUTINE_TYPE: { + if (Record.size() != 3) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(MDSubroutineType, Record[0], + (Context, Record[1], getMDOrNull(Record[2]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_FILE: { + if (Record.size() != 3) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(MDFile, Record[0], (Context, getMDString(Record[1]), + getMDString(Record[2]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_COMPILE_UNIT: { + if (Record.size() != 14) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(MDCompileUnit, Record[0], + (Context, Record[1], getMDOrNull(Record[2]), + getMDString(Record[3]), Record[4], + getMDString(Record[5]), Record[6], + getMDString(Record[7]), Record[8], + getMDOrNull(Record[9]), getMDOrNull(Record[10]), + getMDOrNull(Record[11]), getMDOrNull(Record[12]), + getMDOrNull(Record[13]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_SUBPROGRAM: { + if (Record.size() != 19) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT( + MDSubprogram, Record[0], + (Context, getMDOrNull(Record[1]), getMDString(Record[2]), + getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], + getMDOrNull(Record[6]), Record[7], Record[8], Record[9], + getMDOrNull(Record[10]), Record[11], Record[12], Record[13], + Record[14], getMDOrNull(Record[15]), getMDOrNull(Record[16]), + getMDOrNull(Record[17]), getMDOrNull(Record[18]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_LEXICAL_BLOCK: { + if (Record.size() != 5) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(MDLexicalBlock, Record[0], + (Context, getMDOrNull(Record[1]), + getMDOrNull(Record[2]), Record[3], Record[4])), + NextMDValueNo++); + break; + } + case bitc::METADATA_LEXICAL_BLOCK_FILE: { + if (Record.size() != 4) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(MDLexicalBlockFile, Record[0], + (Context, getMDOrNull(Record[1]), + getMDOrNull(Record[2]), Record[3])), + NextMDValueNo++); + break; + } + case bitc::METADATA_NAMESPACE: { + if (Record.size() != 5) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(MDNamespace, Record[0], + (Context, getMDOrNull(Record[1]), + getMDOrNull(Record[2]), getMDString(Record[3]), + Record[4])), + NextMDValueNo++); + break; + } + case bitc::METADATA_TEMPLATE_TYPE: { + if (Record.size() != 3) + return Error("Invalid record"); + + MDValueList.AssignValue(GET_OR_DISTINCT(MDTemplateTypeParameter, + Record[0], + (Context, getMDString(Record[1]), + getMDOrNull(Record[2]))), NextMDValueNo++); break; } + case bitc::METADATA_TEMPLATE_VALUE: { + if (Record.size() != 5) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(MDTemplateValueParameter, Record[0], + (Context, Record[1], getMDString(Record[2]), + getMDOrNull(Record[3]), getMDOrNull(Record[4]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_GLOBAL_VAR: { + if (Record.size() != 11) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(MDGlobalVariable, Record[0], + (Context, getMDOrNull(Record[1]), + getMDString(Record[2]), getMDString(Record[3]), + getMDOrNull(Record[4]), Record[5], + getMDOrNull(Record[6]), Record[7], Record[8], + getMDOrNull(Record[9]), getMDOrNull(Record[10]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_LOCAL_VAR: { + // 10th field is for the obseleted 'inlinedAt:' field. + if (Record.size() != 9 && Record.size() != 10) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(MDLocalVariable, Record[0], + (Context, Record[1], getMDOrNull(Record[2]), + getMDString(Record[3]), getMDOrNull(Record[4]), + Record[5], getMDOrNull(Record[6]), Record[7], + Record[8])), + NextMDValueNo++); + break; + } + case bitc::METADATA_EXPRESSION: { + if (Record.size() < 1) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(MDExpression, Record[0], + (Context, makeArrayRef(Record).slice(1))), + NextMDValueNo++); + break; + } + case bitc::METADATA_OBJC_PROPERTY: { + if (Record.size() != 8) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(MDObjCProperty, Record[0], + (Context, getMDString(Record[1]), + getMDOrNull(Record[2]), Record[3], + getMDString(Record[4]), getMDString(Record[5]), + Record[6], getMDOrNull(Record[7]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_IMPORTED_ENTITY: { + if (Record.size() != 6) + return Error("Invalid record"); + + MDValueList.AssignValue( + GET_OR_DISTINCT(MDImportedEntity, Record[0], + (Context, Record[1], getMDOrNull(Record[2]), + getMDOrNull(Record[3]), Record[4], + getMDString(Record[5]))), + NextMDValueNo++); + break; + } case bitc::METADATA_STRING: { std::string String(Record.begin(), Record.end()); llvm::UpgradeMDStringConstant(String); @@ -1325,6 +1984,7 @@ std::error_code BitcodeReader::ParseMetadata() { } } } +#undef GET_OR_DISTINCT } /// decodeSignRotatedValue - Decode a signed value stored with the sign bit in @@ -1646,19 +2306,29 @@ std::error_code BitcodeReader::ParseConstants() { } case bitc::CST_CODE_CE_INBOUNDS_GEP: case bitc::CST_CODE_CE_GEP: { // CE_GEP: [n x operands] - if (Record.size() & 1) - return Error("Invalid record"); + unsigned OpNum = 0; + Type *PointeeType = nullptr; + if (Record.size() % 2) + PointeeType = getTypeByID(Record[OpNum++]); SmallVector Elts; - for (unsigned i = 0, e = Record.size(); i != e; i += 2) { - Type *ElTy = getTypeByID(Record[i]); + while (OpNum != Record.size()) { + Type *ElTy = getTypeByID(Record[OpNum++]); if (!ElTy) return Error("Invalid record"); - Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], ElTy)); + Elts.push_back(ValueList.getConstantFwdRef(Record[OpNum++], ElTy)); } + + if (PointeeType && + PointeeType != + cast(Elts[0]->getType()->getScalarType()) + ->getElementType()) + return Error("Explicit gep operator type does not match pointee type " + "of pointer operand"); + ArrayRef Indices(Elts.begin() + 1, Elts.end()); - V = ConstantExpr::getGetElementPtr(Elts[0], Indices, + V = ConstantExpr::getGetElementPtr(PointeeType, Elts[0], Indices, BitCode == - bitc::CST_CODE_CE_INBOUNDS_GEP); + bitc::CST_CODE_CE_INBOUNDS_GEP); break; } case bitc::CST_CODE_CE_SELECT: { // CE_SELECT: [opval#, opval#, opval#] @@ -1928,6 +2598,32 @@ std::error_code BitcodeReader::ParseUseLists() { } } +/// When we see the block for metadata, remember where it is and then skip it. +/// This lets us lazily deserialize the metadata. +std::error_code BitcodeReader::rememberAndSkipMetadata() { + // Save the current stream state. + uint64_t CurBit = Stream.GetCurrentBitNo(); + DeferredMetadataInfo.push_back(CurBit); + + // Skip over the block for now. + if (Stream.SkipBlock()) + return Error("Invalid record"); + return std::error_code(); +} + +std::error_code BitcodeReader::materializeMetadata() { + for (uint64_t BitPos : DeferredMetadataInfo) { + // Move the bit stream to the saved position. + Stream.JumpToBit(BitPos); + if (std::error_code EC = ParseMetadata()) + return EC; + } + DeferredMetadataInfo.clear(); + return std::error_code(); +} + +void BitcodeReader::setStripDebugInfo() { StripDebugInfo = true; } + /// 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. @@ -1978,7 +2674,8 @@ std::error_code BitcodeReader::GlobalCleanup() { return std::error_code(); } -std::error_code BitcodeReader::ParseModule(bool Resume) { +std::error_code BitcodeReader::ParseModule(bool Resume, + bool ShouldLazyLoadMetadata) { if (Resume) Stream.JumpToBit(NextUnreadBit); else if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) @@ -2032,6 +2729,12 @@ std::error_code BitcodeReader::ParseModule(bool Resume) { return EC; break; case bitc::METADATA_BLOCK_ID: + if (ShouldLazyLoadMetadata && !IsMetadataMaterialized) { + if (std::error_code EC = rememberAndSkipMetadata()) + return EC; + break; + } + assert(DeferredMetadataInfo.empty() && "Unexpected deferred metadata"); if (std::error_code EC = ParseMetadata()) return EC; break; @@ -2150,7 +2853,8 @@ std::error_code BitcodeReader::ParseModule(bool Resume) { } // GLOBALVAR: [pointer type, isconst, initid, // linkage, alignment, section, visibility, threadlocal, - // unnamed_addr, dllstorageclass] + // unnamed_addr, externally_initialized, dllstorageclass, + // comdat] case bitc::MODULE_CODE_GLOBALVAR: { if (Record.size() < 6) return Error("Invalid record"); @@ -2165,7 +2869,9 @@ std::error_code BitcodeReader::ParseModule(bool Resume) { bool isConstant = Record[1]; uint64_t RawLinkage = Record[3]; GlobalValue::LinkageTypes Linkage = getDecodedLinkage(RawLinkage); - unsigned Alignment = (1 << Record[4]) >> 1; + unsigned Alignment; + if (std::error_code EC = parseAlignmentValue(Record[4], Alignment)) + return EC; std::string Section; if (Record[5]) { if (Record[5]-1 >= SectionTable.size()) @@ -2229,10 +2935,9 @@ std::error_code BitcodeReader::ParseModule(bool Resume) { Type *Ty = getTypeByID(Record[0]); if (!Ty) return Error("Invalid record"); - if (!Ty->isPointerTy()) - return Error("Invalid type for value"); - FunctionType *FTy = - dyn_cast(cast(Ty)->getElementType()); + if (auto *PTy = dyn_cast(Ty)) + Ty = PTy->getElementType(); + auto *FTy = dyn_cast(Ty); if (!FTy) return Error("Invalid type for value"); @@ -2245,7 +2950,10 @@ std::error_code BitcodeReader::ParseModule(bool Resume) { Func->setLinkage(getDecodedLinkage(RawLinkage)); Func->setAttributes(getAttributes(Record[4])); - Func->setAlignment((1 << Record[5]) >> 1); + unsigned Alignment; + if (std::error_code EC = parseAlignmentValue(Record[5], Alignment)) + return EC; + Func->setAlignment(Alignment); if (Record[6]) { if (Record[6]-1 >= SectionTable.size()) return Error("Invalid ID"); @@ -2340,7 +3048,8 @@ std::error_code BitcodeReader::ParseModule(bool Resume) { } } -std::error_code BitcodeReader::ParseBitcodeInto(Module *M) { +std::error_code BitcodeReader::ParseBitcodeInto(Module *M, + bool ShouldLazyLoadMetadata) { TheModule = nullptr; if (std::error_code EC = InitStream()) @@ -2358,8 +3067,12 @@ std::error_code BitcodeReader::ParseBitcodeInto(Module *M) { // We expect a number of well-defined blocks, though we don't necessarily // need to understand them all. while (1) { - if (Stream.AtEndOfStream()) - return std::error_code(); + if (Stream.AtEndOfStream()) { + if (TheModule) + return std::error_code(); + // We didn't really read a proper Module. + return Error("Malformed IR file"); + } BitstreamEntry Entry = Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs); @@ -2381,7 +3094,7 @@ std::error_code BitcodeReader::ParseBitcodeInto(Module *M) { if (TheModule) return Error("Invalid multiple blocks"); TheModule = M; - if (std::error_code EC = ParseModule(false)) + if (std::error_code EC = ParseModule(false, ShouldLazyLoadMetadata)) return EC; if (LazyStreamer) return std::error_code(); @@ -2750,13 +3463,33 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { InstructionList.push_back(I); break; } - case bitc::FUNC_CODE_INST_INBOUNDS_GEP: - case bitc::FUNC_CODE_INST_GEP: { // GEP: [n x operands] + case bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD: + case bitc::FUNC_CODE_INST_GEP_OLD: + case bitc::FUNC_CODE_INST_GEP: { // GEP: type, [n x operands] unsigned OpNum = 0; + + Type *Ty; + bool InBounds; + + if (BitCode == bitc::FUNC_CODE_INST_GEP) { + InBounds = Record[OpNum++]; + Ty = getTypeByID(Record[OpNum++]); + } else { + InBounds = BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD; + Ty = nullptr; + } + Value *BasePtr; if (getValueTypePair(Record, OpNum, NextValueNo, BasePtr)) return Error("Invalid record"); + if (Ty && + Ty != + cast(BasePtr->getType()->getScalarType()) + ->getElementType()) + return Error( + "Explicit gep type does not match pointee type of pointer operand"); + SmallVector GEPIdx; while (OpNum != Record.size()) { Value *Op; @@ -2765,9 +3498,10 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { GEPIdx.push_back(Op); } - I = GetElementPtrInst::Create(BasePtr, GEPIdx); + I = GetElementPtrInst::Create(Ty, BasePtr, GEPIdx); + InstructionList.push_back(I); - if (BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP) + if (InBounds) cast(I)->setIsInBounds(true); break; } @@ -2780,12 +3514,27 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { return Error("Invalid record"); SmallVector EXTRACTVALIdx; + Type *CurTy = Agg->getType(); for (unsigned RecSize = Record.size(); OpNum != RecSize; ++OpNum) { + bool IsArray = CurTy->isArrayTy(); + bool IsStruct = CurTy->isStructTy(); uint64_t Index = Record[OpNum]; + + if (!IsStruct && !IsArray) + return Error("EXTRACTVAL: Invalid type"); if ((unsigned)Index != Index) return Error("Invalid value"); + if (IsStruct && Index >= CurTy->subtypes().size()) + return Error("EXTRACTVAL: Invalid struct index"); + if (IsArray && Index >= CurTy->getArrayNumElements()) + return Error("EXTRACTVAL: Invalid array index"); EXTRACTVALIdx.push_back((unsigned)Index); + + if (IsStruct) + CurTy = CurTy->subtypes()[Index]; + else + CurTy = CurTy->subtypes()[0]; } I = ExtractValueInst::Create(Agg, EXTRACTVALIdx); @@ -2804,12 +3553,29 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { return Error("Invalid record"); SmallVector INSERTVALIdx; + Type *CurTy = Agg->getType(); for (unsigned RecSize = Record.size(); OpNum != RecSize; ++OpNum) { + bool IsArray = CurTy->isArrayTy(); + bool IsStruct = CurTy->isStructTy(); uint64_t Index = Record[OpNum]; + + if (!IsStruct && !IsArray) + return Error("INSERTVAL: Invalid type"); + if (!CurTy->isStructTy() && !CurTy->isArrayTy()) + return Error("Invalid type"); if ((unsigned)Index != Index) return Error("Invalid value"); + if (IsStruct && Index >= CurTy->subtypes().size()) + return Error("INSERTVAL: Invalid struct index"); + if (IsArray && Index >= CurTy->getArrayNumElements()) + return Error("INSERTVAL: Invalid array index"); + INSERTVALIdx.push_back((unsigned)Index); + if (IsStruct) + CurTy = CurTy->subtypes()[Index]; + else + CurTy = CurTy->subtypes()[0]; } I = InsertValueInst::Create(Agg, Val, INSERTVALIdx); @@ -3210,12 +3976,17 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { dyn_cast_or_null(getTypeByID(Record[0])); Type *OpTy = getTypeByID(Record[1]); Value *Size = getFnValueByID(Record[2], OpTy); - unsigned AlignRecord = Record[3]; - bool InAlloca = AlignRecord & (1 << 5); - unsigned Align = AlignRecord & ((1 << 5) - 1); + uint64_t AlignRecord = Record[3]; + const uint64_t InAllocaMask = uint64_t(1) << 5; + bool InAlloca = AlignRecord & InAllocaMask; + unsigned Align; + if (std::error_code EC = + parseAlignmentValue(AlignRecord & ~InAllocaMask, Align)) { + return EC; + } if (!Ty || !Size) return Error("Invalid record"); - AllocaInst *AI = new AllocaInst(Ty->getElementType(), Size, (1 << Align) >> 1); + AllocaInst *AI = new AllocaInst(Ty->getElementType(), Size, Align); AI->setUsedWithInAlloca(InAlloca); I = AI; InstructionList.push_back(I); @@ -3225,10 +3996,23 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { unsigned OpNum = 0; Value *Op; if (getValueTypePair(Record, OpNum, NextValueNo, Op) || - OpNum+2 != Record.size()) + (OpNum + 2 != Record.size() && OpNum + 3 != Record.size())) return Error("Invalid record"); - I = new LoadInst(Op, "", Record[OpNum+1], (1 << Record[OpNum]) >> 1); + Type *Ty = nullptr; + if (OpNum + 3 == Record.size()) + Ty = getTypeByID(Record[OpNum++]); + if (!Ty) + Ty = cast(Op->getType())->getElementType(); + else if (Ty != cast(Op->getType())->getElementType()) + return Error("Explicit load type does not match pointee type of " + "pointer operand"); + + unsigned Align; + if (std::error_code EC = parseAlignmentValue(Record[OpNum], Align)) + return EC; + I = new LoadInst(Ty, Op, "", Record[OpNum + 1], Align); + InstructionList.push_back(I); break; } @@ -3237,9 +4021,13 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { unsigned OpNum = 0; Value *Op; if (getValueTypePair(Record, OpNum, NextValueNo, Op) || - OpNum+4 != Record.size()) + (OpNum + 4 != Record.size() && OpNum + 5 != Record.size())) return Error("Invalid record"); + Type *Ty = nullptr; + if (OpNum + 5 == Record.size()) + Ty = getTypeByID(Record[OpNum++]); + AtomicOrdering Ordering = GetDecodedOrdering(Record[OpNum+2]); if (Ordering == NotAtomic || Ordering == Release || Ordering == AcquireRelease) @@ -3248,21 +4036,34 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { return Error("Invalid record"); SynchronizationScope SynchScope = GetDecodedSynchScope(Record[OpNum+3]); - I = new LoadInst(Op, "", Record[OpNum+1], (1 << Record[OpNum]) >> 1, - Ordering, SynchScope); + unsigned Align; + if (std::error_code EC = parseAlignmentValue(Record[OpNum], Align)) + return EC; + I = new LoadInst(Op, "", Record[OpNum+1], Align, Ordering, SynchScope); + + (void)Ty; + assert((!Ty || Ty == I->getType()) && + "Explicit type doesn't match pointee type of the first operand"); + InstructionList.push_back(I); break; } - case bitc::FUNC_CODE_INST_STORE: { // STORE2:[ptrty, ptr, val, align, vol] + case bitc::FUNC_CODE_INST_STORE: + case bitc::FUNC_CODE_INST_STORE_OLD: { // STORE2:[ptrty, ptr, val, align, vol] unsigned OpNum = 0; Value *Val, *Ptr; if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) || - popValue(Record, OpNum, NextValueNo, - cast(Ptr->getType())->getElementType(), Val) || - OpNum+2 != Record.size()) + (BitCode == bitc::FUNC_CODE_INST_STORE + ? getValueTypePair(Record, OpNum, NextValueNo, Val) + : popValue(Record, OpNum, NextValueNo, + cast(Ptr->getType())->getElementType(), + Val)) || + OpNum + 2 != Record.size()) return Error("Invalid record"); - - I = new StoreInst(Val, Ptr, Record[OpNum+1], (1 << Record[OpNum]) >> 1); + unsigned Align; + if (std::error_code EC = parseAlignmentValue(Record[OpNum], Align)) + return EC; + I = new StoreInst(Val, Ptr, Record[OpNum+1], Align); InstructionList.push_back(I); break; } @@ -3284,8 +4085,10 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { if (Ordering != NotAtomic && Record[OpNum] == 0) return Error("Invalid record"); - I = new StoreInst(Val, Ptr, Record[OpNum+1], (1 << Record[OpNum]) >> 1, - Ordering, SynchScope); + unsigned Align; + if (std::error_code EC = parseAlignmentValue(Record[OpNum], Align)) + return EC; + I = new StoreInst(Val, Ptr, Record[OpNum+1], Align, Ordering, SynchScope); InstructionList.push_back(I); break; } @@ -3369,19 +4172,31 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { if (Record.size() < 3) return Error("Invalid record"); - AttributeSet PAL = getAttributes(Record[0]); - unsigned CCInfo = Record[1]; + unsigned OpNum = 0; + AttributeSet PAL = getAttributes(Record[OpNum++]); + unsigned CCInfo = Record[OpNum++]; + + FunctionType *FTy = nullptr; + if (CCInfo >> 15 & 1 && + !(FTy = dyn_cast(getTypeByID(Record[OpNum++])))) + return Error("Explicit call type is not a function type"); - unsigned OpNum = 2; Value *Callee; if (getValueTypePair(Record, OpNum, NextValueNo, Callee)) return Error("Invalid record"); PointerType *OpTy = dyn_cast(Callee->getType()); - FunctionType *FTy = nullptr; - if (OpTy) FTy = dyn_cast(OpTy->getElementType()); - if (!FTy || Record.size() < FTy->getNumParams()+OpNum) - return Error("Invalid record"); + if (!OpTy) + return Error("Callee is not a pointer type"); + if (!FTy) { + FTy = dyn_cast(OpTy->getElementType()); + if (!FTy) + return Error("Callee is not of pointer to function type"); + } else if (OpTy->getElementType() != FTy) + return Error("Explicit call type does not match pointee type of " + "callee operand"); + if (Record.size() < FTy->getNumParams() + OpNum) + return Error("Insufficient operands to call"); SmallVector Args; // Read the fixed params. @@ -3408,7 +4223,7 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { } } - I = CallInst::Create(Callee, Args); + I = CallInst::Create(FTy, Callee, Args); InstructionList.push_back(I); cast(I)->setCallingConv( static_cast((~(1U << 14) & CCInfo) >> 1)); @@ -3502,6 +4317,9 @@ std::error_code BitcodeReader::FindFunctionInStream( void BitcodeReader::releaseBuffer() { Buffer.release(); } std::error_code BitcodeReader::materialize(GlobalValue *GV) { + if (std::error_code EC = materializeMetadata()) + return EC; + Function *F = dyn_cast(GV); // If it's not a function or is already material, ignore the request. if (!F || !F->isMaterializable()) @@ -3522,6 +4340,9 @@ std::error_code BitcodeReader::materialize(GlobalValue *GV) { return EC; F->setIsMaterializable(false); + if (StripDebugInfo) + stripDebugInfo(*F); + // Upgrade any old intrinsic calls in the function. for (UpgradedIntrinsicMap::iterator I = UpgradedIntrinsics.begin(), E = UpgradedIntrinsics.end(); I != E; ++I) { @@ -3569,6 +4390,9 @@ std::error_code BitcodeReader::MaterializeModule(Module *M) { assert(M == TheModule && "Can only Materialize the Module this BitcodeReader is attached to."); + if (std::error_code EC = materializeMetadata()) + return EC; + // Promise to materialize all forward references. WillMaterializeAllForwardRefs = true; @@ -3709,7 +4533,8 @@ const std::error_category &llvm::BitcodeErrorCategory() { static ErrorOr getLazyBitcodeModuleImpl(std::unique_ptr &&Buffer, LLVMContext &Context, bool WillMaterializeAll, - DiagnosticHandlerFunction DiagnosticHandler) { + DiagnosticHandlerFunction DiagnosticHandler, + bool ShouldLazyLoadMetadata = false) { Module *M = new Module(Buffer->getBufferIdentifier(), Context); BitcodeReader *R = new BitcodeReader(Buffer.get(), Context, DiagnosticHandler); @@ -3721,7 +4546,8 @@ getLazyBitcodeModuleImpl(std::unique_ptr &&Buffer, return EC; }; - if (std::error_code EC = R->ParseBitcodeInto(M)) + // Delay parsing Metadata if ShouldLazyLoadMetadata is true. + if (std::error_code EC = R->ParseBitcodeInto(M, ShouldLazyLoadMetadata)) return cleanupOnError(EC); if (!WillMaterializeAll) @@ -3736,9 +4562,10 @@ getLazyBitcodeModuleImpl(std::unique_ptr &&Buffer, ErrorOr llvm::getLazyBitcodeModule(std::unique_ptr &&Buffer, LLVMContext &Context, - DiagnosticHandlerFunction DiagnosticHandler) { + DiagnosticHandlerFunction DiagnosticHandler, + bool ShouldLazyLoadMetadata) { return getLazyBitcodeModuleImpl(std::move(Buffer), Context, false, - DiagnosticHandler); + DiagnosticHandler, ShouldLazyLoadMetadata); } ErrorOr>