Revert D87970 "[ThinLTO] Avoid temporaries when loading global decl attachment metadata"
This reverts commit ab1b4810b5.
It caused an issue in llvm::lto::thinBackend for a -fsanitize=cfi build.
```
AbbrevNo is 0 => "Invalid abbrev number"
0 llvm::BitstreamCursor::getAbbrev (this=0x9db4c8, AbbrevID=4) at llvm/include/llvm/Bitstream/BitstreamReader.h:528
1 0x00007f5f777a6eb4 in llvm::BitstreamCursor::readRecord (this=0x9db4c8, AbbrevID=4, Vals=llvm::SmallVector of Size 0, Capacity 64, Blob=0x7ffcd0e26558) at
usr/local/google/home/maskray/llvm/llvm/lib/Bitstream/Reader/BitstreamReader.cpp:228
2 0x00007f5f796bf633 in llvm::MetadataLoader::MetadataLoaderImpl::lazyLoadOneMetadata (this=0x9db3a0, ID=188, Placeholders=...) at /usr/local/google/home/mas
ray/llvm/llvm/lib/Bitcode/Reader/MetadataLoader.cpp:1091
3 0x00007f5f796c2527 in llvm::MetadataLoader::MetadataLoaderImpl::getMetadataFwdRefOrLoad (this=0x9db3a0, ID=188) at llvm
lib/Bitcode/Reader/MetadataLoader.cpp:668
4 0x00007f5f796bfff3 in llvm::MetadataLoader::getMetadataFwdRefOrLoad (this=0xd31580, Idx=188) at llvm/lib/Bitcode/Reader
MetadataLoader.cpp:2290
5 0x00007f5f79638265 in (anonymous namespace)::BitcodeReader::parseFunctionBody (this=0xd312e0, F=0x9de758) at llvm/lib/B
tcode/Reader/BitcodeReader.cpp:3938
6 0x00007f5f79635d32 in (anonymous namespace)::BitcodeReader::materialize (this=0xd312e0, GV=0x9de758) at llvm/lib/Bitcod
/Reader/BitcodeReader.cpp:5408
7 0x00007f5f7f8dbe3e in llvm::Module::materialize (this=0x9b92c0, GV=0x9de758) at llvm/lib/IR/Module.cpp:442
8 0x00007f5f7f7f8fbe in llvm::GlobalValue::materialize (this=0x9de758) at llvm/lib/IR/Globals.cpp:50
9 0x00007f5f83b9b5f5 in llvm::FunctionImporter::importFunctions (this=0x7ffcd0e2a730, DestModule=..., ImportList=...) at
llvm/lib/Transforms/IPO/FunctionImport.cpp:1182
```
This commit is contained in:
@@ -438,20 +438,6 @@ class MetadataLoader::MetadataLoaderImpl {
|
||||
/// Index that keeps track of where to find a metadata record in the stream.
|
||||
std::vector<uint64_t> GlobalMetadataBitPosIndex;
|
||||
|
||||
/// Cursor position of the start of the global decl attachments, to enable
|
||||
/// loading using the index built for lazy loading, instead of forward
|
||||
/// references.
|
||||
uint64_t GlobalDeclAttachmentPos = 0;
|
||||
|
||||
#ifndef NDEBUG
|
||||
/// Sanity check that we end up parsing all of the global decl attachments.
|
||||
unsigned NumGlobalDeclAttachSkipped = 0;
|
||||
unsigned NumGlobalDeclAttachParsed = 0;
|
||||
#endif
|
||||
|
||||
/// Load the global decl attachments, using the index built for lazy loading.
|
||||
Expected<bool> loadGlobalDeclAttachments();
|
||||
|
||||
/// Populate the index above to enable lazily loading of metadata, and load
|
||||
/// the named metadata as well as the transitively referenced global
|
||||
/// Metadata.
|
||||
@@ -695,10 +681,8 @@ Expected<bool>
|
||||
MetadataLoader::MetadataLoaderImpl::lazyLoadModuleMetadataBlock() {
|
||||
IndexCursor = Stream;
|
||||
SmallVector<uint64_t, 64> Record;
|
||||
GlobalDeclAttachmentPos = 0;
|
||||
// Get the abbrevs, and preload record positions to make them lazy-loadable.
|
||||
while (true) {
|
||||
uint64_t SavedPos = IndexCursor.GetCurrentBitNo();
|
||||
Expected<BitstreamEntry> MaybeEntry = IndexCursor.advanceSkippingSubblocks(
|
||||
BitstreamCursor::AF_DontPopBlockAtEnd);
|
||||
if (!MaybeEntry)
|
||||
@@ -833,11 +817,25 @@ MetadataLoader::MetadataLoaderImpl::lazyLoadModuleMetadataBlock() {
|
||||
break;
|
||||
}
|
||||
case bitc::METADATA_GLOBAL_DECL_ATTACHMENT: {
|
||||
if (!GlobalDeclAttachmentPos)
|
||||
GlobalDeclAttachmentPos = SavedPos;
|
||||
#ifndef NDEBUG
|
||||
NumGlobalDeclAttachSkipped++;
|
||||
#endif
|
||||
// FIXME: we need to do this early because we don't materialize global
|
||||
// value explicitly.
|
||||
if (Error Err = IndexCursor.JumpToBit(CurrentPos))
|
||||
return std::move(Err);
|
||||
Record.clear();
|
||||
if (Expected<unsigned> MaybeRecord =
|
||||
IndexCursor.readRecord(Entry.ID, Record))
|
||||
;
|
||||
else
|
||||
return MaybeRecord.takeError();
|
||||
if (Record.size() % 2 == 0)
|
||||
return error("Invalid record");
|
||||
unsigned ValueID = Record[0];
|
||||
if (ValueID >= ValueList.size())
|
||||
return error("Invalid record");
|
||||
if (auto *GO = dyn_cast<GlobalObject>(ValueList[ValueID]))
|
||||
if (Error Err = parseGlobalObjectAttachment(
|
||||
*GO, ArrayRef<uint64_t>(Record).slice(1)))
|
||||
return std::move(Err);
|
||||
break;
|
||||
}
|
||||
case bitc::METADATA_KIND:
|
||||
@@ -887,81 +885,6 @@ MetadataLoader::MetadataLoaderImpl::lazyLoadModuleMetadataBlock() {
|
||||
}
|
||||
}
|
||||
|
||||
// Load the global decl attachments after building the lazy loading index.
|
||||
// We don't load them "lazily" - all global decl attachments must be
|
||||
// parsed since they aren't materialized on demand. However, by delaying
|
||||
// their parsing until after the index is created, we can use the index
|
||||
// instead of creating temporaries.
|
||||
Expected<bool> MetadataLoader::MetadataLoaderImpl::loadGlobalDeclAttachments() {
|
||||
// Nothing to do if we didn't find any of these metadata records.
|
||||
if (!GlobalDeclAttachmentPos)
|
||||
return true;
|
||||
IndexCursor = Stream;
|
||||
SmallVector<uint64_t, 64> Record;
|
||||
// Jump to the position before the first global decl attachment, so we can
|
||||
// scan for the first BitstreamEntry record.
|
||||
if (Error Err = IndexCursor.JumpToBit(GlobalDeclAttachmentPos))
|
||||
return std::move(Err);
|
||||
while (true) {
|
||||
Expected<BitstreamEntry> MaybeEntry = IndexCursor.advanceSkippingSubblocks(
|
||||
BitstreamCursor::AF_DontPopBlockAtEnd);
|
||||
if (!MaybeEntry)
|
||||
return MaybeEntry.takeError();
|
||||
BitstreamEntry Entry = MaybeEntry.get();
|
||||
|
||||
switch (Entry.Kind) {
|
||||
case BitstreamEntry::SubBlock: // Handled for us already.
|
||||
case BitstreamEntry::Error:
|
||||
return error("Malformed block");
|
||||
case BitstreamEntry::EndBlock:
|
||||
// Sanity check that we parsed them all.
|
||||
assert(NumGlobalDeclAttachSkipped == NumGlobalDeclAttachParsed);
|
||||
return true;
|
||||
case BitstreamEntry::Record:
|
||||
break;
|
||||
}
|
||||
uint64_t CurrentPos = IndexCursor.GetCurrentBitNo();
|
||||
Expected<unsigned> MaybeCode = IndexCursor.skipRecord(Entry.ID);
|
||||
if (!MaybeCode)
|
||||
return MaybeCode.takeError();
|
||||
if (MaybeCode.get() != bitc::METADATA_GLOBAL_DECL_ATTACHMENT) {
|
||||
// Anything other than a global decl attachment signals the end of
|
||||
// these records. sanity check that we parsed them all.
|
||||
assert(NumGlobalDeclAttachSkipped == NumGlobalDeclAttachParsed);
|
||||
return true;
|
||||
}
|
||||
#ifndef NDEBUG
|
||||
NumGlobalDeclAttachParsed++;
|
||||
#endif
|
||||
// FIXME: we need to do this early because we don't materialize global
|
||||
// value explicitly.
|
||||
if (Error Err = IndexCursor.JumpToBit(CurrentPos))
|
||||
return std::move(Err);
|
||||
Record.clear();
|
||||
if (Expected<unsigned> MaybeRecord =
|
||||
IndexCursor.readRecord(Entry.ID, Record))
|
||||
;
|
||||
else
|
||||
return MaybeRecord.takeError();
|
||||
if (Record.size() % 2 == 0)
|
||||
return error("Invalid record");
|
||||
unsigned ValueID = Record[0];
|
||||
if (ValueID >= ValueList.size())
|
||||
return error("Invalid record");
|
||||
if (auto *GO = dyn_cast<GlobalObject>(ValueList[ValueID])) {
|
||||
// Need to save and restore the current position since
|
||||
// parseGlobalObjectAttachment will resolve all forward references which
|
||||
// would require parsing from locations stored in the index.
|
||||
CurrentPos = IndexCursor.GetCurrentBitNo();
|
||||
if (Error Err = parseGlobalObjectAttachment(
|
||||
*GO, ArrayRef<uint64_t>(Record).slice(1)))
|
||||
return std::move(Err);
|
||||
if (Error Err = IndexCursor.JumpToBit(CurrentPos))
|
||||
return std::move(Err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse a METADATA_BLOCK. If ModuleLevel is true then we are parsing
|
||||
/// module level metadata.
|
||||
Error MetadataLoader::MetadataLoaderImpl::parseMetadata(bool ModuleLevel) {
|
||||
@@ -991,14 +914,6 @@ Error MetadataLoader::MetadataLoaderImpl::parseMetadata(bool ModuleLevel) {
|
||||
MetadataList.resize(MDStringRef.size() +
|
||||
GlobalMetadataBitPosIndex.size());
|
||||
|
||||
// Now that we have built the index, load the global decl attachments
|
||||
// that were deferred during that process. This avoids creating
|
||||
// temporaries.
|
||||
SuccessOrErr = loadGlobalDeclAttachments();
|
||||
if (!SuccessOrErr)
|
||||
return SuccessOrErr.takeError();
|
||||
assert(SuccessOrErr.get());
|
||||
|
||||
// Reading the named metadata created forward references and/or
|
||||
// placeholders, that we flush here.
|
||||
resolveForwardRefsAndPlaceholders(Placeholders);
|
||||
@@ -2106,8 +2021,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseGlobalObjectAttachment(
|
||||
auto K = MDKindMap.find(Record[I]);
|
||||
if (K == MDKindMap.end())
|
||||
return error("Invalid ID");
|
||||
MDNode *MD =
|
||||
dyn_cast_or_null<MDNode>(getMetadataFwdRefOrLoad(Record[I + 1]));
|
||||
MDNode *MD = MetadataList.getMDNodeFwdRefOrNull(Record[I + 1]);
|
||||
if (!MD)
|
||||
return error("Invalid metadata attachment: expect fwd ref to MDNode");
|
||||
GO.addMetadata(K->second, *MD);
|
||||
|
||||
Reference in New Issue
Block a user