68#define DEBUG_TYPE "bitcode-reader"
70STATISTIC(NumMDStringLoaded,
"Number of MDStrings loaded");
71STATISTIC(NumMDNodeTemporary,
"Number of MDNode::Temporary created");
72STATISTIC(NumMDRecordLoaded,
"Number of Metadata records loaded");
78 cl::desc(
"Import full type definitions for ThinLTO."));
82 cl::desc(
"Force disable the lazy-loading on-demand of metadata when "
83 "loading bitcode for importing."));
87static int64_t unrotateSign(
uint64_t U) {
return (U & 1) ? ~(U >> 1) : U >> 1; }
89class BitcodeReaderMetadataList {
116 unsigned RefsUpperBound;
119 BitcodeReaderMetadataList(
LLVMContext &
C,
size_t RefsUpperBound)
125 unsigned size()
const {
return MetadataPtrs.
size(); }
126 void resize(
unsigned N) { MetadataPtrs.
resize(
N); }
130 void pop_back() { MetadataPtrs.
pop_back(); }
131 bool empty()
const {
return MetadataPtrs.
empty(); }
133 Metadata *operator[](
unsigned i)
const {
135 return MetadataPtrs[i];
139 if (
I < MetadataPtrs.
size())
140 return MetadataPtrs[
I];
144 void shrinkTo(
unsigned N) {
145 assert(
N <=
size() &&
"Invalid shrinkTo request!");
147 assert(UnresolvedNodes.
empty() &&
"Unexpected unresolved node");
161 MDNode *getMDNodeFwdRefOrNull(
unsigned Idx);
163 void tryToResolveCycles();
165 int getNextFwdRef() {
183void BitcodeReaderMetadataList::assignValue(
Metadata *MD,
unsigned Idx) {
184 if (
auto *MDN = dyn_cast<MDNode>(MD))
185 if (!MDN->isResolved())
203 TempMDTuple PrevMD(cast<MDTuple>(OldMD.
get()));
204 PrevMD->replaceAllUsesWith(MD);
208Metadata *BitcodeReaderMetadataList::getMetadataFwdRef(
unsigned Idx) {
210 if (
Idx >= RefsUpperBound)
223 ++NumMDNodeTemporary;
225 MetadataPtrs[
Idx].reset(MD);
229Metadata *BitcodeReaderMetadataList::getMetadataIfResolved(
unsigned Idx) {
231 if (
auto *
N = dyn_cast_or_null<MDNode>(MD))
232 if (!
N->isResolved())
237MDNode *BitcodeReaderMetadataList::getMDNodeFwdRefOrNull(
unsigned Idx) {
238 return dyn_cast_or_null<MDNode>(getMetadataFwdRef(
Idx));
241void BitcodeReaderMetadataList::tryToResolveCycles() {
247 for (
const auto &
Ref : OldTypeRefs.FwdDecls)
248 OldTypeRefs.Final.insert(
Ref);
249 OldTypeRefs.FwdDecls.clear();
253 for (
const auto &Array : OldTypeRefs.Arrays)
254 Array.second->replaceAllUsesWith(resolveTypeRefArray(
Array.first.get()));
255 OldTypeRefs.Arrays.clear();
260 for (
const auto &
Ref : OldTypeRefs.Unknown) {
262 Ref.second->replaceAllUsesWith(CT);
264 Ref.second->replaceAllUsesWith(
Ref.first);
266 OldTypeRefs.Unknown.clear();
268 if (UnresolvedNodes.
empty())
273 for (
unsigned I : UnresolvedNodes) {
274 auto &MD = MetadataPtrs[
I];
275 auto *
N = dyn_cast_or_null<MDNode>(MD);
279 assert(!
N->isTemporary() &&
"Unexpected forward reference");
284 UnresolvedNodes.clear();
287void BitcodeReaderMetadataList::addTypeRef(
MDString &
UUID,
291 OldTypeRefs.FwdDecls.insert(std::make_pair(&
UUID, &CT));
293 OldTypeRefs.Final.insert(std::make_pair(&
UUID, &CT));
297 auto *
UUID = dyn_cast_or_null<MDString>(MaybeUUID);
301 if (
auto *CT = OldTypeRefs.Final.lookup(
UUID))
304 auto &
Ref = OldTypeRefs.Unknown[
UUID];
310Metadata *BitcodeReaderMetadataList::upgradeTypeRefArray(
Metadata *MaybeTuple) {
311 auto *Tuple = dyn_cast_or_null<MDTuple>(MaybeTuple);
312 if (!Tuple || Tuple->isDistinct())
316 if (!Tuple->isTemporary())
317 return resolveTypeRefArray(Tuple);
321 OldTypeRefs.Arrays.emplace_back(
322 std::piecewise_construct, std::forward_as_tuple(Tuple),
324 return OldTypeRefs.Arrays.back().second.get();
327Metadata *BitcodeReaderMetadataList::resolveTypeRefArray(
Metadata *MaybeTuple) {
328 auto *Tuple = dyn_cast_or_null<MDTuple>(MaybeTuple);
329 if (!Tuple || Tuple->isDistinct())
334 Ops.
reserve(Tuple->getNumOperands());
335 for (
Metadata *MD : Tuple->operands())
343class PlaceholderQueue {
346 std::deque<DistinctMDOperandPlaceholder> PHs;
349 ~PlaceholderQueue() {
351 "PlaceholderQueue hasn't been flushed before being destroyed");
353 bool empty()
const {
return PHs.empty(); }
355 void flush(BitcodeReaderMetadataList &MetadataList);
359 void getTemporaries(BitcodeReaderMetadataList &MetadataList,
361 for (
auto &PH : PHs) {
362 auto ID = PH.getID();
363 auto *MD = MetadataList.lookup(
ID);
368 auto *
N = dyn_cast_or_null<MDNode>(MD);
369 if (
N &&
N->isTemporary())
378 PHs.emplace_back(
ID);
382void PlaceholderQueue::flush(BitcodeReaderMetadataList &MetadataList) {
383 while (!PHs.empty()) {
384 auto *MD = MetadataList.lookup(PHs.front().getID());
385 assert(MD &&
"Flushing placeholder on unassigned MD");
387 if (
auto *MDN = dyn_cast<MDNode>(MD))
388 assert(MDN->isResolved() &&
389 "Flushing Placeholder while cycles aren't resolved");
391 PHs.front().replaceUseWith(MD);
399 return make_error<StringError>(
404 BitcodeReaderMetadataList MetadataList;
417 std::vector<StringRef> MDStringRef;
424 std::vector<uint64_t> GlobalMetadataBitPosIndex;
429 uint64_t GlobalDeclAttachmentPos = 0;
434 unsigned NumGlobalDeclAttachSkipped = 0;
435 unsigned NumGlobalDeclAttachParsed = 0;
448 void lazyLoadOneMetadata(
unsigned Idx, PlaceholderQueue &Placeholders);
452 std::vector<std::pair<DICompileUnit *, Metadata *>> CUSubprograms;
461 bool StripTBAA =
false;
462 bool HasSeenOldLoopTags =
false;
463 bool NeedUpgradeToDIGlobalVariableExpression =
false;
464 bool NeedDeclareExpressionUpgrade =
false;
467 bool IsImporting =
false;
470 PlaceholderQueue &Placeholders,
StringRef Blob,
471 unsigned &NextMetadataNo);
478 void resolveForwardRefsAndPlaceholders(PlaceholderQueue &Placeholders);
481 void upgradeCUSubprograms() {
482 for (
auto CU_SP : CUSubprograms)
483 if (
auto *SPs = dyn_cast_or_null<MDTuple>(CU_SP.second))
484 for (
auto &Op : SPs->operands())
485 if (
auto *SP = dyn_cast_or_null<DISubprogram>(Op))
486 SP->replaceUnit(CU_SP.first);
487 CUSubprograms.clear();
491 void upgradeCUVariables() {
492 if (!NeedUpgradeToDIGlobalVariableExpression)
497 for (
unsigned I = 0,
E = CUNodes->getNumOperands();
I !=
E; ++
I) {
498 auto *
CU = cast<DICompileUnit>(CUNodes->getOperand(
I));
499 if (
auto *GVs = dyn_cast_or_null<MDTuple>(
CU->getRawGlobalVariables()))
500 for (
unsigned I = 0;
I < GVs->getNumOperands();
I++)
502 dyn_cast_or_null<DIGlobalVariable>(GVs->getOperand(
I))) {
505 GVs->replaceOperandWith(
I, DGVE);
510 for (
auto &GV : TheModule.
globals()) {
512 GV.getMetadata(LLVMContext::MD_dbg, MDs);
513 GV.eraseMetadata(LLVMContext::MD_dbg);
515 if (
auto *DGV = dyn_cast<DIGlobalVariable>(MD)) {
518 GV.addMetadata(LLVMContext::MD_dbg, *DGVE);
520 GV.addMetadata(LLVMContext::MD_dbg, *MD);
526 void upgradeDeclareExpressions(
Function &
F) {
527 if (!NeedDeclareExpressionUpgrade)
532 if (
auto *DDI = dyn_cast<DbgDeclareInst>(&
I))
533 if (
auto *DIExpr = DDI->getExpression())
534 if (DIExpr->startsWithDeref() &&
535 isa_and_nonnull<Argument>(DDI->getAddress())) {
537 Ops.
append(std::next(DIExpr->elements_begin()),
538 DIExpr->elements_end());
547 auto N = Expr.
size();
548 switch (FromVersion) {
550 return error(
"Invalid record");
552 if (
N >= 3 && Expr[
N - 3] == dwarf::DW_OP_bit_piece)
557 if (
N && Expr[0] == dwarf::DW_OP_deref) {
558 auto End = Expr.
end();
559 if (Expr.
size() >= 3 &&
561 End = std::prev(End, 3);
562 std::move(std::next(Expr.
begin()), End, Expr.
begin());
563 *std::prev(End) = dwarf::DW_OP_deref;
565 NeedDeclareExpressionUpgrade =
true;
571 while (!SubExpr.empty()) {
576 switch (SubExpr.front()) {
580 case dwarf::DW_OP_constu:
581 case dwarf::DW_OP_minus:
582 case dwarf::DW_OP_plus:
592 HistoricSize = std::min(SubExpr.size(), HistoricSize);
595 switch (SubExpr.front()) {
596 case dwarf::DW_OP_plus:
597 Buffer.
push_back(dwarf::DW_OP_plus_uconst);
598 Buffer.
append(Args.begin(), Args.end());
600 case dwarf::DW_OP_minus:
602 Buffer.
append(Args.begin(), Args.end());
607 Buffer.
append(Args.begin(), Args.end());
612 SubExpr = SubExpr.slice(HistoricSize);
625 void upgradeDebugInfo() {
626 upgradeCUSubprograms();
627 upgradeCUVariables();
636 : MetadataList(TheModule.getContext(), Stream.SizeInBytes()),
637 ValueList(ValueList), Stream(Stream),
Context(TheModule.getContext()),
638 TheModule(TheModule), Callbacks(
std::
move(Callbacks)),
639 IsImporting(IsImporting) {}
643 bool hasFwdRefs()
const {
return MetadataList.hasFwdRefs(); }
646 if (
ID < MDStringRef.size())
647 return lazyLoadOneMDString(
ID);
648 if (
auto *MD = MetadataList.lookup(
ID))
652 if (
ID < (MDStringRef.size() + GlobalMetadataBitPosIndex.size())) {
653 PlaceholderQueue Placeholders;
654 lazyLoadOneMetadata(
ID, Placeholders);
655 resolveForwardRefsAndPlaceholders(Placeholders);
656 return MetadataList.lookup(
ID);
658 return MetadataList.getMetadataFwdRef(
ID);
662 return FunctionsWithSPs.
lookup(
F);
675 unsigned size()
const {
return MetadataList.size(); }
681MetadataLoader::MetadataLoaderImpl::lazyLoadModuleMetadataBlock() {
682 IndexCursor = Stream;
684 GlobalDeclAttachmentPos = 0;
695 switch (Entry.Kind) {
698 return error(
"Malformed block");
713 return std::move(Err);
720 return MaybeRecord.takeError();
721 unsigned NumStrings =
Record[0];
722 MDStringRef.reserve(NumStrings);
723 auto IndexNextMDString = [&](
StringRef Str) {
724 MDStringRef.push_back(Str);
726 if (
auto Err = parseMetadataStrings(
Record, Blob, IndexNextMDString))
727 return std::move(Err);
734 return std::move(Err);
740 return MaybeRecord.takeError();
742 return error(
"Invalid record");
746 return std::move(Err);
752 Entry = MaybeEntry.
get();
754 "Corrupted bitcode: Expected `Record` when trying to find the "
760 "Corrupted bitcode: Expected `METADATA_INDEX` when trying to "
761 "find the Metadata index");
763 return MaybeCode.takeError();
765 auto CurrentValue = BeginPos;
766 GlobalMetadataBitPosIndex.reserve(
Record.size());
767 for (
auto &Elt :
Record) {
769 GlobalMetadataBitPosIndex.push_back(CurrentValue);
776 return error(
"Corrupted Metadata block");
780 return std::move(Err);
786 Code = MaybeCode.get();
789 return MaybeCode.takeError();
794 Code = MaybeCode.get();
796 return MaybeCode.takeError();
805 return MaybeNextBitCode.takeError();
810 for (
unsigned i = 0; i !=
Size; ++i) {
815 MDNode *MD = MetadataList.getMDNodeFwdRefOrNull(
Record[i]);
816 assert(MD &&
"Invalid metadata: expect fwd ref to MDNode");
822 if (!GlobalDeclAttachmentPos)
823 GlobalDeclAttachmentPos = SavedPos;
825 NumGlobalDeclAttachSkipped++;
869 GlobalMetadataBitPosIndex.clear();
883Expected<bool> MetadataLoader::MetadataLoaderImpl::loadGlobalDeclAttachments() {
885 if (!GlobalDeclAttachmentPos)
894 return std::move(Err);
903 switch (Entry.Kind) {
906 return error(
"Malformed block");
909 assert(NumGlobalDeclAttachSkipped == NumGlobalDeclAttachParsed);
921 assert(NumGlobalDeclAttachSkipped == NumGlobalDeclAttachParsed);
925 NumGlobalDeclAttachParsed++;
930 return std::move(Err);
936 return MaybeRecord.takeError();
937 if (
Record.size() % 2 == 0)
938 return error(
"Invalid record");
939 unsigned ValueID =
Record[0];
940 if (ValueID >= ValueList.size())
941 return error(
"Invalid record");
942 if (
auto *GO = dyn_cast<GlobalObject>(ValueList[ValueID])) {
947 if (
Error Err = parseGlobalObjectAttachment(
949 return std::move(Err);
951 return std::move(Err);
956void MetadataLoader::MetadataLoaderImpl::callMDTypeCallback(
Metadata **Val,
958 if (Callbacks.MDType) {
959 (*Callbacks.MDType)(Val,
TypeID, Callbacks.GetTypeByID,
960 Callbacks.GetContainedTypeID);
967 if (!ModuleLevel && MetadataList.hasFwdRefs())
968 return error(
"Invalid metadata: fwd refs into function blocks");
972 auto EntryPos = Stream.GetCurrentBitNo();
978 PlaceholderQueue Placeholders;
982 if (ModuleLevel && IsImporting && MetadataList.empty() &&
984 auto SuccessOrErr = lazyLoadModuleMetadataBlock();
986 return SuccessOrErr.takeError();
987 if (SuccessOrErr.get()) {
990 MetadataList.resize(MDStringRef.size() +
991 GlobalMetadataBitPosIndex.size());
996 SuccessOrErr = loadGlobalDeclAttachments();
998 return SuccessOrErr.takeError();
999 assert(SuccessOrErr.get());
1003 resolveForwardRefsAndPlaceholders(Placeholders);
1007 Stream.ReadBlockEnd();
1008 if (
Error Err = IndexCursor.JumpToBit(EntryPos))
1010 if (
Error Err = Stream.SkipBlock()) {
1021 unsigned NextMetadataNo = MetadataList.size();
1026 if (
Error E = Stream.advanceSkippingSubblocks().moveInto(Entry))
1029 switch (Entry.Kind) {
1032 return error(
"Malformed block");
1034 resolveForwardRefsAndPlaceholders(Placeholders);
1045 ++NumMDRecordLoaded;
1047 Stream.readRecord(Entry.ID,
Record, &Blob)) {
1048 if (
Error Err = parseOneMetadata(
Record, MaybeCode.
get(), Placeholders,
1049 Blob, NextMetadataNo))
1056MDString *MetadataLoader::MetadataLoaderImpl::lazyLoadOneMDString(
unsigned ID) {
1057 ++NumMDStringLoaded;
1059 return cast<MDString>(MD);
1061 MetadataList.assignValue(MDS,
ID);
1065void MetadataLoader::MetadataLoaderImpl::lazyLoadOneMetadata(
1066 unsigned ID, PlaceholderQueue &Placeholders) {
1067 assert(
ID < (MDStringRef.size()) + GlobalMetadataBitPosIndex.size());
1068 assert(
ID >= MDStringRef.size() &&
"Unexpected lazy-loading of MDString");
1070 if (
auto *MD = MetadataList.lookup(
ID)) {
1071 auto *
N = cast<MDNode>(MD);
1072 if (!
N->isTemporary())
1077 if (
Error Err = IndexCursor.JumpToBit(
1078 GlobalMetadataBitPosIndex[
ID - MDStringRef.size()]))
1082 if (
Error E = IndexCursor.advanceSkippingSubblocks().moveInto(Entry))
1086 ++NumMDRecordLoaded;
1088 IndexCursor.readRecord(Entry.ID,
Record, &Blob)) {
1090 parseOneMetadata(
Record, MaybeCode.
get(), Placeholders, Blob,
ID))
1100void MetadataLoader::MetadataLoaderImpl::resolveForwardRefsAndPlaceholders(
1101 PlaceholderQueue &Placeholders) {
1105 Placeholders.getTemporaries(MetadataList, Temporaries);
1108 if (Temporaries.
empty() && !MetadataList.hasFwdRefs())
1113 for (
auto ID : Temporaries)
1114 lazyLoadOneMetadata(
ID, Placeholders);
1115 Temporaries.clear();
1119 while (MetadataList.hasFwdRefs())
1120 lazyLoadOneMetadata(MetadataList.getNextFwdRef(), Placeholders);
1125 MetadataList.tryToResolveCycles();
1129 Placeholders.flush(MetadataList);
1132Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
1134 PlaceholderQueue &Placeholders,
StringRef Blob,
unsigned &NextMetadataNo) {
1136 bool IsDistinct =
false;
1137 auto getMD = [&](
unsigned ID) ->
Metadata * {
1138 if (
ID < MDStringRef.size())
1139 return lazyLoadOneMDString(
ID);
1141 if (
auto *MD = MetadataList.lookup(
ID))
1145 if (
ID < (MDStringRef.size() + GlobalMetadataBitPosIndex.size())) {
1149 MetadataList.getMetadataFwdRef(NextMetadataNo);
1150 lazyLoadOneMetadata(
ID, Placeholders);
1151 return MetadataList.lookup(
ID);
1154 return MetadataList.getMetadataFwdRef(
ID);
1156 if (
auto *MD = MetadataList.getMetadataIfResolved(
ID))
1158 return &Placeholders.getPlaceholderOp(
ID);
1160 auto getMDOrNull = [&](
unsigned ID) ->
Metadata * {
1162 return getMD(
ID - 1);
1165 auto getMDOrNullWithoutPlaceholders = [&](
unsigned ID) ->
Metadata * {
1167 return MetadataList.getMetadataFwdRef(
ID - 1);
1170 auto getMDString = [&](
unsigned ID) ->
MDString * {
1173 auto MDS = getMDOrNull(
ID);
1174 return cast_or_null<MDString>(MDS);
1178 auto getDITypeRefOrNull = [&](
unsigned ID) {
1179 return MetadataList.upgradeTypeRef(getMDOrNull(
ID));
1182#define GET_OR_DISTINCT(CLASS, ARGS) \
1183 (IsDistinct ? CLASS::getDistinct ARGS : CLASS::get ARGS)
1192 if (
Error E = Stream.ReadCode().moveInto(Code))
1195 ++NumMDRecordLoaded;
1198 return error(
"METADATA_NAME not followed by METADATA_NAMED_NODE");
1200 return MaybeNextBitCode.takeError();
1205 for (
unsigned i = 0; i !=
Size; ++i) {
1206 MDNode *MD = MetadataList.getMDNodeFwdRefOrNull(
Record[i]);
1208 return error(
"Invalid named metadata: expect fwd ref to MDNode");
1217 if (
Record.size() % 2 == 1)
1218 return error(
"Invalid record");
1222 auto dropRecord = [&] {
1223 MetadataList.assignValue(
MDNode::get(Context, std::nullopt),
1227 if (
Record.size() != 2) {
1232 unsigned TyID =
Record[0];
1233 Type *Ty = Callbacks.GetTypeByID(TyID);
1239 Value *V = ValueList.getValueFwdRef(
Record[1], Ty, TyID,
1242 return error(
"Invalid value reference from old fn metadata");
1250 if (
Record.size() % 2 == 1)
1251 return error(
"Invalid record");
1255 for (
unsigned i = 0; i !=
Size; i += 2) {
1256 unsigned TyID =
Record[i];
1257 Type *Ty = Callbacks.GetTypeByID(TyID);
1259 return error(
"Invalid record");
1263 Value *V = ValueList.getValueFwdRef(
Record[i + 1], Ty, TyID,
1266 return error(
"Invalid value reference from old metadata");
1268 assert(isa<ConstantAsMetadata>(MD) &&
1269 "Expected non-function-local metadata");
1270 callMDTypeCallback(&MD, TyID);
1275 MetadataList.assignValue(
MDNode::get(Context, Elts), NextMetadataNo);
1281 return error(
"Invalid record");
1283 unsigned TyID =
Record[0];
1284 Type *Ty = Callbacks.GetTypeByID(TyID);
1286 return error(
"Invalid record");
1288 Value *V = ValueList.getValueFwdRef(
Record[1], Ty, TyID,
1291 return error(
"Invalid value reference from metadata");
1294 callMDTypeCallback(&MD, TyID);
1295 MetadataList.assignValue(MD, NextMetadataNo);
1315 return error(
"Invalid record");
1319 unsigned Column =
Record[2];
1323 MetadataList.assignValue(
1332 return error(
"Invalid record");
1338 if (
Tag >= 1u << 16 || Version != 0)
1339 return error(
"Invalid record");
1341 auto *Header = getMDString(
Record[3]);
1343 for (
unsigned I = 4,
E =
Record.size();
I !=
E; ++
I)
1345 MetadataList.assignValue(
1361 switch (
Record[0] >> 1) {
1368 unrotateSign(
Record[2])));
1376 return error(
"Invalid record: Unsupported version of DISubrange");
1379 MetadataList.assignValue(Val, NextMetadataNo);
1380 IsDistinct =
Record[0] & 1;
1387 (Context, getMDOrNull(
Record[1]),
1389 getMDOrNull(
Record[4])));
1391 MetadataList.assignValue(Val, NextMetadataNo);
1392 IsDistinct =
Record[0] & 1;
1398 return error(
"Invalid record");
1400 IsDistinct =
Record[0] & 1;
1401 bool IsUnsigned =
Record[0] & 2;
1402 bool IsBigInt =
Record[0] & 4;
1407 const size_t NumWords =
Record.size() - 3;
1412 MetadataList.assignValue(
1414 (Context,
Value, IsUnsigned, getMDString(
Record[2]))),
1421 return error(
"Invalid record");
1428 MetadataList.assignValue(
1438 return error(
"Invalid record");
1441 bool SizeIs8 =
Record.size() == 8;
1444 Metadata *StringLocationExp = SizeIs8 ? nullptr : getMDOrNull(
Record[5]);
1445 unsigned Offset = SizeIs8 ? 5 : 6;
1446 MetadataList.assignValue(
1458 return error(
"Invalid record");
1462 std::optional<unsigned> DWARFAddressSpace;
1464 DWARFAddressSpace =
Record[12] - 1;
1472 MetadataList.assignValue(
1476 getDITypeRefOrNull(
Record[5]),
1478 Record[9], DWARFAddressSpace, Flags,
1486 return error(
"Invalid record");
1490 IsDistinct =
Record[0] & 0x1;
1491 bool IsNotUsedInTypeRef =
Record[0] >= 2;
1500 return error(
"Alignment value is too large");
1505 unsigned RuntimeLang =
Record[12];
1507 Metadata *TemplateParams =
nullptr;
1523 (
Tag == dwarf::DW_TAG_enumeration_type ||
1524 Tag == dwarf::DW_TAG_class_type ||
1525 Tag == dwarf::DW_TAG_structure_type ||
1526 Tag == dwarf::DW_TAG_union_type)) {
1535 TemplateParams = getMDOrNull(
Record[14]);
1539 OffsetInBits =
Record[9];
1541 VTableHolder = getDITypeRefOrNull(
Record[13]);
1542 TemplateParams = getMDOrNull(
Record[14]);
1546 DataLocation = getMDOrNull(
Record[17]);
1547 if (
Record.size() > 19) {
1548 Associated = getMDOrNull(
Record[18]);
1549 Allocated = getMDOrNull(
Record[19]);
1551 if (
Record.size() > 20) {
1552 Rank = getMDOrNull(
Record[20]);
1554 if (
Record.size() > 21) {
1562 SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
1563 VTableHolder, TemplateParams, Discriminator, DataLocation, Associated,
1570 SizeInBits, AlignInBits, OffsetInBits, Flags,
1571 Elements, RuntimeLang, VTableHolder, TemplateParams,
1572 Identifier, Discriminator, DataLocation, Associated,
1574 if (!IsNotUsedInTypeRef && Identifier)
1575 MetadataList.addTypeRef(*Identifier, *cast<DICompositeType>(CT));
1577 MetadataList.assignValue(CT, NextMetadataNo);
1583 return error(
"Invalid record");
1584 bool IsOldTypeRefArray =
Record[0] < 2;
1587 IsDistinct =
Record[0] & 0x1;
1591 Types = MetadataList.upgradeTypeRefArray(Types);
1593 MetadataList.assignValue(
1602 return error(
"Invalid record");
1606 MetadataList.assignValue(
1609 (Context,
Record.size() >= 8 ? getMDOrNull(
Record[1]) :
nullptr,
1622 return error(
"Invalid record");
1625 std::optional<DIFile::ChecksumInfo<MDString *>> Checksum;
1634 MetadataList.assignValue(
1636 (Context, getMDString(
Record[1]),
1637 getMDString(
Record[2]), Checksum,
1638 Record.size() > 5 ? getMDString(
Record[5]) :
nullptr)),
1645 return error(
"Invalid record");
1655 Record.size() <= 15 ?
nullptr : getMDOrNull(
Record[15]),
1661 Record.size() <= 20 ?
nullptr : getMDString(
Record[20]),
1662 Record.size() <= 21 ?
nullptr : getMDString(
Record[21]));
1664 MetadataList.assignValue(
CU, NextMetadataNo);
1669 CUSubprograms.push_back({
CU, SPs});
1674 return error(
"Invalid record");
1676 bool HasSPFlags =
Record[0] & 4;
1689 const unsigned DIFlagMainSubprogram = 1 << 21;
1690 bool HasOldMainSubprogramFlag =
Flags & DIFlagMainSubprogram;
1691 if (HasOldMainSubprogramFlag)
1695 Flags &= ~static_cast<DINode::DIFlags>(DIFlagMainSubprogram);
1697 if (HasOldMainSubprogramFlag && HasSPFlags)
1698 SPFlags |= DISubprogram::SPFlagMainSubprogram;
1699 else if (!HasSPFlags)
1703 HasOldMainSubprogramFlag);
1706 IsDistinct = (
Record[0] & 1) || (SPFlags & DISubprogram::SPFlagDefinition);
1712 bool HasUnit =
Record[0] & 2;
1713 if (!HasSPFlags && HasUnit &&
Record.size() < 19)
1714 return error(
"Invalid record");
1715 if (HasSPFlags && !HasUnit)
1716 return error(
"Invalid record");
1719 bool HasThisAdj =
true;
1720 bool HasThrownTypes =
true;
1721 bool HasAnnotations =
false;
1722 bool HasTargetFuncName =
false;
1723 unsigned OffsetA = 0;
1724 unsigned OffsetB = 0;
1728 if (
Record.size() >= 19) {
1732 HasThisAdj =
Record.size() >= 20;
1733 HasThrownTypes =
Record.size() >= 21;
1735 HasAnnotations =
Record.size() >= 19;
1736 HasTargetFuncName =
Record.size() >= 20;
1742 getDITypeRefOrNull(
Record[1]),
1749 getDITypeRefOrNull(
Record[8 + OffsetA]),
1751 HasThisAdj ?
Record[16 + OffsetB] : 0,
1754 HasUnit ? CUorFn :
nullptr,
1755 getMDOrNull(
Record[13 + OffsetB]),
1756 getMDOrNull(
Record[14 + OffsetB]),
1757 getMDOrNull(
Record[15 + OffsetB]),
1758 HasThrownTypes ? getMDOrNull(
Record[17 + OffsetB])
1760 HasAnnotations ? getMDOrNull(
Record[18 + OffsetB])
1762 HasTargetFuncName ? getMDString(
Record[19 + OffsetB])
1765 MetadataList.assignValue(SP, NextMetadataNo);
1770 if (
auto *CMD = dyn_cast_or_null<ConstantAsMetadata>(CUorFn))
1771 if (
auto *
F = dyn_cast<Function>(CMD->getValue())) {
1772 if (
F->isMaterializable())
1775 FunctionsWithSPs[
F] = SP;
1776 else if (!
F->empty())
1777 F->setSubprogram(SP);
1784 return error(
"Invalid record");
1787 MetadataList.assignValue(
1789 (Context, getMDOrNull(
Record[1]),
1797 return error(
"Invalid record");
1800 MetadataList.assignValue(
1802 (Context, getMDOrNull(
Record[1]),
1809 IsDistinct =
Record[0] & 1;
1810 MetadataList.assignValue(
1812 (Context, getMDOrNull(
Record[1]),
1824 else if (
Record.size() == 5)
1827 return error(
"Invalid record");
1829 IsDistinct =
Record[0] & 1;
1830 bool ExportSymbols =
Record[0] & 2;
1831 MetadataList.assignValue(
1833 (Context, getMDOrNull(
Record[1]),
Name, ExportSymbols)),
1840 return error(
"Invalid record");
1843 MetadataList.assignValue(
1846 getMDString(
Record[4]))),
1853 return error(
"Invalid record");
1856 MetadataList.assignValue(
1859 getMDOrNull(
Record[4]))),
1866 return error(
"Invalid record");
1869 MetadataList.assignValue(
1871 (Context, getMDString(
Record[1]),
1872 getDITypeRefOrNull(
Record[2]),
1874 : getMDOrNull(
false))),
1881 return error(
"Invalid record");
1885 MetadataList.assignValue(
1889 getDITypeRefOrNull(
Record[3]),
1890 (
Record.size() == 6) ? getMDOrNull(
Record[4]) : getMDOrNull(
false),
1892 : getMDOrNull(
Record[4]))),
1899 return error(
"Invalid record");
1901 IsDistinct =
Record[0] & 1;
1909 MetadataList.assignValue(
1911 (Context, getMDOrNull(
Record[1]),
1920 }
else if (Version == 1) {
1923 MetadataList.assignValue(
1926 (Context, getMDOrNull(
Record[1]), getMDString(
Record[2]),
1929 getMDOrNull(
Record[10]),
nullptr,
Record[11],
nullptr)),
1933 }
else if (Version == 0) {
1936 NeedUpgradeToDIGlobalVariableExpression =
true;
1939 if (
Record.size() > 11) {
1941 return error(
"Alignment value is too large");
1942 AlignInBits =
Record[11];
1945 if (
auto *CMD = dyn_cast_or_null<ConstantAsMetadata>(Expr)) {
1946 if (
auto *GV = dyn_cast<GlobalVariable>(CMD->getValue())) {
1949 }
else if (
auto *CI = dyn_cast<ConstantInt>(CMD->getValue())) {
1951 {dwarf::DW_OP_constu, CI->getZExtValue(),
1952 dwarf::DW_OP_stack_value});
1959 (Context, getMDOrNull(
Record[1]), getMDString(
Record[2]),
1962 getMDOrNull(
Record[10]),
nullptr, AlignInBits,
nullptr));
1972 MetadataList.assignValue(
MDNode, NextMetadataNo);
1975 return error(
"Invalid record");
1981 return error(
"Invalid DIAssignID record.");
1983 IsDistinct =
Record[0] & 1;
1985 return error(
"Invalid DIAssignID record. Must be distinct");
1994 return error(
"Invalid record");
1996 IsDistinct =
Record[0] & 1;
1997 bool HasAlignment =
Record[0] & 2;
2001 bool HasTag = !HasAlignment &&
Record.size() > 8;
2007 return error(
"Alignment value is too large");
2013 MetadataList.assignValue(
2015 (Context, getMDOrNull(
Record[1 + HasTag]),
2016 getMDString(
Record[2 + HasTag]),
2018 getDITypeRefOrNull(
Record[5 + HasTag]),
2026 return error(
"Invalid record");
2028 IsDistinct =
Record[0] & 1;
2029 MetadataList.assignValue(
2039 return error(
"Invalid record");
2041 IsDistinct =
Record[0] & 1;
2046 if (
Error Err = upgradeDIExpression(Version, Elts, Buffer))
2056 return error(
"Invalid record");
2062 MetadataList.assignValue(
2064 (Context, getMDOrNull(
Record[1]), Expr)),
2071 return error(
"Invalid record");
2074 MetadataList.assignValue(
2076 (Context, getMDString(
Record[1]),
2086 return error(
"Invalid DIImportedEntity record");
2089 bool HasFile = (
Record.size() >= 7);
2090 bool HasElements = (
Record.size() >= 8);
2091 MetadataList.assignValue(
2094 getDITypeRefOrNull(
Record[3]),
2095 HasFile ? getMDOrNull(
Record[6]) :
nullptr,
2097 HasElements ? getMDOrNull(
Record[7]) :
nullptr)),
2107 ++NumMDStringLoaded;
2109 MetadataList.assignValue(MD, NextMetadataNo);
2114 auto CreateNextMDString = [&](
StringRef Str) {
2115 ++NumMDStringLoaded;
2116 MetadataList.assignValue(
MDString::get(Context, Str), NextMetadataNo);
2119 if (
Error Err = parseMetadataStrings(
Record, Blob, CreateNextMDString))
2124 if (
Record.size() % 2 == 0)
2125 return error(
"Invalid record");
2126 unsigned ValueID =
Record[0];
2127 if (ValueID >= ValueList.size())
2128 return error(
"Invalid record");
2129 if (
auto *GO = dyn_cast<GlobalObject>(ValueList[ValueID]))
2130 if (
Error Err = parseGlobalObjectAttachment(
2147 if (isa<MDNode>(MD) && cast<MDNode>(MD)->isTemporary())
2149 "Invalid record: DIArgList should not contain forward refs");
2150 if (!isa<ValueAsMetadata>(MD))
2151 return error(
"Invalid record");
2152 Elts.
push_back(cast<ValueAsMetadata>(MD));
2155 MetadataList.assignValue(
DIArgList::get(Context, Elts), NextMetadataNo);
2161#undef GET_OR_DISTINCT
2164Error MetadataLoader::MetadataLoaderImpl::parseMetadataStrings(
2171 return error(
"Invalid record: metadata strings layout");
2173 unsigned NumStrings =
Record[0];
2174 unsigned StringsOffset =
Record[1];
2176 return error(
"Invalid record: metadata strings with no strings");
2177 if (StringsOffset > Blob.
size())
2178 return error(
"Invalid record: metadata strings corrupt offset");
2185 if (
R.AtEndOfStream())
2186 return error(
"Invalid record: metadata strings bad length");
2191 if (Strings.size() <
Size)
2192 return error(
"Invalid record: metadata strings truncated chars");
2194 CallBack(Strings.slice(0,
Size));
2195 Strings = Strings.drop_front(
Size);
2196 }
while (--NumStrings);
2201Error MetadataLoader::MetadataLoaderImpl::parseGlobalObjectAttachment(
2204 for (
unsigned I = 0,
E =
Record.size();
I !=
E;
I += 2) {
2205 auto K = MDKindMap.find(
Record[
I]);
2206 if (K == MDKindMap.end())
2207 return error(
"Invalid ID");
2211 return error(
"Invalid metadata attachment: expect fwd ref to MDNode");
2224 PlaceholderQueue Placeholders;
2228 if (
Error E = Stream.advanceSkippingSubblocks().moveInto(Entry))
2231 switch (Entry.Kind) {
2234 return error(
"Malformed block");
2236 resolveForwardRefsAndPlaceholders(Placeholders);
2245 ++NumMDRecordLoaded;
2249 switch (MaybeRecord.
get()) {
2253 unsigned RecordLength =
Record.size();
2255 return error(
"Invalid record");
2256 if (RecordLength % 2 == 0) {
2258 if (
Error Err = parseGlobalObjectAttachment(
F,
Record))
2265 for (
unsigned i = 1; i != RecordLength; i = i + 2) {
2266 unsigned Kind =
Record[i];
2268 if (
I == MDKindMap.end())
2269 return error(
"Invalid ID");
2270 if (
I->second == LLVMContext::MD_tbaa && StripTBAA)
2274 if (
Idx < (MDStringRef.size() + GlobalMetadataBitPosIndex.size()) &&
2275 !MetadataList.lookup(
Idx)) {
2278 lazyLoadOneMetadata(
Idx, Placeholders);
2279 resolveForwardRefsAndPlaceholders(Placeholders);
2282 Metadata *Node = MetadataList.getMetadataFwdRef(
Idx);
2283 if (isa<LocalAsMetadata>(Node))
2287 MDNode *MD = dyn_cast_or_null<MDNode>(Node);
2289 return error(
"Invalid metadata attachment");
2291 if (HasSeenOldLoopTags &&
I->second == LLVMContext::MD_loop)
2294 if (
I->second == LLVMContext::MD_tbaa) {
2307Error MetadataLoader::MetadataLoaderImpl::parseMetadataKindRecord(
2310 return error(
"Invalid record");
2312 unsigned Kind =
Record[0];
2315 unsigned NewKind = TheModule.getMDKindID(
Name.str());
2316 if (!MDKindMap.insert(std::make_pair(Kind, NewKind)).second)
2317 return error(
"Conflicting METADATA_KIND records");
2331 if (
Error E = Stream.advanceSkippingSubblocks().moveInto(Entry))
2334 switch (Entry.Kind) {
2337 return error(
"Malformed block");
2347 ++NumMDRecordLoaded;
2351 switch (MaybeCode.
get()) {
2364 Pimpl = std::move(
RHS.Pimpl);
2376 Stream, TheModule, ValueList,
std::
move(Callbacks), IsImporting)) {}
2378Error MetadataLoader::parseMetadata(
bool ModuleLevel) {
2379 return Pimpl->parseMetadata(ModuleLevel);
2387 return Pimpl->getMetadataFwdRefOrLoad(
Idx);
2391 return Pimpl->lookupSubprogramForFunction(
F);
2396 return Pimpl->parseMetadataAttachment(
F, InstructionList);
2400 return Pimpl->parseMetadataKinds();
2404 return Pimpl->setStripTBAA(StripTBAA);
2413 return Pimpl->upgradeDebugIntrinsics(
F);
This file implements a class to represent arbitrary precision integral constant values and operations...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_UNLIKELY(EXPR)
#define LLVM_LIKELY(EXPR)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static void clear(coro::Shape &Shape)
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
This file contains constants used for implementing Dwarf debug support.
static bool lookup(const GsymReader &GR, DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr, uint64_t Addr, SourceLocations &SrcLocs, llvm::Error &Err)
A Lookup helper functions.
#define GET_OR_DISTINCT(CLASS, ARGS)
Module.h This file contains the declarations for the Module class.
return ToRemove size() > 0
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallString class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
std::pair< llvm::MachO::Target, std::string > UUID
Class for arbitrary precision integers.
Annotations lets you mark points and ranges inside source code, for tests:
This class represents an incoming formal argument to a Function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
This represents a position within a bitcode file, implemented on top of a SimpleBitstreamCursor.
Error JumpToBit(uint64_t BitNo)
Reset the stream to the specified bit number.
uint64_t GetCurrentBitNo() const
Return the bit # of the bit we are reading.
Expected< BitstreamEntry > advanceSkippingSubblocks(unsigned Flags=0)
This is a convenience function for clients that don't expect any subblocks.
Expected< unsigned > readRecord(unsigned AbbrevID, SmallVectorImpl< uint64_t > &Vals, StringRef *Blob=nullptr)
Expected< unsigned > skipRecord(unsigned AbbrevID)
Read the current record and discard it, returning the code for the record.
Expected< unsigned > ReadCode()
@ AF_DontPopBlockAtEnd
If this flag is used, the advance() method does not automatically pop the block scope when the end of...
static DIAssignID * getDistinct(LLVMContext &Context)
Basic type, like 'int' or 'float'.
static DICompositeType * buildODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator, Metadata *DataLocation, Metadata *Associated, Metadata *Allocated, Metadata *Rank, Metadata *Annotations)
Build a DICompositeType with the given ODR identifier.
MDString * getRawIdentifier() const
ChecksumKind
Which algorithm (e.g.
A pair of DIGlobalVariable and DIExpression.
An imported module (C++ using directive or similar).
Represents a module in the programming language, for example, a Clang module, or a Fortran module.
String type, Fortran CHARACTER(n)
static DISPFlags toSPFlags(bool IsLocalToUnit, bool IsDefinition, bool IsOptimized, unsigned Virtuality=SPFlagNonvirtual, bool IsMainSubprogram=false)
DISPFlags
Debug info subprogram flags.
Type array for a subprogram.
bool isForwardDecl() const
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Implements a dense probed hash-table based set.
Placeholder metadata for operands of distinct MDNodes.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
reference get()
Returns a reference to the stored T value.
Generic tagged DWARF-like metadata node.
void addMetadata(unsigned KindID, MDNode &MD)
Add a metadata attachment.
void addDebugInfo(DIGlobalVariableExpression *GV)
Attach a DIGlobalVariableExpression.
void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
This is an important class for using LLVM in a threaded context.
static MDTuple * getDistinct(LLVMContext &Context, ArrayRef< Metadata * > MDs)
static TempMDTuple getTemporary(LLVMContext &Context, ArrayRef< Metadata * > MDs)
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
static MDString * get(LLVMContext &Context, StringRef Str)
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
static TempMDTuple getTemporary(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Return a temporary node.
A Module instance is used to store all the information related to an LLVM module.
NamedMDNode * getNamedMetadata(const Twine &Name) const
Return the first NamedMDNode in the module with the specified name.
iterator_range< global_iterator > globals()
NamedMDNode * getOrInsertNamedMetadata(StringRef Name)
Return the named MDNode in the module with the specified name.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
MutableArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
void addOperand(MDNode *M)
This represents a position within a bitstream.
Implements a dense probed hash-table based set with some number of buckets stored inline.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
size - Get the string size.
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
bool startswith(StringRef Prefix) const
Tracking metadata reference.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
TypeID
Definitions of all of the base types for the Type system.
bool isVoidTy() const
Return true if this is 'void'.
bool isMetadataTy() const
Return true if this is 'metadata'.
LLVM Value Representation.
std::pair< iterator, bool > insert(const ValueT &V)
An efficient, type-erasing, non-owning reference to a callable.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ METADATA_TEMPLATE_VALUE
@ METADATA_LEXICAL_BLOCK_FILE
@ METADATA_SUBROUTINE_TYPE
@ METADATA_GLOBAL_DECL_ATTACHMENT
@ METADATA_IMPORTED_ENTITY
@ METADATA_GENERIC_SUBRANGE
@ METADATA_COMPOSITE_TYPE
@ METADATA_GLOBAL_VAR_EXPR
initializer< Ty > init(const Ty &Val)
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
@ DW_OP_LLVM_fragment
Only used in LLVM metadata.
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
This is an optimization pass for GlobalISel generic memory operations.
std::error_code make_error_code(BitcodeError E)
MDNode * upgradeInstructionLoopAttachment(MDNode &N)
Upgrade the loop attachment metadata node.
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
bool mayBeOldLoopAttachmentTag(StringRef Name)
Check whether a string looks like an old loop attachment tag.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
@ Ref
The access may reference the value stored in memory.
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
constexpr unsigned BitWidth
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
APInt readWideAPInt(ArrayRef< uint64_t > Vals, unsigned TypeBits)
MDNode * UpgradeTBAANode(MDNode &TBAANode)
If the given TBAA tag uses the scalar TBAA format, create a new node corresponding to the upgrade to ...
void consumeError(Error Err)
Consume a Error without doing anything.
When advancing through a bitstream cursor, each advance can discover a few different kinds of entries...