[llvm] r289621 - LTO: Add support for multi-module bitcode files.

Peter Collingbourne via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 13 17:17:59 PST 2016


Author: pcc
Date: Tue Dec 13 19:17:59 2016
New Revision: 289621

URL: http://llvm.org/viewvc/llvm-project?rev=289621&view=rev
Log:
LTO: Add support for multi-module bitcode files.

Differential Revision: https://reviews.llvm.org/D27313

Added:
    llvm/trunk/test/LTO/Resolution/X86/empty-bitcode.test
    llvm/trunk/test/LTO/Resolution/X86/multi-thinlto.ll
Modified:
    llvm/trunk/include/llvm/Bitcode/BitcodeReader.h
    llvm/trunk/include/llvm/LTO/LTO.h
    llvm/trunk/include/llvm/LTO/LTOBackend.h
    llvm/trunk/lib/LTO/LTO.cpp
    llvm/trunk/lib/LTO/LTOBackend.cpp
    llvm/trunk/test/LTO/Resolution/X86/mixed_lto.ll

Modified: llvm/trunk/include/llvm/Bitcode/BitcodeReader.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/BitcodeReader.h?rev=289621&r1=289620&r2=289621&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Bitcode/BitcodeReader.h (original)
+++ llvm/trunk/include/llvm/Bitcode/BitcodeReader.h Tue Dec 13 19:17:59 2016
@@ -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>>

Modified: llvm/trunk/include/llvm/LTO/LTO.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LTO/LTO.h?rev=289621&r1=289620&r2=289621&view=diff
==============================================================================
--- llvm/trunk/include/llvm/LTO/LTO.h (original)
+++ llvm/trunk/include/llvm/LTO/LTO.h Tue Dec 13 19:17:59 2016
@@ -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,

Modified: llvm/trunk/include/llvm/LTO/LTOBackend.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LTO/LTOBackend.h?rev=289621&r1=289620&r2=289621&view=diff
==============================================================================
--- llvm/trunk/include/llvm/LTO/LTOBackend.h (original)
+++ llvm/trunk/include/llvm/LTO/LTOBackend.h Tue Dec 13 19:17:59 2016
@@ -27,6 +27,7 @@
 
 namespace llvm {
 
+class BitcodeModule;
 class Error;
 class Module;
 class Target;
@@ -43,7 +44,7 @@ Error thinBackend(Config &C, unsigned Ta
                   ModuleSummaryIndex &CombinedIndex,
                   const FunctionImporter::ImportMapTy &ImportList,
                   const GVSummaryMapTy &DefinedGlobals,
-                  MapVector<StringRef, MemoryBufferRef> &ModuleMap);
+                  MapVector<StringRef, BitcodeModule> &ModuleMap);
 }
 }
 

Modified: llvm/trunk/lib/LTO/LTO.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTO.cpp?rev=289621&r1=289620&r2=289621&view=diff
==============================================================================
--- llvm/trunk/lib/LTO/LTO.cpp (original)
+++ llvm/trunk/lib/LTO/LTO.cpp Tue Dec 13 19:17:59 2016
@@ -214,6 +214,17 @@ void llvm::thinLTOInternalizeAndPromoteI
     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>> Inp
       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::getComd
   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 Backen
       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(SmallPtrS
 
 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
   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
     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
 
     // 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
 }
 
 // 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);
 

Modified: llvm/trunk/lib/LTO/LTOBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTOBackend.cpp?rev=289621&r1=289620&r2=289621&view=diff
==============================================================================
--- llvm/trunk/lib/LTO/LTOBackend.cpp (original)
+++ llvm/trunk/lib/LTO/LTOBackend.cpp Tue Dec 13 19:17:59 2016
@@ -318,7 +318,7 @@ Error lto::thinBackend(Config &Conf, uns
                        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, uns
   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);

Added: llvm/trunk/test/LTO/Resolution/X86/empty-bitcode.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LTO/Resolution/X86/empty-bitcode.test?rev=289621&view=auto
==============================================================================
--- llvm/trunk/test/LTO/Resolution/X86/empty-bitcode.test (added)
+++ llvm/trunk/test/LTO/Resolution/X86/empty-bitcode.test Tue Dec 13 19:17:59 2016
@@ -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

Modified: llvm/trunk/test/LTO/Resolution/X86/mixed_lto.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LTO/Resolution/X86/mixed_lto.ll?rev=289621&r1=289620&r2=289621&view=diff
==============================================================================
--- llvm/trunk/test/LTO/Resolution/X86/mixed_lto.ll (original)
+++ llvm/trunk/test/LTO/Resolution/X86/mixed_lto.ll Tue Dec 13 19:17:59 2016
@@ -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

Added: llvm/trunk/test/LTO/Resolution/X86/multi-thinlto.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LTO/Resolution/X86/multi-thinlto.ll?rev=289621&view=auto
==============================================================================
--- llvm/trunk/test/LTO/Resolution/X86/multi-thinlto.ll (added)
+++ llvm/trunk/test/LTO/Resolution/X86/multi-thinlto.ll Tue Dec 13 19:17:59 2016
@@ -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"




More information about the llvm-commits mailing list