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:
Fangrui Song
2020-09-23 10:23:48 -07:00
parent e976fb1e54
commit 01b9deba76
2 changed files with 22 additions and 110 deletions

View File

@@ -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);