Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(240)

Unified Diff: lib/Bitcode/Reader/BitcodeReader.cpp

Issue 8437024: Bitcode parsing modifications for streaming (Closed)
Patch Set: Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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;

Powered by Google App Engine
This is Rietveld 408576698