LTO: Lazy-load LTOModule in local contexts

Start lazy-loading `LTOModule`s that own their contexts.  These can only
really be used for parsing symbols, so its unnecessary to ever
materialize their functions.

I looked into using `IRObjectFile::create()` and optionally calling
`materializAllPermanently()` afterwards, but this turned out to be
awkward.

  - The default target triple and data layout logic needs to happen
    *before* the call to `IRObjectFile::IRObjectFile()`, but after
    `Module` was created.

  - I tried passing a lambda in to do the module initialization, but
    this seemed to require threading the error message from
    `TargetRegistry::lookupTarget()` through `std::error_code`.

  - I also looked at setting `errMsg` directly from within the lambda,
    but this didn't look any better.

(I guess there's a reason we weren't already using that function.)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@224466 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan P. N. Exon Smith 2014-12-17 22:05:42 +00:00
parent 1c97c5e8bd
commit 657f8c831a

View File

@ -146,6 +146,25 @@ LTOModule *LTOModule::createInContext(const void *mem, size_t length,
return makeLTOModule(Buffer, options, errMsg, Context);
}
static ErrorOr<Module *> parseBitcodeFileImpl(MemoryBufferRef Buffer,
LLVMContext &Context,
bool ShouldBeLazy) {
// Find the buffer.
ErrorOr<MemoryBufferRef> MBOrErr =
IRObjectFile::findBitcodeInMemBuffer(Buffer);
if (std::error_code EC = MBOrErr.getError())
return EC;
if (!ShouldBeLazy)
// Parse the full file.
return parseBitcodeFile(*MBOrErr, Context);
// Parse lazily.
std::unique_ptr<MemoryBuffer> LightweightBuf =
MemoryBuffer::getMemBuffer(*MBOrErr, false);
return getLazyBitcodeModule(std::move(LightweightBuf), Context);
}
LTOModule *LTOModule::makeLTOModule(MemoryBufferRef Buffer,
TargetOptions options, std::string &errMsg,
LLVMContext *Context) {
@ -155,13 +174,10 @@ LTOModule *LTOModule::makeLTOModule(MemoryBufferRef Buffer,
Context = OwnedContext.get();
}
ErrorOr<MemoryBufferRef> MBOrErr =
IRObjectFile::findBitcodeInMemBuffer(Buffer);
if (std::error_code EC = MBOrErr.getError()) {
errMsg = EC.message();
return nullptr;
}
ErrorOr<Module *> MOrErr = parseBitcodeFile(*MBOrErr, *Context);
// If we own a context, we know this is being used only for symbol
// extraction, not linking. Be lazy in that case.
ErrorOr<Module *> MOrErr = parseBitcodeFileImpl(
Buffer, *Context, /* ShouldBeLazy */ static_cast<bool>(OwnedContext));
if (std::error_code EC = MOrErr.getError()) {
errMsg = EC.message();
return nullptr;