Index: llvm/include/llvm/Object/IRSymtab.h =================================================================== --- llvm/include/llvm/Object/IRSymtab.h +++ llvm/include/llvm/Object/IRSymtab.h @@ -30,6 +30,9 @@ #include "llvm/Support/Endian.h" namespace llvm { + +class BitcodeModule; + namespace irsymtab { namespace storage { @@ -291,6 +294,17 @@ return {SymbolRef(MBegin, MEnd, this), SymbolRef(MEnd, MEnd, this)}; } +/// The contents of a bitcode file and its irsymtab. Any underlying data +/// for the irsymtab are owned by Symtab and Strtab. +struct File { + std::vector<BitcodeModule> Mods; + SmallVector<char, 0> Symtab, Strtab; + Reader TheReader; +}; + +/// Reads a bitcode file, creating its irsymtab if necessary. +Expected<File> read(MemoryBufferRef MBRef); + } } Index: llvm/lib/LTO/LTO.cpp =================================================================== --- llvm/lib/LTO/LTO.cpp +++ llvm/lib/LTO/LTO.cpp @@ -310,53 +310,18 @@ Expected<std::unique_ptr<InputFile>> InputFile::create(MemoryBufferRef Object) { std::unique_ptr<InputFile> File(new InputFile); - ErrorOr<MemoryBufferRef> BCOrErr = - IRObjectFile::findBitcodeInMemBuffer(Object); - if (!BCOrErr) - return errorCodeToError(BCOrErr.getError()); - - Expected<std::vector<BitcodeModule>> BMsOrErr = - getBitcodeModuleList(*BCOrErr); - if (!BMsOrErr) - return BMsOrErr.takeError(); - - if (BMsOrErr->empty()) - return make_error<StringError>("Bitcode file does not contain any modules", - inconvertibleErrorCode()); - - File->Mods = *BMsOrErr; - - LLVMContext Ctx; - std::vector<Module *> Mods; - std::vector<std::unique_ptr<Module>> OwnedMods; - for (auto BM : *BMsOrErr) { - Expected<std::unique_ptr<Module>> MOrErr = - BM.getLazyModule(Ctx, /*ShouldLazyLoadMetadata*/ true, - /*IsImporting*/ false); - if (!MOrErr) - return MOrErr.takeError(); - - if ((*MOrErr)->getDataLayoutStr().empty()) - return make_error<StringError>("input module has no datalayout", - inconvertibleErrorCode()); - - Mods.push_back(MOrErr->get()); - OwnedMods.push_back(std::move(*MOrErr)); - } - - SmallVector<char, 0> Symtab; - if (Error E = irsymtab::build(Mods, Symtab, File->Strtab)) - return std::move(E); + Expected<irsymtab::File> FOrErr = irsymtab::read(Object); + if (!FOrErr) + return FOrErr.takeError(); - irsymtab::Reader R({Symtab.data(), Symtab.size()}, - {File->Strtab.data(), File->Strtab.size()}); - File->SourceFileName = R.getSourceFileName(); - File->COFFLinkerOpts = R.getCOFFLinkerOpts(); - File->ComdatTable = R.getComdatTable(); + File->SourceFileName = FOrErr->TheReader.getSourceFileName(); + File->COFFLinkerOpts = FOrErr->TheReader.getCOFFLinkerOpts(); + File->ComdatTable = FOrErr->TheReader.getComdatTable(); - for (unsigned I = 0; I != Mods.size(); ++I) { + for (unsigned I = 0; I != FOrErr->Mods.size(); ++I) { size_t Begin = File->Symbols.size(); - for (const irsymtab::Reader::SymbolRef &Sym : R.module_symbols(I)) + for (const irsymtab::Reader::SymbolRef &Sym : + FOrErr->TheReader.module_symbols(I)) // Skip symbols that are irrelevant to LTO. Note that this condition needs // to match the one in Skip() in LTO::addRegularLTO(). if (Sym.isGlobal() && !Sym.isFormatSpecific()) @@ -364,6 +329,8 @@ File->ModuleSymIndices.push_back({Begin, File->Symbols.size()}); } + File->Mods = FOrErr->Mods; + File->Strtab = std::move(FOrErr->Strtab); return std::move(File); } Index: llvm/lib/Object/IRSymtab.cpp =================================================================== --- llvm/lib/Object/IRSymtab.cpp +++ llvm/lib/Object/IRSymtab.cpp @@ -11,7 +11,9 @@ #include "llvm/Analysis/ObjectUtils.h" #include "llvm/IR/Mangler.h" #include "llvm/IR/Module.h" +#include "llvm/Bitcode/BitcodeReader.h" #include "llvm/MC/StringTableBuilder.h" +#include "llvm/Object/IRObjectFile.h" #include "llvm/Object/ModuleSymbolTable.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/StringSaver.h" @@ -226,3 +228,46 @@ SmallVector<char, 0> &Strtab) { return Builder(Symtab, Strtab).build(Mods); } + +Expected<File> irsymtab::read(MemoryBufferRef MBRef) { + File F; + ErrorOr<MemoryBufferRef> BCOrErr = + object::IRObjectFile::findBitcodeInMemBuffer(MBRef); + if (!BCOrErr) + return errorCodeToError(BCOrErr.getError()); + + Expected<std::vector<BitcodeModule>> BMsOrErr = + getBitcodeModuleList(*BCOrErr); + if (!BMsOrErr) + return BMsOrErr.takeError(); + + if (BMsOrErr->empty()) + return make_error<StringError>("Bitcode file does not contain any modules", + inconvertibleErrorCode()); + F.Mods = std::move(*BMsOrErr); + + LLVMContext Ctx; + std::vector<Module *> Mods; + std::vector<std::unique_ptr<Module>> OwnedMods; + for (auto BM : F.Mods) { + Expected<std::unique_ptr<Module>> MOrErr = + BM.getLazyModule(Ctx, /*ShouldLazyLoadMetadata*/ true, + /*IsImporting*/ false); + if (!MOrErr) + return MOrErr.takeError(); + + if ((*MOrErr)->getDataLayoutStr().empty()) + return make_error<StringError>("input module has no datalayout", + inconvertibleErrorCode()); + + Mods.push_back(MOrErr->get()); + OwnedMods.push_back(std::move(*MOrErr)); + } + + if (Error E = build(Mods, F.Symtab, F.Strtab)) + return std::move(E); + + F.TheReader = {{F.Symtab.data(), F.Symtab.size()}, + {F.Strtab.data(), F.Strtab.size()}}; + return std::move(F); +}