diff options
Diffstat (limited to 'lib/Bitcode/Reader')
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 237 | ||||
-rw-r--r-- | lib/Bitcode/Reader/MetadataLoader.cpp | 119 | ||||
-rw-r--r-- | lib/Bitcode/Reader/MetadataLoader.h | 4 | ||||
-rw-r--r-- | lib/Bitcode/Reader/ValueList.cpp | 2 |
4 files changed, 282 insertions, 80 deletions
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index c45b441238bc..fe051e7a9125 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -876,6 +876,7 @@ static FunctionSummary::FFlags getDecodedFFlags(uint64_t RawFlags) { Flags.ReadOnly = (RawFlags >> 1) & 0x1; Flags.NoRecurse = (RawFlags >> 2) & 0x1; Flags.ReturnDoesNotAlias = (RawFlags >> 3) & 0x1; + Flags.NoInline = (RawFlags >> 4) & 0x1; return Flags; } @@ -897,6 +898,11 @@ static GlobalValueSummary::GVFlags getDecodedGVSummaryFlags(uint64_t RawFlags, return GlobalValueSummary::GVFlags(Linkage, NotEligibleToImport, Live, Local); } +// Decode the flags for GlobalVariable in the summary +static GlobalVarSummary::GVarFlags getDecodedGVarFlags(uint64_t RawFlags) { + return GlobalVarSummary::GVarFlags((RawFlags & 0x1) ? true : false); +} + static GlobalValue::VisibilityTypes getDecodedVisibility(unsigned Val) { switch (Val) { default: // Map unknown visibilities to default. @@ -963,6 +969,20 @@ static int getDecodedCastOpcode(unsigned Val) { } } +static int getDecodedUnaryOpcode(unsigned Val, Type *Ty) { + bool IsFP = Ty->isFPOrFPVectorTy(); + // UnOps are only valid for int/fp or vector of int/fp types + if (!IsFP && !Ty->isIntOrIntVectorTy()) + return -1; + + switch (Val) { + default: + return -1; + case bitc::UNOP_NEG: + return IsFP ? Instruction::FNeg : -1; + } +} + static int getDecodedBinaryOpcode(unsigned Val, Type *Ty) { bool IsFP = Ty->isFPOrFPVectorTy(); // BinOps are only valid for int/fp or vector of int/fp types @@ -1165,6 +1185,8 @@ static uint64_t getRawAttributeMask(Attribute::AttrKind Val) { case Attribute::NoCfCheck: return 1ULL << 57; case Attribute::OptForFuzzing: return 1ULL << 58; case Attribute::ShadowCallStack: return 1ULL << 59; + case Attribute::SpeculativeLoadHardening: + return 1ULL << 60; case Attribute::Dereferenceable: llvm_unreachable("dereferenceable attribute not supported in raw format"); break; @@ -1389,6 +1411,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) { return Attribute::SanitizeThread; case bitc::ATTR_KIND_SANITIZE_MEMORY: return Attribute::SanitizeMemory; + case bitc::ATTR_KIND_SPECULATIVE_LOAD_HARDENING: + return Attribute::SpeculativeLoadHardening; case bitc::ATTR_KIND_SWIFT_ERROR: return Attribute::SwiftError; case bitc::ATTR_KIND_SWIFT_SELF: @@ -2312,6 +2336,19 @@ Error BitcodeReader::parseConstants() { } break; } + case bitc::CST_CODE_CE_UNOP: { // CE_UNOP: [opcode, opval] + if (Record.size() < 2) + return error("Invalid record"); + int Opc = getDecodedUnaryOpcode(Record[0], CurTy); + if (Opc < 0) { + V = UndefValue::get(CurTy); // Unknown unop. + } else { + Constant *LHS = ValueList.getConstantFwdRef(Record[1], CurTy); + unsigned Flags = 0; + V = ConstantExpr::get(Opc, LHS, Flags); + } + break; + } case bitc::CST_CODE_CE_BINOP: { // CE_BINOP: [opcode, opval, opval] if (Record.size() < 3) return error("Invalid record"); @@ -2938,7 +2975,7 @@ Error BitcodeReader::parseGlobalVarRecord(ArrayRef<uint64_t> Record) { Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) { // v1: [type, callingconv, isproto, linkage, paramattr, alignment, section, // visibility, gc, unnamed_addr, prologuedata, dllstorageclass, comdat, - // prefixdata, personalityfn, preemption specifier] (name in VST) + // prefixdata, personalityfn, preemption specifier, addrspace] (name in VST) // v2: [strtab_offset, strtab_size, v1] StringRef Name; std::tie(Name, Record) = readNameFromStrtab(Record); @@ -2957,8 +2994,12 @@ Error BitcodeReader::parseFunctionRecord(ArrayRef<uint64_t> Record) { if (CC & ~CallingConv::MaxID) return error("Invalid calling convention ID"); - Function *Func = - Function::Create(FTy, GlobalValue::ExternalLinkage, Name, TheModule); + unsigned AddrSpace = TheModule->getDataLayout().getProgramAddressSpace(); + if (Record.size() > 16) + AddrSpace = Record[16]; + + Function *Func = Function::Create(FTy, GlobalValue::ExternalLinkage, + AddrSpace, Name, TheModule); Func->setCallingConv(CC); bool isProto = Record[2]; @@ -3508,24 +3549,47 @@ Error BitcodeReader::parseFunctionBody(Function *F) { unsigned Line = Record[0], Col = Record[1]; unsigned ScopeID = Record[2], IAID = Record[3]; + bool isImplicitCode = Record.size() == 5 && Record[4]; MDNode *Scope = nullptr, *IA = nullptr; if (ScopeID) { - Scope = MDLoader->getMDNodeFwdRefOrNull(ScopeID - 1); + Scope = dyn_cast_or_null<MDNode>( + MDLoader->getMetadataFwdRefOrLoad(ScopeID - 1)); if (!Scope) return error("Invalid record"); } if (IAID) { - IA = MDLoader->getMDNodeFwdRefOrNull(IAID - 1); + IA = dyn_cast_or_null<MDNode>( + MDLoader->getMetadataFwdRefOrLoad(IAID - 1)); if (!IA) return error("Invalid record"); } - LastLoc = DebugLoc::get(Line, Col, Scope, IA); + LastLoc = DebugLoc::get(Line, Col, Scope, IA, isImplicitCode); I->setDebugLoc(LastLoc); I = nullptr; continue; } + case bitc::FUNC_CODE_INST_UNOP: { // UNOP: [opval, ty, opcode] + unsigned OpNum = 0; + Value *LHS; + if (getValueTypePair(Record, OpNum, NextValueNo, LHS) || + OpNum+1 > Record.size()) + return error("Invalid record"); + int Opc = getDecodedUnaryOpcode(Record[OpNum++], LHS->getType()); + if (Opc == -1) + return error("Invalid record"); + I = UnaryOperator::Create((Instruction::UnaryOps)Opc, LHS); + InstructionList.push_back(I); + if (OpNum < Record.size()) { + if (isa<FPMathOperator>(I)) { + FastMathFlags FMF = getDecodedFastMathFlags(Record[OpNum]); + if (FMF.any()) + I->setFastMathFlags(FMF); + } + } + break; + } case bitc::FUNC_CODE_INST_BINOP: { // BINOP: [opval, ty, opval, opcode] unsigned OpNum = 0; Value *LHS, *RHS; @@ -3656,16 +3720,16 @@ Error BitcodeReader::parseFunctionBody(Function *F) { return error("EXTRACTVAL: Invalid type"); if ((unsigned)Index != Index) return error("Invalid value"); - if (IsStruct && Index >= CurTy->subtypes().size()) + if (IsStruct && Index >= CurTy->getStructNumElements()) 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]; + CurTy = CurTy->getStructElementType(Index); else - CurTy = CurTy->subtypes()[0]; + CurTy = CurTy->getArrayElementType(); } I = ExtractValueInst::Create(Agg, EXTRACTVALIdx); @@ -3698,16 +3762,16 @@ Error BitcodeReader::parseFunctionBody(Function *F) { return error("INSERTVAL: Invalid type"); if ((unsigned)Index != Index) return error("Invalid value"); - if (IsStruct && Index >= CurTy->subtypes().size()) + if (IsStruct && Index >= CurTy->getStructNumElements()) 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]; + CurTy = CurTy->getStructElementType(Index); else - CurTy = CurTy->subtypes()[0]; + CurTy = CurTy->getArrayElementType(); } if (CurTy != Val->getType()) @@ -4616,7 +4680,7 @@ Error BitcodeReader::parseFunctionBody(Function *F) { CurBB->getInstList().push_back(I); // If this was a terminator instruction, move to the next block. - if (isa<TerminatorInst>(I)) { + if (I->isTerminator()) { ++CurBBNo; CurBB = CurBBNo < FunctionBBs.size() ? FunctionBBs[CurBBNo] : nullptr; } @@ -4854,7 +4918,7 @@ void ModuleSummaryIndexBitcodeReader::setValueGUID( ValueIdToValueInfoMap[ValueID] = std::make_pair( TheIndex.getOrInsertValueInfo( ValueGUID, - UseStrtab ? ValueName : TheIndex.saveString(ValueName.str())), + UseStrtab ? ValueName : TheIndex.saveString(ValueName)), OriginalNameID); } @@ -5160,6 +5224,12 @@ static void parseTypeIdSummaryRecord(ArrayRef<uint64_t> Record, parseWholeProgramDevirtResolution(Record, Strtab, Slot, TypeId); } +static void setImmutableRefs(std::vector<ValueInfo> &Refs, unsigned Count) { + // Read-only refs are in the end of the refs list. + for (unsigned RefNo = Refs.size() - Count; RefNo < Refs.size(); ++RefNo) + Refs[RefNo].setReadOnly(); +} + // Eagerly parse the entire summary block. This populates the GlobalValueSummary // objects in the index. Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { @@ -5177,9 +5247,9 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { } const uint64_t Version = Record[0]; const bool IsOldProfileFormat = Version == 1; - if (Version < 1 || Version > 4) + if (Version < 1 || Version > 6) return error("Invalid summary version " + Twine(Version) + - ", 1, 2, 3 or 4 expected"); + ". Version should be in the range [1-6]."); Record.clear(); // Keep around the last seen summary to be used when we see an optional @@ -5224,15 +5294,30 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { break; case bitc::FS_FLAGS: { // [flags] uint64_t Flags = Record[0]; - // Scan flags (set only on the combined index). - assert(Flags <= 0x3 && "Unexpected bits in flag"); + // Scan flags. + assert(Flags <= 0x1f && "Unexpected bits in flag"); // 1 bit: WithGlobalValueDeadStripping flag. + // Set on combined index only. if (Flags & 0x1) TheIndex.setWithGlobalValueDeadStripping(); // 1 bit: SkipModuleByDistributedBackend flag. + // Set on combined index only. if (Flags & 0x2) TheIndex.setSkipModuleByDistributedBackend(); + // 1 bit: HasSyntheticEntryCounts flag. + // Set on combined index only. + if (Flags & 0x4) + TheIndex.setHasSyntheticEntryCounts(); + // 1 bit: DisableSplitLTOUnit flag. + // Set on per module indexes. It is up to the client to validate + // the consistency of this flag across modules being linked. + if (Flags & 0x8) + TheIndex.setEnableSplitLTOUnit(); + // 1 bit: PartiallySplitLTOUnits flag. + // Set on combined index only. + if (Flags & 0x10) + TheIndex.setPartiallySplitLTOUnits(); break; } case bitc::FS_VALUE_GUID: { // [valueid, refguid] @@ -5258,11 +5343,16 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { unsigned InstCount = Record[2]; uint64_t RawFunFlags = 0; unsigned NumRefs = Record[3]; + unsigned NumImmutableRefs = 0; int RefListStartIndex = 4; if (Version >= 4) { RawFunFlags = Record[3]; NumRefs = Record[4]; RefListStartIndex = 5; + if (Version >= 5) { + NumImmutableRefs = Record[5]; + RefListStartIndex = 6; + } } auto Flags = getDecodedGVSummaryFlags(RawFlags, Version); @@ -5281,9 +5371,10 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { std::vector<FunctionSummary::EdgeTy> Calls = makeCallList( ArrayRef<uint64_t>(Record).slice(CallGraphEdgeStartIndex), IsOldProfileFormat, HasProfile, HasRelBF); + setImmutableRefs(Refs, NumImmutableRefs); auto FS = llvm::make_unique<FunctionSummary>( - Flags, InstCount, getDecodedFFlags(RawFunFlags), std::move(Refs), - std::move(Calls), std::move(PendingTypeTests), + Flags, InstCount, getDecodedFFlags(RawFunFlags), /*EntryCount=*/0, + std::move(Refs), std::move(Calls), std::move(PendingTypeTests), std::move(PendingTypeTestAssumeVCalls), std::move(PendingTypeCheckedLoadVCalls), std::move(PendingTypeTestAssumeConstVCalls), @@ -5329,14 +5420,21 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { TheIndex.addGlobalValueSummary(GUID.first, std::move(AS)); break; } - // FS_PERMODULE_GLOBALVAR_INIT_REFS: [valueid, flags, n x valueid] + // FS_PERMODULE_GLOBALVAR_INIT_REFS: [valueid, flags, varflags, n x valueid] case bitc::FS_PERMODULE_GLOBALVAR_INIT_REFS: { unsigned ValueID = Record[0]; uint64_t RawFlags = Record[1]; + unsigned RefArrayStart = 2; + GlobalVarSummary::GVarFlags GVF; auto Flags = getDecodedGVSummaryFlags(RawFlags, Version); + if (Version >= 5) { + GVF = getDecodedGVarFlags(Record[2]); + RefArrayStart = 3; + } std::vector<ValueInfo> Refs = - makeRefList(ArrayRef<uint64_t>(Record).slice(2)); - auto FS = llvm::make_unique<GlobalVarSummary>(Flags, std::move(Refs)); + makeRefList(ArrayRef<uint64_t>(Record).slice(RefArrayStart)); + auto FS = + llvm::make_unique<GlobalVarSummary>(Flags, GVF, std::move(Refs)); FS->setModulePath(getThisModule()->first()); auto GUID = getValueInfoFromValueId(ValueID); FS->setOriginalName(GUID.second); @@ -5354,13 +5452,25 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { uint64_t RawFlags = Record[2]; unsigned InstCount = Record[3]; uint64_t RawFunFlags = 0; + uint64_t EntryCount = 0; unsigned NumRefs = Record[4]; + unsigned NumImmutableRefs = 0; int RefListStartIndex = 5; if (Version >= 4) { RawFunFlags = Record[4]; - NumRefs = Record[5]; RefListStartIndex = 6; + size_t NumRefsIndex = 5; + if (Version >= 5) { + RefListStartIndex = 7; + if (Version >= 6) { + NumRefsIndex = 6; + EntryCount = Record[5]; + RefListStartIndex = 8; + } + NumImmutableRefs = Record[RefListStartIndex - 1]; + } + NumRefs = Record[NumRefsIndex]; } auto Flags = getDecodedGVSummaryFlags(RawFlags, Version); @@ -5374,9 +5484,10 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { ArrayRef<uint64_t>(Record).slice(CallGraphEdgeStartIndex), IsOldProfileFormat, HasProfile, false); ValueInfo VI = getValueInfoFromValueId(ValueID).first; + setImmutableRefs(Refs, NumImmutableRefs); auto FS = llvm::make_unique<FunctionSummary>( - Flags, InstCount, getDecodedFFlags(RawFunFlags), std::move(Refs), - std::move(Edges), std::move(PendingTypeTests), + Flags, InstCount, getDecodedFFlags(RawFunFlags), EntryCount, + std::move(Refs), std::move(Edges), std::move(PendingTypeTests), std::move(PendingTypeTestAssumeVCalls), std::move(PendingTypeCheckedLoadVCalls), std::move(PendingTypeTestAssumeConstVCalls), @@ -5422,10 +5533,17 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { unsigned ValueID = Record[0]; uint64_t ModuleId = Record[1]; uint64_t RawFlags = Record[2]; + unsigned RefArrayStart = 3; + GlobalVarSummary::GVarFlags GVF; auto Flags = getDecodedGVSummaryFlags(RawFlags, Version); + if (Version >= 5) { + GVF = getDecodedGVarFlags(Record[3]); + RefArrayStart = 4; + } std::vector<ValueInfo> Refs = - makeRefList(ArrayRef<uint64_t>(Record).slice(3)); - auto FS = llvm::make_unique<GlobalVarSummary>(Flags, std::move(Refs)); + makeRefList(ArrayRef<uint64_t>(Record).slice(RefArrayStart)); + auto FS = + llvm::make_unique<GlobalVarSummary>(Flags, GVF, std::move(Refs)); LastSeenSummary = FS.get(); FS->setModulePath(ModuleIdMap[ModuleId]); ValueInfo VI = getValueInfoFromValueId(ValueID).first; @@ -5811,6 +5929,46 @@ Expected<std::unique_ptr<ModuleSummaryIndex>> BitcodeModule::getSummary() { return std::move(Index); } +static Expected<bool> getEnableSplitLTOUnitFlag(BitstreamCursor &Stream, + unsigned ID) { + if (Stream.EnterSubBlock(ID)) + return error("Invalid record"); + SmallVector<uint64_t, 64> Record; + + while (true) { + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + // If no flags record found, conservatively return true to mimic + // behavior before this flag was added. + return true; + case BitstreamEntry::Record: + // The interesting case. + break; + } + + // Look for the FS_FLAGS record. + Record.clear(); + auto BitCode = Stream.readRecord(Entry.ID, Record); + switch (BitCode) { + default: // Default behavior: ignore. + break; + case bitc::FS_FLAGS: { // [flags] + uint64_t Flags = Record[0]; + // Scan flags. + assert(Flags <= 0x1f && "Unexpected bits in flag"); + + return Flags & 0x8; + } + } + } + llvm_unreachable("Exit infinite loop"); +} + // Check if the given bitcode buffer contains a global value summary block. Expected<BitcodeLTOInfo> BitcodeModule::getLTOInfo() { BitstreamCursor Stream(Buffer); @@ -5826,14 +5984,27 @@ Expected<BitcodeLTOInfo> BitcodeModule::getLTOInfo() { case BitstreamEntry::Error: return error("Malformed block"); case BitstreamEntry::EndBlock: - return BitcodeLTOInfo{/*IsThinLTO=*/false, /*HasSummary=*/false}; + return BitcodeLTOInfo{/*IsThinLTO=*/false, /*HasSummary=*/false, + /*EnableSplitLTOUnit=*/false}; case BitstreamEntry::SubBlock: - if (Entry.ID == bitc::GLOBALVAL_SUMMARY_BLOCK_ID) - return BitcodeLTOInfo{/*IsThinLTO=*/true, /*HasSummary=*/true}; + if (Entry.ID == bitc::GLOBALVAL_SUMMARY_BLOCK_ID) { + Expected<bool> EnableSplitLTOUnit = + getEnableSplitLTOUnitFlag(Stream, Entry.ID); + if (!EnableSplitLTOUnit) + return EnableSplitLTOUnit.takeError(); + return BitcodeLTOInfo{/*IsThinLTO=*/true, /*HasSummary=*/true, + *EnableSplitLTOUnit}; + } - if (Entry.ID == bitc::FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID) - return BitcodeLTOInfo{/*IsThinLTO=*/false, /*HasSummary=*/true}; + if (Entry.ID == bitc::FULL_LTO_GLOBALVAL_SUMMARY_BLOCK_ID) { + Expected<bool> EnableSplitLTOUnit = + getEnableSplitLTOUnitFlag(Stream, Entry.ID); + if (!EnableSplitLTOUnit) + return EnableSplitLTOUnit.takeError(); + return BitcodeLTOInfo{/*IsThinLTO=*/false, /*HasSummary=*/true, + *EnableSplitLTOUnit}; + } // Ignore other sub-blocks. if (Stream.SkipBlock()) diff --git a/lib/Bitcode/Reader/MetadataLoader.cpp b/lib/Bitcode/Reader/MetadataLoader.cpp index 011c41e2cecd..3289aa0acddd 100644 --- a/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/lib/Bitcode/Reader/MetadataLoader.cpp @@ -650,10 +650,6 @@ public: return MetadataList.getMetadataFwdRef(ID); } - MDNode *getMDNodeFwdRefOrNull(unsigned Idx) { - return MetadataList.getMDNodeFwdRefOrNull(Idx); - } - DISubprogram *lookupSubprogramForFunction(Function *F) { return FunctionsWithSPs.lookup(F); } @@ -772,7 +768,7 @@ MetadataLoader::MetadataLoaderImpl::lazyLoadModuleMetadataBlock() { // It is acknowledged by 'TODO: Inherit from Metadata' in the // NamedMDNode class definition. MDNode *MD = MetadataList.getMDNodeFwdRefOrNull(Record[i]); - assert(MD && "Invalid record"); + assert(MD && "Invalid metadata: expect fwd ref to MDNode"); NMD->addOperand(MD); } break; @@ -1049,7 +1045,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( for (unsigned i = 0; i != Size; ++i) { MDNode *MD = MetadataList.getMDNodeFwdRefOrNull(Record[i]); if (!MD) - return error("Invalid record"); + return error("Invalid named metadata: expect fwd ref to MDNode"); NMD->addOperand(MD); } break; @@ -1139,7 +1135,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( break; } case bitc::METADATA_LOCATION: { - if (Record.size() != 5) + if (Record.size() != 5 && Record.size() != 6) return error("Invalid record"); IsDistinct = Record[0]; @@ -1147,8 +1143,10 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( unsigned Column = Record[2]; Metadata *Scope = getMD(Record[3]); Metadata *InlinedAt = getMDOrNull(Record[4]); + bool ImplicitCode = Record.size() == 6 && Record[5]; MetadataList.assignValue( - GET_OR_DISTINCT(DILocation, (Context, Line, Column, Scope, InlinedAt)), + GET_OR_DISTINCT(DILocation, (Context, Line, Column, Scope, InlinedAt, + ImplicitCode)), NextMetadataNo); NextMetadataNo++; break; @@ -1211,14 +1209,17 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( break; } case bitc::METADATA_BASIC_TYPE: { - if (Record.size() != 6) + if (Record.size() < 6 || Record.size() > 7) return error("Invalid record"); IsDistinct = Record[0]; + DINode::DIFlags Flags = (Record.size() > 6) ? + static_cast<DINode::DIFlags>(Record[6]) : DINode::FlagZero; + MetadataList.assignValue( GET_OR_DISTINCT(DIBasicType, (Context, Record[1], getMDString(Record[2]), Record[3], - Record[4], Record[5])), + Record[4], Record[5], Flags)), NextMetadataNo); NextMetadataNo++; break; @@ -1308,7 +1309,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( (Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams, - Identifier)); + Identifier, Discriminator)); if (!IsNotUsedInTypeRef && Identifier) MetadataList.addTypeRef(*Identifier, *cast<DICompositeType>(CT)); @@ -1390,7 +1391,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( Record.size() <= 14 ? 0 : Record[14], Record.size() <= 16 ? true : Record[16], Record.size() <= 17 ? false : Record[17], - Record.size() <= 18 ? false : Record[18]); + Record.size() <= 18 ? 0 : Record[18], + Record.size() <= 19 ? 0 : Record[19]); MetadataList.assignValue(CU, NextMetadataNo); NextMetadataNo++; @@ -1404,20 +1406,43 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( if (Record.size() < 18 || Record.size() > 21) return error("Invalid record"); - IsDistinct = - (Record[0] & 1) || Record[8]; // All definitions should be distinct. + bool HasSPFlags = Record[0] & 4; + DISubprogram::DISPFlags SPFlags = + HasSPFlags + ? static_cast<DISubprogram::DISPFlags>(Record[9]) + : DISubprogram::toSPFlags( + /*IsLocalToUnit=*/Record[7], /*IsDefinition=*/Record[8], + /*IsOptimized=*/Record[14], /*Virtuality=*/Record[11]); + + // All definitions should be distinct. + IsDistinct = (Record[0] & 1) || (SPFlags & DISubprogram::SPFlagDefinition); // Version 1 has a Function as Record[15]. // Version 2 has removed Record[15]. // Version 3 has the Unit as Record[15]. // Version 4 added thisAdjustment. - bool HasUnit = Record[0] >= 2; - if (HasUnit && Record.size() < 19) + // Version 5 repacked flags into DISPFlags, changing many element numbers. + bool HasUnit = Record[0] & 2; + if (!HasSPFlags && HasUnit && Record.size() < 19) return error("Invalid record"); - Metadata *CUorFn = getMDOrNull(Record[15]); - unsigned Offset = Record.size() >= 19 ? 1 : 0; - bool HasFn = Offset && !HasUnit; - bool HasThisAdj = Record.size() >= 20; - bool HasThrownTypes = Record.size() >= 21; + if (HasSPFlags && !HasUnit) + return error("Invalid record"); + // Accommodate older formats. + bool HasFn = false; + bool HasThisAdj = true; + bool HasThrownTypes = true; + unsigned OffsetA = 0; + unsigned OffsetB = 0; + if (!HasSPFlags) { + OffsetA = 2; + OffsetB = 2; + if (Record.size() >= 19) { + HasFn = !HasUnit; + OffsetB++; + } + HasThisAdj = Record.size() >= 20; + HasThrownTypes = Record.size() >= 21; + } + Metadata *CUorFn = getMDOrNull(Record[12 + OffsetB]); DISubprogram *SP = GET_OR_DISTINCT( DISubprogram, (Context, @@ -1427,20 +1452,18 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( getMDOrNull(Record[4]), // file Record[5], // line getMDOrNull(Record[6]), // type - Record[7], // isLocal - Record[8], // isDefinition - Record[9], // scopeLine - getDITypeRefOrNull(Record[10]), // containingType - Record[11], // virtuality - Record[12], // virtualIndex - HasThisAdj ? Record[19] : 0, // thisAdjustment - static_cast<DINode::DIFlags>(Record[13]), // flags - Record[14], // isOptimized + Record[7 + OffsetA], // scopeLine + getDITypeRefOrNull(Record[8 + OffsetA]), // containingType + Record[10 + OffsetA], // virtualIndex + HasThisAdj ? Record[16 + OffsetB] : 0, // thisAdjustment + static_cast<DINode::DIFlags>(Record[11 + OffsetA]),// flags + SPFlags, // SPFlags HasUnit ? CUorFn : nullptr, // unit - getMDOrNull(Record[15 + Offset]), // templateParams - getMDOrNull(Record[16 + Offset]), // declaration - getMDOrNull(Record[17 + Offset]), // retainedNodes - HasThrownTypes ? getMDOrNull(Record[20]) : nullptr // thrownTypes + getMDOrNull(Record[13 + OffsetB]), // templateParams + getMDOrNull(Record[14 + OffsetB]), // declaration + getMDOrNull(Record[15 + OffsetB]), // retainedNodes + HasThrownTypes ? getMDOrNull(Record[17 + OffsetB]) + : nullptr // thrownTypes )); MetadataList.assignValue(SP, NextMetadataNo); NextMetadataNo++; @@ -1557,21 +1580,35 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( break; } case bitc::METADATA_GLOBAL_VAR: { - if (Record.size() < 11 || Record.size() > 12) + if (Record.size() < 11 || Record.size() > 13) return error("Invalid record"); IsDistinct = Record[0] & 1; unsigned Version = Record[0] >> 1; - if (Version == 1) { + if (Version == 2) { + MetadataList.assignValue( + GET_OR_DISTINCT( + DIGlobalVariable, + (Context, getMDOrNull(Record[1]), getMDString(Record[2]), + getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], + getDITypeRefOrNull(Record[6]), Record[7], Record[8], + getMDOrNull(Record[9]), getMDOrNull(Record[10]), Record[11])), + NextMetadataNo); + + NextMetadataNo++; + } else if (Version == 1) { + // No upgrade necessary. A null field will be introduced to indicate + // that no parameter information is available. MetadataList.assignValue( GET_OR_DISTINCT(DIGlobalVariable, (Context, getMDOrNull(Record[1]), getMDString(Record[2]), getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], getDITypeRefOrNull(Record[6]), Record[7], Record[8], - getMDOrNull(Record[10]), Record[11])), + getMDOrNull(Record[10]), nullptr, Record[11])), NextMetadataNo); + NextMetadataNo++; } else if (Version == 0) { // Upgrade old metadata, which stored a global variable reference or a @@ -1602,7 +1639,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata( (Context, getMDOrNull(Record[1]), getMDString(Record[2]), getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], getDITypeRefOrNull(Record[6]), Record[7], Record[8], - getMDOrNull(Record[10]), AlignInBits)); + getMDOrNull(Record[10]), nullptr, AlignInBits)); DIGlobalVariableExpression *DGVE = nullptr; if (Attach || Expr) @@ -1814,7 +1851,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseGlobalObjectAttachment( return error("Invalid ID"); MDNode *MD = MetadataList.getMDNodeFwdRefOrNull(Record[I + 1]); if (!MD) - return error("Invalid metadata attachment"); + return error("Invalid metadata attachment: expect fwd ref to MDNode"); GO.addMetadata(K->second, *MD); } return Error::success(); @@ -1984,10 +2021,6 @@ Metadata *MetadataLoader::getMetadataFwdRefOrLoad(unsigned Idx) { return Pimpl->getMetadataFwdRefOrLoad(Idx); } -MDNode *MetadataLoader::getMDNodeFwdRefOrNull(unsigned Idx) { - return Pimpl->getMDNodeFwdRefOrNull(Idx); -} - DISubprogram *MetadataLoader::lookupSubprogramForFunction(Function *F) { return Pimpl->lookupSubprogramForFunction(F); } diff --git a/lib/Bitcode/Reader/MetadataLoader.h b/lib/Bitcode/Reader/MetadataLoader.h index f23dcc06cc94..07a77a086f32 100644 --- a/lib/Bitcode/Reader/MetadataLoader.h +++ b/lib/Bitcode/Reader/MetadataLoader.h @@ -65,9 +65,7 @@ public: /// necessary. Metadata *getMetadataFwdRefOrLoad(unsigned Idx); - MDNode *getMDNodeFwdRefOrNull(unsigned Idx); - - /// Return the DISubprogra metadata for a Function if any, null otherwise. + /// Return the DISubprogram metadata for a Function if any, null otherwise. DISubprogram *lookupSubprogramForFunction(Function *F); /// Parse a `METADATA_ATTACHMENT` block for a function. diff --git a/lib/Bitcode/Reader/ValueList.cpp b/lib/Bitcode/Reader/ValueList.cpp index 1ab22b5cc3d1..b3945a37408f 100644 --- a/lib/Bitcode/Reader/ValueList.cpp +++ b/lib/Bitcode/Reader/ValueList.cpp @@ -144,7 +144,7 @@ Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty) { void BitcodeReaderValueList::resolveConstantForwardRefs() { // Sort the values by-pointer so that they are efficient to look up with a // binary search. - llvm::sort(ResolveConstants.begin(), ResolveConstants.end()); + llvm::sort(ResolveConstants); SmallVector<Constant *, 64> NewOps; |