summaryrefslogtreecommitdiff
path: root/lib/Bitcode/Reader
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Bitcode/Reader')
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp237
-rw-r--r--lib/Bitcode/Reader/MetadataLoader.cpp119
-rw-r--r--lib/Bitcode/Reader/MetadataLoader.h4
-rw-r--r--lib/Bitcode/Reader/ValueList.cpp2
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;