diff options
-rw-r--r-- | clang/lib/CodeGen/BackendUtil.cpp | 31 | ||||
-rw-r--r-- | clang/test/CodeGen/thinlto_backend.ll | 9 | ||||
-rw-r--r-- | llvm/include/llvm/Bitcode/BitcodeReader.h | 2 | ||||
-rw-r--r-- | llvm/include/llvm/LTO/LTO.h | 35 | ||||
-rw-r--r-- | llvm/include/llvm/LTO/LTOBackend.h | 3 | ||||
-rw-r--r-- | llvm/lib/LTO/LTO.cpp | 170 | ||||
-rw-r--r-- | llvm/lib/LTO/LTOBackend.cpp | 8 | ||||
-rw-r--r-- | llvm/test/LTO/Resolution/X86/empty-bitcode.test | 3 | ||||
-rw-r--r-- | llvm/test/LTO/Resolution/X86/mixed_lto.ll | 6 | ||||
-rw-r--r-- | llvm/test/LTO/Resolution/X86/multi-thinlto.ll | 6 |
10 files changed, 198 insertions, 75 deletions
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 87937c057be..cef7485446a 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -753,7 +753,7 @@ static void runThinLTOBackend(const CodeGenOptions &CGOpts, Module *M, ImportList); std::vector<std::unique_ptr<llvm::MemoryBuffer>> OwnedImports; - MapVector<llvm::StringRef, llvm::MemoryBufferRef> ModuleMap; + MapVector<llvm::StringRef, llvm::BitcodeModule> ModuleMap; for (auto &I : ImportList) { ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> MBOrErr = @@ -763,7 +763,34 @@ static void runThinLTOBackend(const CodeGenOptions &CGOpts, Module *M, << "': " << MBOrErr.getError().message() << "\n"; return; } - ModuleMap[I.first()] = (*MBOrErr)->getMemBufferRef(); + + Expected<std::vector<BitcodeModule>> BMsOrErr = + getBitcodeModuleList(**MBOrErr); + if (!BMsOrErr) { + handleAllErrors(BMsOrErr.takeError(), [&](ErrorInfoBase &EIB) { + errs() << "Error loading imported file '" << I.first() + << "': " << EIB.message() << '\n'; + }); + return; + } + + // The bitcode file may contain multiple modules, we want the one with a + // summary. + bool FoundModule = false; + for (BitcodeModule &BM : *BMsOrErr) { + Expected<bool> HasSummary = BM.hasSummary(); + if (HasSummary && *HasSummary) { + ModuleMap.insert({I.first(), BM}); + FoundModule = true; + break; + } + } + if (!FoundModule) { + errs() << "Error loading imported file '" << I.first() + << "': Could not find module summary\n"; + return; + } + OwnedImports.push_back(std::move(*MBOrErr)); } auto AddStream = [&](size_t Task) { diff --git a/clang/test/CodeGen/thinlto_backend.ll b/clang/test/CodeGen/thinlto_backend.ll index 0fb2643e037..4b01b1ad15b 100644 --- a/clang/test/CodeGen/thinlto_backend.ll +++ b/clang/test/CodeGen/thinlto_backend.ll @@ -9,8 +9,8 @@ ; CHECK-WARNING: error: invalid argument '-fthinlto-index={{.*}}' only allowed with '-x ir' ; Ensure we get expected error for missing index file -; RUN: %clang -O2 -o %t3.o -x ir %t1.o -c -fthinlto-index=bad.thinlto.bc 2>&1 | FileCheck %s -check-prefix=CHECK-ERROR -; CHECK-ERROR: Error loading index file 'bad.thinlto.bc' +; RUN: %clang -O2 -o %t4.o -x ir %t1.o -c -fthinlto-index=bad.thinlto.bc 2>&1 | FileCheck %s -check-prefix=CHECK-ERROR1 +; CHECK-ERROR1: Error loading index file 'bad.thinlto.bc' ; Ensure f2 was imported ; RUN: %clang -target x86_64-unknown-linux-gnu -O2 -o %t3.o -x ir %t1.o -c -fthinlto-index=%t.thinlto.bc @@ -18,6 +18,11 @@ ; CHECK-OBJ: T f1 ; CHECK-OBJ-NOT: U f2 +; Ensure we get expected error for input files without summaries +; RUN: opt -o %t2.o %s +; RUN: %clang -target x86_64-unknown-linux-gnu -O2 -o %t3.o -x ir %t1.o -c -fthinlto-index=%t.thinlto.bc +; CHECK-ERROR2: Error loading imported file '{{.*}}': Could not find module summary + target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/llvm/include/llvm/Bitcode/BitcodeReader.h b/llvm/include/llvm/Bitcode/BitcodeReader.h index 4e60101727d..ab2f25186d7 100644 --- a/llvm/include/llvm/Bitcode/BitcodeReader.h +++ b/llvm/include/llvm/Bitcode/BitcodeReader.h @@ -70,6 +70,8 @@ namespace llvm { return StringRef((const char *)Buffer.begin(), Buffer.size()); } + StringRef getModuleIdentifier() const { return ModuleIdentifier; } + /// Read the bitcode module and prepare for lazy deserialization of function /// bodies. If ShouldLazyLoadMetadata is true, lazily load metadata as well. Expected<std::unique_ptr<Module>> diff --git a/llvm/include/llvm/LTO/LTO.h b/llvm/include/llvm/LTO/LTO.h index 28c05ed3fa1..bc435702157 100644 --- a/llvm/include/llvm/LTO/LTO.h +++ b/llvm/include/llvm/LTO/LTO.h @@ -31,6 +31,7 @@ namespace llvm { +class BitcodeModule; class Error; class LLVMContext; class MemoryBufferRef; @@ -80,14 +81,16 @@ class InputFile { // FIXME: Remove the LLVMContext once we have bitcode symbol tables. LLVMContext Ctx; + struct InputModule; + std::vector<InputModule> Mods; ModuleSymbolTable SymTab; - std::unique_ptr<Module> Mod; - MemoryBufferRef MBRef; std::vector<StringRef> Comdats; DenseMap<const Comdat *, unsigned> ComdatMap; public: + ~InputFile(); + /// Create an InputFile. static Expected<std::unique_ptr<InputFile>> create(MemoryBufferRef Object); @@ -217,11 +220,17 @@ public: symbol_iterator(SymTab.symbols().end(), SymTab, this)); } - StringRef getSourceFileName() const { return Mod->getSourceFileName(); } - MemoryBufferRef getMemoryBufferRef() const { return MBRef; } + /// Returns the path to the InputFile. + StringRef getName() const; + + /// Returns the source file path specified at compile time. + StringRef getSourceFileName() const; // Returns a table with all the comdats used by this file. ArrayRef<StringRef> getComdatTable() const { return Comdats; } + +private: + iterator_range<symbol_iterator> module_symbols(InputModule &IM); }; /// This class wraps an output stream for a native object. Most clients should @@ -311,6 +320,7 @@ public: /// Until that is fixed, a Config argument is required. LTO(Config Conf, ThinBackend Backend = nullptr, unsigned ParallelCodeGenParallelismLevel = 1); + ~LTO(); /// Add an input file to the LTO link, using the provided symbol resolutions. /// The symbol resolutions must appear in the enumeration order given by @@ -357,7 +367,7 @@ private: ThinBackend Backend; ModuleSummaryIndex CombinedIndex; - MapVector<StringRef, MemoryBufferRef> ModuleMap; + MapVector<StringRef, BitcodeModule> ModuleMap; DenseMap<GlobalValue::GUID, StringRef> PrevailingModuleForGUID; } ThinLTO; @@ -405,10 +415,17 @@ private: const InputFile::Symbol &Sym, SymbolResolution Res, unsigned Partition); - Error addRegularLTO(std::unique_ptr<InputFile> Input, - ArrayRef<SymbolResolution> Res); - Error addThinLTO(std::unique_ptr<InputFile> Input, - ArrayRef<SymbolResolution> Res); + // These functions take a range of symbol resolutions [ResI, ResE) and consume + // the resolutions used by a single input module by incrementing ResI. After + // these functions return, [ResI, ResE) will refer to the resolution range for + // the remaining modules in the InputFile. + Error addModule(InputFile &Input, InputFile::InputModule &IM, + const SymbolResolution *&ResI, const SymbolResolution *ResE); + Error addRegularLTO(BitcodeModule BM, const SymbolResolution *&ResI, + const SymbolResolution *ResE); + Error addThinLTO(BitcodeModule BM, Module &M, + iterator_range<InputFile::symbol_iterator> Syms, + const SymbolResolution *&ResI, const SymbolResolution *ResE); Error runRegularLTO(AddStreamFn AddStream); Error runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache, diff --git a/llvm/include/llvm/LTO/LTOBackend.h b/llvm/include/llvm/LTO/LTOBackend.h index 5a80ca58d87..933503afddc 100644 --- a/llvm/include/llvm/LTO/LTOBackend.h +++ b/llvm/include/llvm/LTO/LTOBackend.h @@ -27,6 +27,7 @@ namespace llvm { +class BitcodeModule; class Error; class Module; class Target; @@ -43,7 +44,7 @@ Error thinBackend(Config &C, unsigned Task, AddStreamFn AddStream, Module &M, ModuleSummaryIndex &CombinedIndex, const FunctionImporter::ImportMapTy &ImportList, const GVSummaryMapTy &DefinedGlobals, - MapVector<StringRef, MemoryBufferRef> &ModuleMap); + MapVector<StringRef, BitcodeModule> &ModuleMap); } } diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp index 8a68025121c..718cbf17048 100644 --- a/llvm/lib/LTO/LTO.cpp +++ b/llvm/lib/LTO/LTO.cpp @@ -214,6 +214,17 @@ void llvm::thinLTOInternalizeAndPromoteInIndex( thinLTOInternalizeAndPromoteGUID(I.second, I.first, isExported); } +struct InputFile::InputModule { + BitcodeModule BM; + std::unique_ptr<Module> Mod; + + // The range of ModuleSymbolTable entries for this input module. + size_t SymBegin, SymEnd; +}; + +// Requires a destructor for std::vector<InputModule>. +InputFile::~InputFile() = default; + Expected<std::unique_ptr<InputFile>> InputFile::create(MemoryBufferRef Object) { std::unique_ptr<InputFile> File(new InputFile); @@ -221,23 +232,37 @@ Expected<std::unique_ptr<InputFile>> InputFile::create(MemoryBufferRef Object) { IRObjectFile::findBitcodeInMemBuffer(Object); if (!BCOrErr) return errorCodeToError(BCOrErr.getError()); - File->MBRef = *BCOrErr; - Expected<std::unique_ptr<Module>> MOrErr = - getLazyBitcodeModule(*BCOrErr, File->Ctx, - /*ShouldLazyLoadMetadata*/ true); - if (!MOrErr) - return MOrErr.takeError(); + Expected<std::vector<BitcodeModule>> BMsOrErr = + getBitcodeModuleList(*BCOrErr); + if (!BMsOrErr) + return BMsOrErr.takeError(); - File->Mod = std::move(*MOrErr); - File->SymTab.addModule(File->Mod.get()); + if (BMsOrErr->empty()) + return make_error<StringError>("Bitcode file does not contain any modules", + inconvertibleErrorCode()); - for (const auto &C : File->Mod->getComdatSymbolTable()) { - auto P = - File->ComdatMap.insert(std::make_pair(&C.second, File->Comdats.size())); - assert(P.second); - (void)P; - File->Comdats.push_back(C.first()); + // Create an InputModule for each module in the InputFile, and add it to the + // ModuleSymbolTable. + for (auto BM : *BMsOrErr) { + Expected<std::unique_ptr<Module>> MOrErr = + BM.getLazyModule(File->Ctx, /*ShouldLazyLoadMetadata*/ true); + if (!MOrErr) + return MOrErr.takeError(); + + size_t SymBegin = File->SymTab.symbols().size(); + File->SymTab.addModule(MOrErr->get()); + size_t SymEnd = File->SymTab.symbols().size(); + + for (const auto &C : (*MOrErr)->getComdatSymbolTable()) { + auto P = File->ComdatMap.insert( + std::make_pair(&C.second, File->Comdats.size())); + assert(P.second); + (void)P; + File->Comdats.push_back(C.first()); + } + + File->Mods.push_back({BM, std::move(*MOrErr), SymBegin, SymEnd}); } return std::move(File); @@ -258,6 +283,21 @@ Expected<int> InputFile::Symbol::getComdatIndex() const { return -1; } +StringRef InputFile::getName() const { + return Mods[0].BM.getModuleIdentifier(); +} + +StringRef InputFile::getSourceFileName() const { + return Mods[0].Mod->getSourceFileName(); +} + +iterator_range<InputFile::symbol_iterator> +InputFile::module_symbols(InputModule &IM) { + return llvm::make_range( + symbol_iterator(SymTab.symbols().data() + IM.SymBegin, SymTab, this), + symbol_iterator(SymTab.symbols().data() + IM.SymEnd, SymTab, this)); +} + LTO::RegularLTOState::RegularLTOState(unsigned ParallelCodeGenParallelismLevel, Config &Conf) : ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel), @@ -275,6 +315,9 @@ LTO::LTO(Config Conf, ThinBackend Backend, RegularLTO(ParallelCodeGenParallelismLevel, this->Conf), ThinLTO(std::move(Backend)) {} +// Requires a destructor for MapVector<BitcodeModule>. +LTO::~LTO() = default; + // Add the given symbol to the GlobalResolutions map, and resolve its partition. void LTO::addSymbolToGlobalRes(SmallPtrSet<GlobalValue *, 8> &Used, const InputFile::Symbol &Sym, @@ -297,7 +340,7 @@ void LTO::addSymbolToGlobalRes(SmallPtrSet<GlobalValue *, 8> &Used, static void writeToResolutionFile(raw_ostream &OS, InputFile *Input, ArrayRef<SymbolResolution> Res) { - StringRef Path = Input->getMemoryBufferRef().getBufferIdentifier(); + StringRef Path = Input->getName(); OS << Path << '\n'; auto ResI = Res.begin(); for (const InputFile::Symbol &Sym : Input->symbols()) { @@ -323,34 +366,45 @@ Error LTO::add(std::unique_ptr<InputFile> Input, if (Conf.ResolutionFile) writeToResolutionFile(*Conf.ResolutionFile, Input.get(), Res); + const SymbolResolution *ResI = Res.begin(); + for (InputFile::InputModule &IM : Input->Mods) + if (Error Err = addModule(*Input, IM, ResI, Res.end())) + return Err; + + assert(ResI == Res.end()); + return Error::success(); +} + +Error LTO::addModule(InputFile &Input, InputFile::InputModule &IM, + const SymbolResolution *&ResI, + const SymbolResolution *ResE) { // FIXME: move to backend - Module &M = *Input->Mod; + Module &M = *IM.Mod; if (!Conf.OverrideTriple.empty()) M.setTargetTriple(Conf.OverrideTriple); else if (M.getTargetTriple().empty()) M.setTargetTriple(Conf.DefaultTriple); - Expected<bool> HasThinLTOSummary = hasGlobalValueSummary(Input->MBRef); + Expected<bool> HasThinLTOSummary = IM.BM.hasSummary(); if (!HasThinLTOSummary) return HasThinLTOSummary.takeError(); if (*HasThinLTOSummary) - return addThinLTO(std::move(Input), Res); + return addThinLTO(IM.BM, M, Input.module_symbols(IM), ResI, ResE); else - return addRegularLTO(std::move(Input), Res); + return addRegularLTO(IM.BM, ResI, ResE); } // Add a regular LTO object to the link. -Error LTO::addRegularLTO(std::unique_ptr<InputFile> Input, - ArrayRef<SymbolResolution> Res) { +Error LTO::addRegularLTO(BitcodeModule BM, const SymbolResolution *&ResI, + const SymbolResolution *ResE) { if (!RegularLTO.CombinedModule) { RegularLTO.CombinedModule = llvm::make_unique<Module>("ld-temp.o", RegularLTO.Ctx); RegularLTO.Mover = llvm::make_unique<IRMover>(*RegularLTO.CombinedModule); } Expected<std::unique_ptr<Module>> MOrErr = - getLazyBitcodeModule(Input->MBRef, RegularLTO.Ctx, - /*ShouldLazyLoadMetadata*/ true); + BM.getLazyModule(RegularLTO.Ctx, /*ShouldLazyLoadMetadata*/ true); if (!MOrErr) return MOrErr.takeError(); @@ -371,13 +425,12 @@ Error LTO::addRegularLTO(std::unique_ptr<InputFile> Input, if (GV.hasAppendingLinkage()) Keep.push_back(&GV); - auto ResI = Res.begin(); for (const InputFile::Symbol &Sym : make_range(InputFile::symbol_iterator(SymTab.symbols().begin(), SymTab, nullptr), InputFile::symbol_iterator(SymTab.symbols().end(), SymTab, nullptr))) { - assert(ResI != Res.end()); + assert(ResI != ResE); SymbolResolution Res = *ResI++; addSymbolToGlobalRes(Used, Sym, Res, 0); @@ -411,7 +464,6 @@ Error LTO::addRegularLTO(std::unique_ptr<InputFile> Input, // FIXME: use proposed local attribute for FinalDefinitionInLinkageUnit. } - assert(ResI == Res.end()); return RegularLTO.Mover->move(std::move(*MOrErr), Keep, [](GlobalValue &, IRMover::ValueAdder) {}, @@ -420,33 +472,36 @@ Error LTO::addRegularLTO(std::unique_ptr<InputFile> Input, } // Add a ThinLTO object to the link. -Error LTO::addThinLTO(std::unique_ptr<InputFile> Input, - ArrayRef<SymbolResolution> Res) { - Module &M = *Input->Mod; +// FIXME: This function should not need to take as many parameters once we have +// a bitcode symbol table. +Error LTO::addThinLTO(BitcodeModule BM, Module &M, + iterator_range<InputFile::symbol_iterator> Syms, + const SymbolResolution *&ResI, + const SymbolResolution *ResE) { SmallPtrSet<GlobalValue *, 8> Used; collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false); - MemoryBufferRef MBRef = Input->MBRef; - Expected<std::unique_ptr<object::ModuleSummaryIndexObjectFile>> - SummaryObjOrErr = object::ModuleSummaryIndexObjectFile::create(MBRef); - if (!SummaryObjOrErr) - return SummaryObjOrErr.takeError(); - ThinLTO.CombinedIndex.mergeFrom((*SummaryObjOrErr)->takeIndex(), + Expected<std::unique_ptr<ModuleSummaryIndex>> SummaryOrErr = BM.getSummary(); + if (!SummaryOrErr) + return SummaryOrErr.takeError(); + ThinLTO.CombinedIndex.mergeFrom(std::move(*SummaryOrErr), ThinLTO.ModuleMap.size()); - auto ResI = Res.begin(); - for (const InputFile::Symbol &Sym : Input->symbols()) { - assert(ResI != Res.end()); + for (const InputFile::Symbol &Sym : Syms) { + assert(ResI != ResE); SymbolResolution Res = *ResI++; addSymbolToGlobalRes(Used, Sym, Res, ThinLTO.ModuleMap.size() + 1); if (Res.Prevailing && Sym.isGV()) ThinLTO.PrevailingModuleForGUID[Sym.getGV()->getGUID()] = - MBRef.getBufferIdentifier(); + BM.getModuleIdentifier(); } - assert(ResI == Res.end()); - ThinLTO.ModuleMap[MBRef.getBufferIdentifier()] = MBRef; + if (!ThinLTO.ModuleMap.insert({BM.getModuleIdentifier(), BM}).second) + return make_error<StringError>( + "Expected at most one ThinLTO module per bitcode file", + inconvertibleErrorCode()); + return Error::success(); } @@ -543,11 +598,11 @@ public: virtual ~ThinBackendProc() {} virtual Error start( - unsigned Task, MemoryBufferRef MBRef, + unsigned Task, BitcodeModule BM, const FunctionImporter::ImportMapTy &ImportList, const FunctionImporter::ExportSetTy &ExportList, const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR, - MapVector<StringRef, MemoryBufferRef> &ModuleMap) = 0; + MapVector<StringRef, BitcodeModule> &ModuleMap) = 0; virtual Error wait() = 0; }; @@ -572,16 +627,15 @@ public: Error runThinLTOBackendThread( AddStreamFn AddStream, NativeObjectCache Cache, unsigned Task, - MemoryBufferRef MBRef, ModuleSummaryIndex &CombinedIndex, + BitcodeModule BM, ModuleSummaryIndex &CombinedIndex, const FunctionImporter::ImportMapTy &ImportList, const FunctionImporter::ExportSetTy &ExportList, const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR, const GVSummaryMapTy &DefinedGlobals, - MapVector<StringRef, MemoryBufferRef> &ModuleMap) { + MapVector<StringRef, BitcodeModule> &ModuleMap) { auto RunThinBackend = [&](AddStreamFn AddStream) { LTOLLVMContext BackendContext(Conf); - Expected<std::unique_ptr<Module>> MOrErr = - parseBitcodeFile(MBRef, BackendContext); + Expected<std::unique_ptr<Module>> MOrErr = BM.parseModule(BackendContext); if (!MOrErr) return MOrErr.takeError(); @@ -589,7 +643,7 @@ public: ImportList, DefinedGlobals, ModuleMap); }; - auto ModuleID = MBRef.getBufferIdentifier(); + auto ModuleID = BM.getModuleIdentifier(); if (!Cache || !CombinedIndex.modulePaths().count(ModuleID) || all_of(CombinedIndex.getModuleHash(ModuleID), @@ -609,25 +663,25 @@ public: } Error start( - unsigned Task, MemoryBufferRef MBRef, + unsigned Task, BitcodeModule BM, const FunctionImporter::ImportMapTy &ImportList, const FunctionImporter::ExportSetTy &ExportList, const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR, - MapVector<StringRef, MemoryBufferRef> &ModuleMap) override { - StringRef ModulePath = MBRef.getBufferIdentifier(); + MapVector<StringRef, BitcodeModule> &ModuleMap) override { + StringRef ModulePath = BM.getModuleIdentifier(); assert(ModuleToDefinedGVSummaries.count(ModulePath)); const GVSummaryMapTy &DefinedGlobals = ModuleToDefinedGVSummaries.find(ModulePath)->second; BackendThreadPool.async( - [=](MemoryBufferRef MBRef, ModuleSummaryIndex &CombinedIndex, + [=](BitcodeModule BM, ModuleSummaryIndex &CombinedIndex, const FunctionImporter::ImportMapTy &ImportList, const FunctionImporter::ExportSetTy &ExportList, const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR, const GVSummaryMapTy &DefinedGlobals, - MapVector<StringRef, MemoryBufferRef> &ModuleMap) { + MapVector<StringRef, BitcodeModule> &ModuleMap) { Error E = runThinLTOBackendThread( - AddStream, Cache, Task, MBRef, CombinedIndex, ImportList, + AddStream, Cache, Task, BM, CombinedIndex, ImportList, ExportList, ResolvedODR, DefinedGlobals, ModuleMap); if (E) { std::unique_lock<std::mutex> L(ErrMu); @@ -637,7 +691,7 @@ public: Err = std::move(E); } }, - MBRef, std::ref(CombinedIndex), std::ref(ImportList), + BM, std::ref(CombinedIndex), std::ref(ImportList), std::ref(ExportList), std::ref(ResolvedODR), std::ref(DefinedGlobals), std::ref(ModuleMap)); return Error::success(); @@ -703,12 +757,12 @@ public: LinkedObjectsFileName(LinkedObjectsFileName) {} Error start( - unsigned Task, MemoryBufferRef MBRef, + unsigned Task, BitcodeModule BM, const FunctionImporter::ImportMapTy &ImportList, const FunctionImporter::ExportSetTy &ExportList, const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR, - MapVector<StringRef, MemoryBufferRef> &ModuleMap) override { - StringRef ModulePath = MBRef.getBufferIdentifier(); + MapVector<StringRef, BitcodeModule> &ModuleMap) override { + StringRef ModulePath = BM.getModuleIdentifier(); std::string NewModulePath = getThinLTOOutputFile(ModulePath, OldPrefix, NewPrefix); diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp index ad76e717981..9d4cbdde3ff 100644 --- a/llvm/lib/LTO/LTOBackend.cpp +++ b/llvm/lib/LTO/LTOBackend.cpp @@ -318,7 +318,7 @@ Error lto::thinBackend(Config &Conf, unsigned Task, AddStreamFn AddStream, Module &Mod, ModuleSummaryIndex &CombinedIndex, const FunctionImporter::ImportMapTy &ImportList, const GVSummaryMapTy &DefinedGlobals, - MapVector<StringRef, MemoryBufferRef> &ModuleMap) { + MapVector<StringRef, BitcodeModule> &ModuleMap) { Expected<const Target *> TOrErr = initAndLookupTarget(Conf, Mod); if (!TOrErr) return TOrErr.takeError(); @@ -353,8 +353,10 @@ Error lto::thinBackend(Config &Conf, unsigned Task, AddStreamFn AddStream, auto ModuleLoader = [&](StringRef Identifier) { assert(Mod.getContext().isODRUniquingDebugTypes() && "ODR Type uniquing should be enabled on the context"); - return getLazyBitcodeModule(ModuleMap[Identifier], Mod.getContext(), - /*ShouldLazyLoadMetadata=*/true); + auto I = ModuleMap.find(Identifier); + assert(I != ModuleMap.end()); + return I->second.getLazyModule(Mod.getContext(), + /*ShouldLazyLoadMetadata=*/true); }; FunctionImporter Importer(CombinedIndex, ModuleLoader); diff --git a/llvm/test/LTO/Resolution/X86/empty-bitcode.test b/llvm/test/LTO/Resolution/X86/empty-bitcode.test new file mode 100644 index 00000000000..c98c54499ef --- /dev/null +++ b/llvm/test/LTO/Resolution/X86/empty-bitcode.test @@ -0,0 +1,3 @@ +RUN: llvm-cat -o %t.o +RUN: not llvm-lto2 -o %t2 %t.o 2>&1 | FileCheck %s +CHECK: Bitcode file does not contain any modules diff --git a/llvm/test/LTO/Resolution/X86/mixed_lto.ll b/llvm/test/LTO/Resolution/X86/mixed_lto.ll index 02e6186a3f5..0302ed990e0 100644 --- a/llvm/test/LTO/Resolution/X86/mixed_lto.ll +++ b/llvm/test/LTO/Resolution/X86/mixed_lto.ll @@ -13,6 +13,12 @@ ; NM1-DAG: T main ; NM1-DAG: U g +; Do the same test again, but with the regular and thin LTO modules in the same file. +; RUN: llvm-cat -b -o %t4.o %t2.o %t1.o +; RUN: llvm-lto2 -o %t5.o %t4.o -r %t4.o,main,px -r %t4.o,g, -r %t4.o,g,px +; RUN: llvm-nm %t5.o.0 | FileCheck %s --check-prefix=NM0 +; RUN: llvm-nm %t5.o.1 | FileCheck %s --check-prefix=NM1 + target triple = "x86_64-unknown-linux-gnu" define i32 @g() { ret i32 0 diff --git a/llvm/test/LTO/Resolution/X86/multi-thinlto.ll b/llvm/test/LTO/Resolution/X86/multi-thinlto.ll new file mode 100644 index 00000000000..605c9694ced --- /dev/null +++ b/llvm/test/LTO/Resolution/X86/multi-thinlto.ll @@ -0,0 +1,6 @@ +; RUN: opt -module-summary %s -o %t.o +; RUN: llvm-cat -b -o %t2.o %t.o %t.o +; RUN: not llvm-lto2 -o %t3.o %t2.o 2>&1 | FileCheck %s +; CHECK: Expected at most one ThinLTO module per bitcode file + +target triple = "x86_64-unknown-linux-gnu" |