summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-05-01 05:52:21 +0000
committerChris Lattner <sabre@nondot.org>2007-05-01 05:52:21 +0000
commit980e5aad4cfaa32e13b297f4201eb1088ca96cc4 (patch)
tree96f4393b1f18ad2bf9502ccd1ba9256a35be58c0 /lib
parent2bbb703e4f84c68a9603838c32eba7423ed54b71 (diff)
downloadllvm-980e5aad4cfaa32e13b297f4201eb1088ca96cc4.tar.gz
llvm-980e5aad4cfaa32e13b297f4201eb1088ca96cc4.tar.bz2
llvm-980e5aad4cfaa32e13b297f4201eb1088ca96cc4.tar.xz
implement materializeModule, force deallocation of vector memory when we
are done with them, start implementing ParseFunctionBody git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36617 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp105
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.h17
2 files changed, 107 insertions, 15 deletions
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
index cbbf8b2f0b..7f23b611bb 100644
--- a/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -659,9 +659,10 @@ bool BitcodeReader::ParseConstants() {
}
}
-/// ParseFunction - When we see the block for a function body, remember where it
-/// is and then skip it. This lets us lazily deserialize the functions.
-bool BitcodeReader::ParseFunction() {
+/// 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.
+bool BitcodeReader::RememberAndSkipFunctionBody() {
// Get the function we are talking about.
if (FunctionsWithBodies.empty())
return Error("Insufficient function protos");
@@ -701,13 +702,21 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) {
while (!Stream.AtEndOfStream()) {
unsigned Code = Stream.ReadCode();
if (Code == bitc::END_BLOCK) {
+ if (Stream.ReadBlockEnd())
+ return Error("Error at end of module block");
+
+ // Patch the initializers for globals and aliases up.
ResolveGlobalAndAliasInits();
if (!GlobalInits.empty() || !AliasInits.empty())
return Error("Malformed global initializer set");
if (!FunctionsWithBodies.empty())
return Error("Too few function bodies found");
- if (Stream.ReadBlockEnd())
- return Error("Error at end of module block");
+
+ // 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);
+ std::vector<Function*>().swap(FunctionsWithBodies);
return false;
}
@@ -741,7 +750,7 @@ bool BitcodeReader::ParseModule(const std::string &ModuleID) {
HasReversedFunctionsWithBodies = true;
}
- if (ParseFunction())
+ if (RememberAndSkipFunctionBody())
return true;
break;
}
@@ -956,6 +965,90 @@ bool BitcodeReader::materializeFunction(Function *F, std::string *ErrInfo) {
F->setLinkage((GlobalValue::LinkageTypes)DFII->second.second);
DeferredFunctionInfo.erase(DFII);
+ if (ParseFunctionBody(F)) {
+ if (ErrInfo) *ErrInfo = ErrorString;
+ return true;
+ }
+
+ return false;
+}
+
+Module *BitcodeReader::materializeModule(std::string *ErrInfo) {
+ DenseMap<Function*, std::pair<uint64_t, unsigned> >::iterator I =
+ DeferredFunctionInfo.begin();
+ while (!DeferredFunctionInfo.empty()) {
+ Function *F = (*I++).first;
+ assert(F->hasNotBeenReadFromBytecode() &&
+ "Deserialized function found in map!");
+ if (materializeFunction(F, ErrInfo))
+ return 0;
+ }
+ return TheModule;
+}
+
+
+/// ParseFunctionBody - Lazily parse the specified function body block.
+bool BitcodeReader::ParseFunctionBody(Function *F) {
+ if (Stream.EnterSubBlock())
+ return Error("Malformed block record");
+
+ unsigned ModuleValueListSize = ValueList.size();
+
+ // Add all the function arguments to the value table.
+ for(Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I)
+ ValueList.push_back(I);
+
+ // Read all the records.
+ SmallVector<uint64_t, 64> Record;
+ while (1) {
+ unsigned Code = Stream.ReadCode();
+ if (Code == bitc::END_BLOCK) {
+ if (Stream.ReadBlockEnd())
+ return Error("Error at end of function block");
+ break;
+ }
+
+ if (Code == bitc::ENTER_SUBBLOCK) {
+ switch (Stream.ReadSubBlockID()) {
+ default: // Skip unknown content.
+ if (Stream.SkipBlock())
+ return Error("Malformed block record");
+ break;
+ case bitc::CONSTANTS_BLOCK_ID:
+ if (ParseConstants()) return true;
+ break;
+ case bitc::VALUE_SYMTAB_BLOCK_ID:
+ if (ParseValueSymbolTable()) return true;
+ break;
+ }
+ continue;
+ }
+
+ if (Code == bitc::DEFINE_ABBREV) {
+ Stream.ReadAbbrevRecord();
+ continue;
+ }
+
+ // Read a record.
+ Record.clear();
+ switch (Stream.ReadRecord(Code, Record)) {
+ default: // Default behavior: unknown constant
+ case bitc::FUNC_CODE_DECLAREBLOCKS: // DECLAREBLOCKS: [nblocks]
+ if (Record.size() < 1)
+ return Error("Invalid FUNC_CODE_DECLAREBLOCKS record");
+ // Create all the basic blocks for the function.
+ FunctionBBs.resize(Record.size());
+ for (unsigned i = 0, e = FunctionBBs.size(); i != e; ++i)
+ FunctionBBs[i] = new BasicBlock("", F);
+ break;
+ }
+ }
+
+
+ // Trim the value list down to the size it was before we parsed this function.
+ ValueList.shrinkTo(ModuleValueListSize);
+ std::vector<BasicBlock*>().swap(FunctionBBs);
+
return false;
}
diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h
index 0e407697aa..65c495b669 100644
--- a/lib/Bitcode/Reader/BitcodeReader.h
+++ b/lib/Bitcode/Reader/BitcodeReader.h
@@ -44,7 +44,7 @@ public:
void pop_back() { Uses.pop_back(); --NumOperands; }
bool empty() const { return NumOperands == 0; }
void shrinkTo(unsigned N) {
- assert(N < NumOperands && "Invalid shrinkTo request!");
+ assert(N <= NumOperands && "Invalid shrinkTo request!");
Uses.resize(N);
NumOperands = N;
}
@@ -69,6 +69,10 @@ class BitcodeReader : public ModuleProvider {
std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits;
+ /// FunctionBBs - While parsing a function body, this is a list of the basic
+ /// blocks for the function.
+ std::vector<BasicBlock*> FunctionBBs;
+
// When reading the module header, this list is populated with functions that
// have bodies later in the file.
std::vector<Function*> FunctionsWithBodies;
@@ -96,13 +100,7 @@ public:
}
virtual bool materializeFunction(Function *F, std::string *ErrInfo = 0);
-
- virtual Module *materializeModule(std::string *ErrInfo = 0) {
- // FIXME: TODO
- //if (ParseAllFunctionBodies(ErrMsg))
- // return 0;
- return TheModule;
- }
+ virtual Module *materializeModule(std::string *ErrInfo = 0);
bool Error(const char *Str) {
ErrorString = Str;
@@ -121,7 +119,8 @@ private:
bool ParseTypeSymbolTable();
bool ParseValueSymbolTable();
bool ParseConstants();
- bool ParseFunction();
+ bool RememberAndSkipFunctionBody();
+ bool ParseFunctionBody(Function *F);
bool ResolveGlobalAndAliasInits();
};