summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Bitcode/Reader/BitcodeReader.cpp')
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp61
1 files changed, 52 insertions, 9 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index e7e8b030ccb..c4e070cd17b 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -82,7 +82,7 @@ BitcodeReader::BitcodeReader(MemoryBuffer *buffer, LLVMContext &C,
TheModule(nullptr), Buffer(buffer), LazyStreamer(nullptr),
NextUnreadBit(0), SeenValueSymbolTable(false), ValueList(C),
MDValueList(C), SeenFirstFunctionBody(false), UseRelativeIDs(false),
- WillMaterializeAllForwardRefs(false) {}
+ WillMaterializeAllForwardRefs(false), IsMetadataMaterialized(false) {}
BitcodeReader::BitcodeReader(DataStreamer *streamer, LLVMContext &C,
DiagnosticHandlerFunction DiagnosticHandler)
@@ -90,7 +90,7 @@ BitcodeReader::BitcodeReader(DataStreamer *streamer, LLVMContext &C,
TheModule(nullptr), Buffer(nullptr), LazyStreamer(streamer),
NextUnreadBit(0), SeenValueSymbolTable(false), ValueList(C),
MDValueList(C), SeenFirstFunctionBody(false), UseRelativeIDs(false),
- WillMaterializeAllForwardRefs(false) {}
+ WillMaterializeAllForwardRefs(false), IsMetadataMaterialized(false) {}
std::error_code BitcodeReader::materializeForwardReferencedFunctions() {
if (WillMaterializeAllForwardRefs)
@@ -136,6 +136,7 @@ void BitcodeReader::FreeState() {
std::vector<BasicBlock*>().swap(FunctionBBs);
std::vector<Function*>().swap(FunctionsWithBodies);
DeferredFunctionInfo.clear();
+ DeferredMetadataInfo.clear();
MDKindMap.clear();
assert(BasicBlockFwdRefs.empty() && "Unresolved blockaddress fwd references");
@@ -1199,6 +1200,7 @@ std::error_code BitcodeReader::ParseValueSymbolTable() {
static int64_t unrotateSign(uint64_t U) { return U & 1 ? ~(U >> 1) : U >> 1; }
std::error_code BitcodeReader::ParseMetadata() {
+ IsMetadataMaterialized = true;
unsigned NextMDValueNo = MDValueList.size();
if (Stream.EnterSubBlock(bitc::METADATA_BLOCK_ID))
@@ -2235,6 +2237,30 @@ std::error_code BitcodeReader::ParseUseLists() {
}
}
+/// When we see the block for metadata, remember where it is and then skip it.
+/// This lets us lazily deserialize the metadata.
+std::error_code BitcodeReader::rememberAndSkipMetadata() {
+ // Save the current stream state.
+ uint64_t CurBit = Stream.GetCurrentBitNo();
+ DeferredMetadataInfo.push_back(CurBit);
+
+ // Skip over the block for now.
+ if (Stream.SkipBlock())
+ return Error("Invalid record");
+ return std::error_code();
+}
+
+std::error_code BitcodeReader::materializeMetadata() {
+ for (uint64_t BitPos : DeferredMetadataInfo) {
+ // Move the bit stream to the saved position.
+ Stream.JumpToBit(BitPos);
+ if (std::error_code EC = ParseMetadata())
+ return EC;
+ }
+ DeferredMetadataInfo.clear();
+ return std::error_code();
+}
+
/// RememberAndSkipFunctionBody - When we see the block for a function body,
/// remember where it is and then skip it. This lets us lazily deserialize the
/// functions.
@@ -2285,7 +2311,8 @@ std::error_code BitcodeReader::GlobalCleanup() {
return std::error_code();
}
-std::error_code BitcodeReader::ParseModule(bool Resume) {
+std::error_code BitcodeReader::ParseModule(bool Resume,
+ bool ShouldLazyLoadMetadata) {
if (Resume)
Stream.JumpToBit(NextUnreadBit);
else if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID))
@@ -2339,6 +2366,12 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
return EC;
break;
case bitc::METADATA_BLOCK_ID:
+ if (ShouldLazyLoadMetadata && !IsMetadataMaterialized) {
+ if (std::error_code EC = rememberAndSkipMetadata())
+ return EC;
+ break;
+ }
+ assert(DeferredMetadataInfo.empty() && "Unexpected deferred metadata");
if (std::error_code EC = ParseMetadata())
return EC;
break;
@@ -2653,7 +2686,8 @@ std::error_code BitcodeReader::ParseModule(bool Resume) {
}
}
-std::error_code BitcodeReader::ParseBitcodeInto(Module *M) {
+std::error_code BitcodeReader::ParseBitcodeInto(Module *M,
+ bool ShouldLazyLoadMetadata) {
TheModule = nullptr;
if (std::error_code EC = InitStream())
@@ -2694,7 +2728,7 @@ std::error_code BitcodeReader::ParseBitcodeInto(Module *M) {
if (TheModule)
return Error("Invalid multiple blocks");
TheModule = M;
- if (std::error_code EC = ParseModule(false))
+ if (std::error_code EC = ParseModule(false, ShouldLazyLoadMetadata))
return EC;
if (LazyStreamer)
return std::error_code();
@@ -3894,6 +3928,9 @@ std::error_code BitcodeReader::FindFunctionInStream(
void BitcodeReader::releaseBuffer() { Buffer.release(); }
std::error_code BitcodeReader::materialize(GlobalValue *GV) {
+ if (std::error_code EC = materializeMetadata())
+ return EC;
+
Function *F = dyn_cast<Function>(GV);
// If it's not a function or is already material, ignore the request.
if (!F || !F->isMaterializable())
@@ -3961,6 +3998,9 @@ std::error_code BitcodeReader::MaterializeModule(Module *M) {
assert(M == TheModule &&
"Can only Materialize the Module this BitcodeReader is attached to.");
+ if (std::error_code EC = materializeMetadata())
+ return EC;
+
// Promise to materialize all forward references.
WillMaterializeAllForwardRefs = true;
@@ -4101,7 +4141,8 @@ const std::error_category &llvm::BitcodeErrorCategory() {
static ErrorOr<Module *>
getLazyBitcodeModuleImpl(std::unique_ptr<MemoryBuffer> &&Buffer,
LLVMContext &Context, bool WillMaterializeAll,
- DiagnosticHandlerFunction DiagnosticHandler) {
+ DiagnosticHandlerFunction DiagnosticHandler,
+ bool ShouldLazyLoadMetadata = false) {
Module *M = new Module(Buffer->getBufferIdentifier(), Context);
BitcodeReader *R =
new BitcodeReader(Buffer.get(), Context, DiagnosticHandler);
@@ -4113,7 +4154,8 @@ getLazyBitcodeModuleImpl(std::unique_ptr<MemoryBuffer> &&Buffer,
return EC;
};
- if (std::error_code EC = R->ParseBitcodeInto(M))
+ // Delay parsing Metadata if ShouldLazyLoadMetadata is true.
+ if (std::error_code EC = R->ParseBitcodeInto(M, ShouldLazyLoadMetadata))
return cleanupOnError(EC);
if (!WillMaterializeAll)
@@ -4128,9 +4170,10 @@ getLazyBitcodeModuleImpl(std::unique_ptr<MemoryBuffer> &&Buffer,
ErrorOr<Module *>
llvm::getLazyBitcodeModule(std::unique_ptr<MemoryBuffer> &&Buffer,
LLVMContext &Context,
- DiagnosticHandlerFunction DiagnosticHandler) {
+ DiagnosticHandlerFunction DiagnosticHandler,
+ bool ShouldLazyLoadMetadata) {
return getLazyBitcodeModuleImpl(std::move(Buffer), Context, false,
- DiagnosticHandler);
+ DiagnosticHandler, ShouldLazyLoadMetadata);
}
ErrorOr<std::unique_ptr<Module>>
OpenPOWER on IntegriCloud