Index: lib/Bitcode/Reader/BitcodeReader.cpp |
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp |
index 5dc2c69b1dbe23143bb4b98b1d065683100ccc7f..163ef3ccbb380e035bc8ee6334cc0898bb1af435 100644 |
--- a/lib/Bitcode/Reader/BitcodeReader.cpp |
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp |
@@ -1539,8 +1539,45 @@ bool BitcodeReader::RememberAndSkipFunctionBody() { |
return false; |
} |
-bool BitcodeReader::ParseModule() { |
- if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) |
+bool BitcodeReader::SuspendModuleParse() { |
+ // save our current position |
+ NextUnreadBit = Stream.GetCurrentBitNo(); |
+ // Patch the initializers for globals and aliases up. |
+ // TODO(dschuff) this probably only needs to be done once as well |
+ ResolveGlobalAndAliasInits(); |
+ if (!GlobalInits.empty() || !AliasInits.empty()) |
+ return Error("Malformed global initializer set"); |
+ |
+ // Look for intrinsic functions which need to be upgraded at some point |
+ // TODO(dschuff): do these intrinsics have bodies? if not, this can be |
+ // done only once, before we start dealing with function bodies. if so, |
+ // this can probably still be done incrementally instead of this copy/paste |
+ // hack |
+ for (Module::iterator FI = TheModule->begin(), FE = TheModule->end(); |
+ FI != FE; ++FI) { |
+ Function* NewFn; |
+ if (UpgradeIntrinsicFunction(FI, NewFn)) |
+ UpgradedIntrinsics.push_back(std::make_pair(FI, NewFn)); |
+ } |
+ |
+ // TODO(dschuff) this probably only needs to be done once (currently it's a |
+ // noop anyway). find the right place to put it |
+ // Look for global variables which need to be renamed. |
+ for (Module::global_iterator |
+ GI = TheModule->global_begin(), GE = TheModule->global_end(); |
+ GI != GE; ++GI) |
+ UpgradeGlobalVariable(GI); |
+ // Force deallocation of memory for these vectors to favor the client that |
+ // want lazy deserialization. |
+ std::vector<std::pair<GlobalVariable*, unsigned> >().swap(GlobalInits); |
+ std::vector<std::pair<GlobalAlias*, unsigned> >().swap(AliasInits); |
+ return false; |
+} |
+ |
+bool BitcodeReader::ParseModule(bool Resume) { |
+ if (Resume) |
+ Stream.JumpToBit(NextUnreadBit); |
+ else if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) |
return Error("Malformed block record"); |
SmallVector<uint64_t, 64> Record; |
@@ -1631,6 +1668,7 @@ bool BitcodeReader::ParseModule() { |
if (RememberAndSkipFunctionBody()) |
return true; |
+ if (LazyStreamer) return SuspendModuleParse(); |
break; |
} |
continue; |
@@ -1785,8 +1823,10 @@ bool BitcodeReader::ParseModule() { |
// If this is a function with a body, remember the prototype we are |
// creating now, so that we can match up the body with them later. |
- if (!isProto) |
+ if (!isProto) { |
FunctionsWithBodies.push_back(Func); |
+ if (LazyStreamer) DeferredFunctionInfo[Func] = 0; |
+ } |
break; |
} |
// ALIAS: [alias type, aliasee val#, linkage] |
@@ -1867,8 +1907,9 @@ bool BitcodeReader::ParseBitcodeInto(Module *M) { |
if (TheModule) |
return Error("Multiple MODULE_BLOCKs in same stream"); |
TheModule = M; |
- if (ParseModule()) |
+ if (ParseModule(false)) |
return true; |
+ if (LazyStreamer) return false; |
break; |
default: |
if (Stream.SkipBlock()) |
@@ -2817,6 +2858,17 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { |
return false; |
} |
+bool BitcodeReader::FindFunctionInStream(Function *F, |
+ DenseMap<Function*, uint64_t>::iterator DFII) { |
+ //Stream.JumpToBit(NextUnreadBit); |
+ while (DFII->second == 0) { |
+ if (Stream.AtEndOfStream()) |
+ return Error("Could not find Function in stream"); |
+ if(ParseModule(true)) return true; |
+ } |
+ return false; |
+} |
+ |
//===----------------------------------------------------------------------===// |
// GVMaterializer implementation |
//===----------------------------------------------------------------------===// |
@@ -2837,6 +2889,8 @@ bool BitcodeReader::Materialize(GlobalValue *GV, std::string *ErrInfo) { |
DenseMap<Function*, uint64_t>::iterator DFII = DeferredFunctionInfo.find(F); |
assert(DFII != DeferredFunctionInfo.end() && "Deferred function not found!"); |
+ if (DFII->second == 0) |
+ if (LazyStreamer && FindFunctionInStream(F, DFII)) return true; |
// Move the bit stream to the saved position of the deferred function body. |
Stream.JumpToBit(DFII->second); |