| Index: lib/Bitcode/Reader/BitcodeReader.cpp
|
| diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp
|
| index 3682e6ddca3c28210442686fa2bfd5331155020d..a6694b074397a54997f35342c7b1b843f01dd4f2 100644
|
| --- a/lib/Bitcode/Reader/BitcodeReader.cpp
|
| +++ b/lib/Bitcode/Reader/BitcodeReader.cpp
|
| @@ -13,6 +13,7 @@
|
|
|
| #include "llvm/Bitcode/ReaderWriter.h"
|
| #include "BitcodeReader.h"
|
| +#include "llvm/Support/BitcodeStream.h"
|
| #include "llvm/Constants.h"
|
| #include "llvm/DerivedTypes.h"
|
| #include "llvm/InlineAsm.h"
|
| @@ -1308,8 +1309,42 @@ 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();
|
| + return false;
|
| +}
|
| +
|
| +bool BitcodeReader::GlobalCleanup() {
|
| + // Patch the initializers for globals and aliases up.
|
| + ResolveGlobalAndAliasInits();
|
| + if (!GlobalInits.empty() || !AliasInits.empty())
|
| + return Error("Malformed global initializer set");
|
| +
|
| + // Look for intrinsic functions which need to be upgraded at some point
|
| + 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));
|
| + }
|
| +
|
| + // 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;
|
| @@ -1323,33 +1358,7 @@ bool BitcodeReader::ParseModule() {
|
| 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");
|
| -
|
| - // Look for intrinsic functions which need to be upgraded at some point
|
| - 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));
|
| - }
|
| -
|
| - // 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);
|
| - std::vector<Function*>().swap(FunctionsWithBodies);
|
| - return false;
|
| + return GlobalCleanup();
|
| }
|
|
|
| if (Code == bitc::ENTER_SUBBLOCK) {
|
| @@ -1385,13 +1394,17 @@ bool BitcodeReader::ParseModule() {
|
| case bitc::FUNCTION_BLOCK_ID:
|
| // If this is the first function body we've seen, reverse the
|
| // FunctionsWithBodies list.
|
| - if (!HasReversedFunctionsWithBodies) {
|
| + if (!SeenFirstFunctionBody) {
|
| std::reverse(FunctionsWithBodies.begin(), FunctionsWithBodies.end());
|
| - HasReversedFunctionsWithBodies = true;
|
| + if (GlobalCleanup())
|
| + return true;
|
| + SeenFirstFunctionBody = true;
|
| }
|
|
|
| if (RememberAndSkipFunctionBody())
|
| return true;
|
| + if (LazyStreamer)
|
| + return SuspendModuleParse();
|
| break;
|
| }
|
| continue;
|
| @@ -1546,8 +1559,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]
|
| @@ -1586,24 +1601,7 @@ bool BitcodeReader::ParseModule() {
|
| bool BitcodeReader::ParseBitcodeInto(Module *M) {
|
| TheModule = 0;
|
|
|
| - unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart();
|
| - unsigned char *BufEnd = BufPtr+Buffer->getBufferSize();
|
| -
|
| - if (Buffer->getBufferSize() & 3) {
|
| - if (!isRawBitcode(BufPtr, BufEnd) && !isBitcodeWrapper(BufPtr, BufEnd))
|
| - return Error("Invalid bitcode signature");
|
| - else
|
| - return Error("Bitcode stream should be a multiple of 4 bytes in length");
|
| - }
|
| -
|
| - // If we have a wrapper header, parse it and ignore the non-bc file contents.
|
| - // The magic number is 0x0B17C0DE stored in little endian.
|
| - if (isBitcodeWrapper(BufPtr, BufEnd))
|
| - if (SkipBitcodeWrapperHeader(BufPtr, BufEnd))
|
| - return Error("Invalid bitcode wrapper header");
|
| -
|
| - StreamFile.init(BufPtr, BufEnd);
|
| - Stream.init(StreamFile);
|
| + if (InitStream()) return true;
|
|
|
| // Sniff for the signature.
|
| if (Stream.Read(8) != 'B' ||
|
| @@ -1645,8 +1643,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())
|
| @@ -1714,20 +1713,7 @@ bool BitcodeReader::ParseModuleTriple(std::string &Triple) {
|
| }
|
|
|
| bool BitcodeReader::ParseTriple(std::string &Triple) {
|
| - if (Buffer->getBufferSize() & 3)
|
| - return Error("Bitcode stream should be a multiple of 4 bytes in length");
|
| -
|
| - unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart();
|
| - unsigned char *BufEnd = BufPtr+Buffer->getBufferSize();
|
| -
|
| - // If we have a wrapper header, parse it and ignore the non-bc file contents.
|
| - // The magic number is 0x0B17C0DE stored in little endian.
|
| - if (isBitcodeWrapper(BufPtr, BufEnd))
|
| - if (SkipBitcodeWrapperHeader(BufPtr, BufEnd))
|
| - return Error("Invalid bitcode wrapper header");
|
| -
|
| - StreamFile.init(BufPtr, BufEnd);
|
| - Stream.init(StreamFile);
|
| + if (InitStream()) return true;
|
|
|
| // Sniff for the signature.
|
| if (Stream.Read(8) != 'B' ||
|
| @@ -2607,6 +2593,19 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
|
| return false;
|
| }
|
|
|
| +/// FindFunctionInStream - Find the function body in the bitcode stream
|
| +bool BitcodeReader::FindFunctionInStream(Function *F,
|
| + DenseMap<Function*, uint64_t>::iterator DeferredFunctionInfoIterator) {
|
| + while (DeferredFunctionInfoIterator->second == 0) {
|
| + if (Stream.AtEndOfStream())
|
| + return Error("Could not find Function in stream");
|
| + // ParseModule will parse the next body in the stream and set its
|
| + // position in the DeferredFunctionInfo map
|
| + if (ParseModule(true)) return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| //===----------------------------------------------------------------------===//
|
| // GVMaterializer implementation
|
| //===----------------------------------------------------------------------===//
|
| @@ -2627,6 +2626,10 @@ 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 its position is recorded as 0, its body is somewhere in the stream
|
| + // but we haven't seen it yet.
|
| + 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);
|
| @@ -2704,6 +2707,56 @@ bool BitcodeReader::MaterializeModule(Module *M, std::string *ErrInfo) {
|
| return false;
|
| }
|
|
|
| +bool BitcodeReader::InitStream() {
|
| + if (LazyStreamer) return InitLazyStream();
|
| + return InitStreamFromBuffer();
|
| +}
|
| +
|
| +bool BitcodeReader::InitStreamFromBuffer() {
|
| + const unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart();
|
| + const unsigned char *BufEnd = BufPtr+Buffer->getBufferSize();
|
| +
|
| + if (Buffer->getBufferSize() & 3) {
|
| + if (!isRawBitcode(BufPtr, BufEnd) && !isBitcodeWrapper(BufPtr, BufEnd))
|
| + return Error("Invalid bitcode signature");
|
| + else
|
| + return Error("Bitcode stream should be a multiple of 4 bytes in length");
|
| + }
|
| +
|
| + // If we have a wrapper header, parse it and ignore the non-bc file contents.
|
| + // The magic number is 0x0B17C0DE stored in little endian.
|
| + if (isBitcodeWrapper(BufPtr, BufEnd))
|
| + if (SkipBitcodeWrapperHeader(BufPtr, BufEnd, true))
|
| + return Error("Invalid bitcode wrapper header");
|
| +
|
| + StreamFile.reset(new BitstreamReader(BufPtr, BufEnd));
|
| + Stream.init(*StreamFile);
|
| +
|
| + return false;
|
| +}
|
| +
|
| +bool BitcodeReader::InitLazyStream() {
|
| + // Check and strip off the bitcode wrapper; BitstreamReader expects never to
|
| + // see it.
|
| + LazyBitstreamBytes *Bytes = new LazyBitstreamBytes(LazyStreamer);
|
| + StreamFile.reset(new BitstreamReader(Bytes));
|
| + Stream.init(*StreamFile);
|
| + if (!Bytes->canSkipToPos(15))
|
| + return Error("Bitcode stream must be at least 16 bytes in length");
|
| + unsigned char buf[16];
|
| + for (int i = 0; i < 16; i++) buf[i] = Bytes->getByte(i);
|
| + if (!isBitcode(buf, buf + 16)) {
|
| + return Error("Invalid bitcode signature");
|
| + }
|
| + if (isBitcodeWrapper(buf, buf + 4)) {
|
| + const unsigned char *bitcodeStart = buf;
|
| + const unsigned char *bitcodeEnd = buf + 16;
|
| + SkipBitcodeWrapperHeader(bitcodeStart, bitcodeEnd, false);
|
| + Bytes->dropLeadingBytes(bitcodeStart - buf);
|
| + Bytes->setKnownBitcodeSize(bitcodeEnd - bitcodeStart);
|
| + }
|
| + return false;
|
| +}
|
|
|
| //===----------------------------------------------------------------------===//
|
| // External interface
|
| @@ -2729,6 +2782,24 @@ Module *llvm::getLazyBitcodeModule(MemoryBuffer *Buffer,
|
| return M;
|
| }
|
|
|
| +
|
| +Module *llvm::getStreamedBitcodeModule(const std::string &name,
|
| + BitcodeStreamer *streamer,
|
| + LLVMContext &Context,
|
| + std::string *ErrMsg) {
|
| + Module *M = new Module(name, Context);
|
| + BitcodeReader *R = new BitcodeReader(streamer, Context);
|
| + M->setMaterializer(R);
|
| + if (R->ParseBitcodeInto(M)) {
|
| + if (ErrMsg)
|
| + *ErrMsg = R->getErrorString();
|
| + delete M; // Also deletes R.
|
| + return 0;
|
| + }
|
| + R->setBufferOwned(false); // no buffer to delete
|
| + return M;
|
| +}
|
| +
|
| /// ParseBitcodeFile - Read the specified bitcode file, returning the module.
|
| /// If an error occurs, return null and fill in *ErrMsg if non-null.
|
| Module *llvm::ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext& Context,
|
|
|