Chromium Code Reviews| Index: lib/Bitcode/Reader/BitcodeReader.cpp |
| diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp |
| index fa1290c9246e45110f748d8a1bab7f67ca569d12..7535fcf5255782b231134e6668a0c20d82b3aed1 100644 |
| --- a/lib/Bitcode/Reader/BitcodeReader.cpp |
| +++ b/lib/Bitcode/Reader/BitcodeReader.cpp |
| @@ -1528,6 +1528,7 @@ bool BitcodeReader::RememberAndSkipFunctionBody() { |
| Function *Fn = FunctionsWithBodies.back(); |
| FunctionsWithBodies.pop_back(); |
| + fprintf(stderr, "skipping %p\n", Fn); |
| // Save the current stream state. |
| uint64_t CurBit = Stream.GetCurrentBitNo(); |
| @@ -1539,10 +1540,47 @@ 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 |
|
jasonwkim
2011/11/03 17:54:09
I think upstream guys dont like TODO(username) -
(google.com) Derek Schuff
2011/11/03 18:01:27
These will go away before I upstream it.
On 2011/
|
| + // 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"); |
| -fprintf(stderr, "module at byte %d\n", Stream.GetCurrentBitNo()*8); |
| +fprintf(stderr, "module at byte %lu\n", Stream.GetCurrentBitNo()/8); |
| SmallVector<uint64_t, 64> Record; |
| std::vector<std::string> SectionTable; |
| std::vector<std::string> GCTable; |
| @@ -1631,6 +1669,7 @@ fprintf(stderr, "module at byte %d\n", Stream.GetCurrentBitNo()*8); |
| if (RememberAndSkipFunctionBody()) |
| return true; |
| + if (LazyStreamer) return SuspendModuleParse(); |
| break; |
| } |
| continue; |
| @@ -1775,6 +1814,7 @@ fprintf(stderr, "module at byte %d\n", Stream.GetCurrentBitNo()*8); |
| Func->setCallingConv(static_cast<CallingConv::ID>(Record[1])); |
| bool isProto = Record[2]; |
| + fprintf(stderr, "func record %p isProto %d\n", Func, isProto); |
| Func->setLinkage(GetDecodedLinkage(Record[3])); |
| Func->setAttributes(getAttributes(Record[4])); |
| @@ -1798,8 +1838,10 @@ fprintf(stderr, "module at byte %d\n", Stream.GetCurrentBitNo()*8); |
| // 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] |
| @@ -1880,8 +1922,9 @@ fprintf(stderr, "ParseBitcodeInto code %d\n", Code); |
| 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()) |
| @@ -2843,17 +2886,32 @@ bool BitcodeReader::isMaterializable(const GlobalValue *GV) const { |
| 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; |
| +} |
| + |
| bool BitcodeReader::Materialize(GlobalValue *GV, std::string *ErrInfo) { |
| Function *F = dyn_cast<Function>(GV); |
| + fprintf(stderr, "Materialize %p (%s)\n", F, F->getName().str().c_str()); |
| // If it's not a function or is already material, ignore the request. |
| if (!F || !F->isMaterializable()) return false; |
| 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); |
| - fprintf(stderr, "Materialize %s\n", F->getName().str().c_str()); |
| + |
| if (ParseFunctionBody(F)) { |
| if (ErrInfo) *ErrInfo = ErrorString; |
| return true; |