llvm.org GIT mirror llvm / 0885016
LTO: Add support for multi-module bitcode files. Differential Revision: https://reviews.llvm.org/D27313 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@289621 91177308-0d34-0410-b5e6-96231b3b80d8 Peter Collingbourne 3 years ago
8 changed file(s) with 167 addition(s) and 76 deletion(s). Raw diff Collapse all Expand all
6868 StringRef getBuffer() const {
6969 return StringRef((const char *)Buffer.begin(), Buffer.size());
7070 }
71
72 StringRef getModuleIdentifier() const { return ModuleIdentifier; }
7173
7274 /// Read the bitcode module and prepare for lazy deserialization of function
7375 /// bodies. If ShouldLazyLoadMetadata is true, lazily load metadata as well.
3030
3131 namespace llvm {
3232
33 class BitcodeModule;
3334 class Error;
3435 class LLVMContext;
3536 class MemoryBufferRef;
7980
8081 // FIXME: Remove the LLVMContext once we have bitcode symbol tables.
8182 LLVMContext Ctx;
83 struct InputModule;
84 std::vector Mods;
8285 ModuleSymbolTable SymTab;
83 std::unique_ptr Mod;
84 MemoryBufferRef MBRef;
8586
8687 std::vector Comdats;
8788 DenseMap ComdatMap;
8889
8990 public:
91 ~InputFile();
92
9093 /// Create an InputFile.
9194 static Expected> create(MemoryBufferRef Object);
9295
216219 symbol_iterator(SymTab.symbols().end(), SymTab, this));
217220 }
218221
219 StringRef getSourceFileName() const { return Mod->getSourceFileName(); }
220 MemoryBufferRef getMemoryBufferRef() const { return MBRef; }
222 /// Returns the path to the InputFile.
223 StringRef getName() const;
224
225 /// Returns the source file path specified at compile time.
226 StringRef getSourceFileName() const;
221227
222228 // Returns a table with all the comdats used by this file.
223229 ArrayRef getComdatTable() const { return Comdats; }
230
231 private:
232 iterator_range module_symbols(InputModule &IM);
224233 };
225234
226235 /// This class wraps an output stream for a native object. Most clients should
310319 /// Until that is fixed, a Config argument is required.
311320 LTO(Config Conf, ThinBackend Backend = nullptr,
312321 unsigned ParallelCodeGenParallelismLevel = 1);
322 ~LTO();
313323
314324 /// Add an input file to the LTO link, using the provided symbol resolutions.
315325 /// The symbol resolutions must appear in the enumeration order given by
356366
357367 ThinBackend Backend;
358368 ModuleSummaryIndex CombinedIndex;
359 MapVectorMemoryBufferRef> ModuleMap;
369 MapVectorBitcodeModule> ModuleMap;
360370 DenseMap PrevailingModuleForGUID;
361371 } ThinLTO;
362372
404414 const InputFile::Symbol &Sym, SymbolResolution Res,
405415 unsigned Partition);
406416
407 Error addRegularLTO(std::unique_ptr Input,
408 ArrayRef Res);
409 Error addThinLTO(std::unique_ptr Input,
410 ArrayRef Res);
417 // These functions take a range of symbol resolutions [ResI, ResE) and consume
418 // the resolutions used by a single input module by incrementing ResI. After
419 // these functions return, [ResI, ResE) will refer to the resolution range for
420 // the remaining modules in the InputFile.
421 Error addModule(InputFile &Input, InputFile::InputModule &IM,
422 const SymbolResolution *&ResI, const SymbolResolution *ResE);
423 Error addRegularLTO(BitcodeModule BM, const SymbolResolution *&ResI,
424 const SymbolResolution *ResE);
425 Error addThinLTO(BitcodeModule BM, Module &M,
426 iterator_range Syms,
427 const SymbolResolution *&ResI, const SymbolResolution *ResE);
411428
412429 Error runRegularLTO(AddStreamFn AddStream);
413430 Error runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache,
2626
2727 namespace llvm {
2828
29 class BitcodeModule;
2930 class Error;
3031 class Module;
3132 class Target;
4243 ModuleSummaryIndex &CombinedIndex,
4344 const FunctionImporter::ImportMapTy &ImportList,
4445 const GVSummaryMapTy &DefinedGlobals,
45 MapVectorMemoryBufferRef> &ModuleMap);
46 MapVectorBitcodeModule> &ModuleMap);
4647 }
4748 }
4849
213213 thinLTOInternalizeAndPromoteGUID(I.second, I.first, isExported);
214214 }
215215
216 struct InputFile::InputModule {
217 BitcodeModule BM;
218 std::unique_ptr Mod;
219
220 // The range of ModuleSymbolTable entries for this input module.
221 size_t SymBegin, SymEnd;
222 };
223
224 // Requires a destructor for std::vector.
225 InputFile::~InputFile() = default;
226
216227 Expected> InputFile::create(MemoryBufferRef Object) {
217228 std::unique_ptr File(new InputFile);
218229
220231 IRObjectFile::findBitcodeInMemBuffer(Object);
221232 if (!BCOrErr)
222233 return errorCodeToError(BCOrErr.getError());
223 File->MBRef = *BCOrErr;
224
225 Expected> MOrErr =
226 getLazyBitcodeModule(*BCOrErr, File->Ctx,
227 /*ShouldLazyLoadMetadata*/ true);
228 if (!MOrErr)
229 return MOrErr.takeError();
230
231 File->Mod = std::move(*MOrErr);
232 File->SymTab.addModule(File->Mod.get());
233
234 for (const auto &C : File->Mod->getComdatSymbolTable()) {
235 auto P =
236 File->ComdatMap.insert(std::make_pair(&C.second, File->Comdats.size()));
237 assert(P.second);
238 (void)P;
239 File->Comdats.push_back(C.first());
234
235 Expected> BMsOrErr =
236 getBitcodeModuleList(*BCOrErr);
237 if (!BMsOrErr)
238 return BMsOrErr.takeError();
239
240 if (BMsOrErr->empty())
241 return make_error("Bitcode file does not contain any modules",
242 inconvertibleErrorCode());
243
244 // Create an InputModule for each module in the InputFile, and add it to the
245 // ModuleSymbolTable.
246 for (auto BM : *BMsOrErr) {
247 Expected> MOrErr =
248 BM.getLazyModule(File->Ctx, /*ShouldLazyLoadMetadata*/ true);
249 if (!MOrErr)
250 return MOrErr.takeError();
251
252 size_t SymBegin = File->SymTab.symbols().size();
253 File->SymTab.addModule(MOrErr->get());
254 size_t SymEnd = File->SymTab.symbols().size();
255
256 for (const auto &C : (*MOrErr)->getComdatSymbolTable()) {
257 auto P = File->ComdatMap.insert(
258 std::make_pair(&C.second, File->Comdats.size()));
259 assert(P.second);
260 (void)P;
261 File->Comdats.push_back(C.first());
262 }
263
264 File->Mods.push_back({BM, std::move(*MOrErr), SymBegin, SymEnd});
240265 }
241266
242267 return std::move(File);
257282 return -1;
258283 }
259284
285 StringRef InputFile::getName() const {
286 return Mods[0].BM.getModuleIdentifier();
287 }
288
289 StringRef InputFile::getSourceFileName() const {
290 return Mods[0].Mod->getSourceFileName();
291 }
292
293 iterator_range
294 InputFile::module_symbols(InputModule &IM) {
295 return llvm::make_range(
296 symbol_iterator(SymTab.symbols().data() + IM.SymBegin, SymTab, this),
297 symbol_iterator(SymTab.symbols().data() + IM.SymEnd, SymTab, this));
298 }
299
260300 LTO::RegularLTOState::RegularLTOState(unsigned ParallelCodeGenParallelismLevel,
261301 Config &Conf)
262302 : ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel),
273313 : Conf(std::move(Conf)),
274314 RegularLTO(ParallelCodeGenParallelismLevel, this->Conf),
275315 ThinLTO(std::move(Backend)) {}
316
317 // Requires a destructor for MapVector.
318 LTO::~LTO() = default;
276319
277320 // Add the given symbol to the GlobalResolutions map, and resolve its partition.
278321 void LTO::addSymbolToGlobalRes(SmallPtrSet &Used,
296339
297340 static void writeToResolutionFile(raw_ostream &OS, InputFile *Input,
298341 ArrayRef Res) {
299 StringRef Path = Input->getMemoryBufferRef().getBufferIdentifier();
342 StringRef Path = Input->getName();
300343 OS << Path << '\n';
301344 auto ResI = Res.begin();
302345 for (const InputFile::Symbol &Sym : Input->symbols()) {
322365 if (Conf.ResolutionFile)
323366 writeToResolutionFile(*Conf.ResolutionFile, Input.get(), Res);
324367
368 const SymbolResolution *ResI = Res.begin();
369 for (InputFile::InputModule &IM : Input->Mods)
370 if (Error Err = addModule(*Input, IM, ResI, Res.end()))
371 return Err;
372
373 assert(ResI == Res.end());
374 return Error::success();
375 }
376
377 Error LTO::addModule(InputFile &Input, InputFile::InputModule &IM,
378 const SymbolResolution *&ResI,
379 const SymbolResolution *ResE) {
325380 // FIXME: move to backend
326 Module &M = *Input->Mod;
381 Module &M = *IM.Mod;
327382 if (!Conf.OverrideTriple.empty())
328383 M.setTargetTriple(Conf.OverrideTriple);
329384 else if (M.getTargetTriple().empty())
330385 M.setTargetTriple(Conf.DefaultTriple);
331386
332 Expected HasThinLTOSummary = hasGlobalValueSummary(Input->MBRef);
387 Expected HasThinLTOSummary = IM.BM.hasSummary();
333388 if (!HasThinLTOSummary)
334389 return HasThinLTOSummary.takeError();
335390
336391 if (*HasThinLTOSummary)
337 return addThinLTO(std::move(Input), Res);
392 return addThinLTO(IM.BM, M, Input.module_symbols(IM), ResI, ResE);
338393 else
339 return addRegularLTO(std::move(Input), Res);
394 return addRegularLTO(IM.BM, ResI, ResE);
340395 }
341396
342397 // Add a regular LTO object to the link.
343 Error LTO::addRegularLTO(std::unique_ptr Input,
344 ArrayRef Res) {
398 Error LTO::addRegularLTO(BitcodeModule BM, const SymbolResolution *&ResI,
399 const SymbolResolution *ResE) {
345400 if (!RegularLTO.CombinedModule) {
346401 RegularLTO.CombinedModule =
347402 llvm::make_unique("ld-temp.o", RegularLTO.Ctx);
348403 RegularLTO.Mover = llvm::make_unique(*RegularLTO.CombinedModule);
349404 }
350405 Expected> MOrErr =
351 getLazyBitcodeModule(Input->MBRef, RegularLTO.Ctx,
352 /*ShouldLazyLoadMetadata*/ true);
406 BM.getLazyModule(RegularLTO.Ctx, /*ShouldLazyLoadMetadata*/ true);
353407 if (!MOrErr)
354408 return MOrErr.takeError();
355409
370424 if (GV.hasAppendingLinkage())
371425 Keep.push_back(&GV);
372426
373 auto ResI = Res.begin();
374427 for (const InputFile::Symbol &Sym :
375428 make_range(InputFile::symbol_iterator(SymTab.symbols().begin(), SymTab,
376429 nullptr),
377430 InputFile::symbol_iterator(SymTab.symbols().end(), SymTab,
378431 nullptr))) {
379 assert(ResI != Res.end());
432 assert(ResI != ResE);
380433 SymbolResolution Res = *ResI++;
381434 addSymbolToGlobalRes(Used, Sym, Res, 0);
382435
410463
411464 // FIXME: use proposed local attribute for FinalDefinitionInLinkageUnit.
412465 }
413 assert(ResI == Res.end());
414466
415467 return RegularLTO.Mover->move(std::move(*MOrErr), Keep,
416468 [](GlobalValue &, IRMover::ValueAdder) {},
419471 }
420472
421473 // Add a ThinLTO object to the link.
422 Error LTO::addThinLTO(std::unique_ptr Input,
423 ArrayRef Res) {
424 Module &M = *Input->Mod;
474 // FIXME: This function should not need to take as many parameters once we have
475 // a bitcode symbol table.
476 Error LTO::addThinLTO(BitcodeModule BM, Module &M,
477 iterator_range Syms,
478 const SymbolResolution *&ResI,
479 const SymbolResolution *ResE) {
425480 SmallPtrSet Used;
426481 collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false);
427482
428 MemoryBufferRef MBRef = Input->MBRef;
429 Expected>
430 SummaryObjOrErr = object::ModuleSummaryIndexObjectFile::create(MBRef);
431 if (!SummaryObjOrErr)
432 return SummaryObjOrErr.takeError();
433 ThinLTO.CombinedIndex.mergeFrom((*SummaryObjOrErr)->takeIndex(),
483 Expected> SummaryOrErr = BM.getSummary();
484 if (!SummaryOrErr)
485 return SummaryOrErr.takeError();
486 ThinLTO.CombinedIndex.mergeFrom(std::move(*SummaryOrErr),
434487 ThinLTO.ModuleMap.size());
435488
436 auto ResI = Res.begin();
437 for (const InputFile::Symbol &Sym : Input->symbols()) {
438 assert(ResI != Res.end());
489 for (const InputFile::Symbol &Sym : Syms) {
490 assert(ResI != ResE);
439491 SymbolResolution Res = *ResI++;
440492 addSymbolToGlobalRes(Used, Sym, Res, ThinLTO.ModuleMap.size() + 1);
441493
442494 if (Res.Prevailing && Sym.isGV())
443495 ThinLTO.PrevailingModuleForGUID[Sym.getGV()->getGUID()] =
444 MBRef.getBufferIdentifier();
445 }
446 assert(ResI == Res.end());
447
448 ThinLTO.ModuleMap[MBRef.getBufferIdentifier()] = MBRef;
496 BM.getModuleIdentifier();
497 }
498
499 if (!ThinLTO.ModuleMap.insert({BM.getModuleIdentifier(), BM}).second)
500 return make_error(
501 "Expected at most one ThinLTO module per bitcode file",
502 inconvertibleErrorCode());
503
449504 return Error::success();
450505 }
451506
542597
543598 virtual ~ThinBackendProc() {}
544599 virtual Error start(
545 unsigned Task, MemoryBufferRef MBRef,
600 unsigned Task, BitcodeModule BM,
546601 const FunctionImporter::ImportMapTy &ImportList,
547602 const FunctionImporter::ExportSetTy &ExportList,
548603 const std::map &ResolvedODR,
549 MapVectorMemoryBufferRef> &ModuleMap) = 0;
604 MapVectorBitcodeModule> &ModuleMap) = 0;
550605 virtual Error wait() = 0;
551606 };
552607
571626
572627 Error runThinLTOBackendThread(
573628 AddStreamFn AddStream, NativeObjectCache Cache, unsigned Task,
574 MemoryBufferRef MBRef, ModuleSummaryIndex &CombinedIndex,
629 BitcodeModule BM, ModuleSummaryIndex &CombinedIndex,
575630 const FunctionImporter::ImportMapTy &ImportList,
576631 const FunctionImporter::ExportSetTy &ExportList,
577632 const std::map &ResolvedODR,
578633 const GVSummaryMapTy &DefinedGlobals,
579 MapVectorMemoryBufferRef> &ModuleMap) {
634 MapVectorBitcodeModule> &ModuleMap) {
580635 auto RunThinBackend = [&](AddStreamFn AddStream) {
581636 LTOLLVMContext BackendContext(Conf);
582 Expected> MOrErr =
583 parseBitcodeFile(MBRef, BackendContext);
637 Expected> MOrErr = BM.parseModule(BackendContext);
584638 if (!MOrErr)
585639 return MOrErr.takeError();
586640
588642 ImportList, DefinedGlobals, ModuleMap);
589643 };
590644
591 auto ModuleID = MBRef.getBufferIdentifier();
645 auto ModuleID = BM.getModuleIdentifier();
592646
593647 if (!Cache || !CombinedIndex.modulePaths().count(ModuleID) ||
594648 all_of(CombinedIndex.getModuleHash(ModuleID),
608662 }
609663
610664 Error start(
611 unsigned Task, MemoryBufferRef MBRef,
665 unsigned Task, BitcodeModule BM,
612666 const FunctionImporter::ImportMapTy &ImportList,
613667 const FunctionImporter::ExportSetTy &ExportList,
614668 const std::map &ResolvedODR,
615 MapVector &ModuleMap) override {
616 StringRef ModulePath = MBRef.getBufferIdentifier();
669 MapVector &ModuleMap) override {
670 StringRef ModulePath = BM.getModuleIdentifier();
617671 assert(ModuleToDefinedGVSummaries.count(ModulePath));
618672 const GVSummaryMapTy &DefinedGlobals =
619673 ModuleToDefinedGVSummaries.find(ModulePath)->second;
620674 BackendThreadPool.async(
621 [=](MemoryBufferRef MBRef, ModuleSummaryIndex &CombinedIndex,
675 [=](BitcodeModule BM, ModuleSummaryIndex &CombinedIndex,
622676 const FunctionImporter::ImportMapTy &ImportList,
623677 const FunctionImporter::ExportSetTy &ExportList,
624678 const std::map
625679 &ResolvedODR,
626680 const GVSummaryMapTy &DefinedGlobals,
627 MapVectorMemoryBufferRef> &ModuleMap) {
681 MapVectorBitcodeModule> &ModuleMap) {
628682 Error E = runThinLTOBackendThread(
629 AddStream, Cache, Task, MBRef, CombinedIndex, ImportList,
683 AddStream, Cache, Task, BM, CombinedIndex, ImportList,
630684 ExportList, ResolvedODR, DefinedGlobals, ModuleMap);
631685 if (E) {
632686 std::unique_lock L(ErrMu);
636690 Err = std::move(E);
637691 }
638692 },
639 MBRef, std::ref(CombinedIndex), std::ref(ImportList),
693 BM, std::ref(CombinedIndex), std::ref(ImportList),
640694 std::ref(ExportList), std::ref(ResolvedODR), std::ref(DefinedGlobals),
641695 std::ref(ModuleMap));
642696 return Error::success();
702756 LinkedObjectsFileName(LinkedObjectsFileName) {}
703757
704758 Error start(
705 unsigned Task, MemoryBufferRef MBRef,
759 unsigned Task, BitcodeModule BM,
706760 const FunctionImporter::ImportMapTy &ImportList,
707761 const FunctionImporter::ExportSetTy &ExportList,
708762 const std::map &ResolvedODR,
709 MapVector &ModuleMap) override {
710 StringRef ModulePath = MBRef.getBufferIdentifier();
763 MapVector &ModuleMap) override {
764 StringRef ModulePath = BM.getModuleIdentifier();
711765 std::string NewModulePath =
712766 getThinLTOOutputFile(ModulePath, OldPrefix, NewPrefix);
713767
317317 Module &Mod, ModuleSummaryIndex &CombinedIndex,
318318 const FunctionImporter::ImportMapTy &ImportList,
319319 const GVSummaryMapTy &DefinedGlobals,
320 MapVectorMemoryBufferRef> &ModuleMap) {
320 MapVectorBitcodeModule> &ModuleMap) {
321321 Expected TOrErr = initAndLookupTarget(Conf, Mod);
322322 if (!TOrErr)
323323 return TOrErr.takeError();
352352 auto ModuleLoader = [&](StringRef Identifier) {
353353 assert(Mod.getContext().isODRUniquingDebugTypes() &&
354354 "ODR Type uniquing should be enabled on the context");
355 return getLazyBitcodeModule(ModuleMap[Identifier], Mod.getContext(),
356 /*ShouldLazyLoadMetadata=*/true);
355 auto I = ModuleMap.find(Identifier);
356 assert(I != ModuleMap.end());
357 return I->second.getLazyModule(Mod.getContext(),
358 /*ShouldLazyLoadMetadata=*/true);
357359 };
358360
359361 FunctionImporter Importer(CombinedIndex, ModuleLoader);
0 RUN: llvm-cat -o %t.o
1 RUN: not llvm-lto2 -o %t2 %t.o 2>&1 | FileCheck %s
2 CHECK: Bitcode file does not contain any modules
1212 ; NM1-DAG: T main
1313 ; NM1-DAG: U g
1414
15 ; Do the same test again, but with the regular and thin LTO modules in the same file.
16 ; RUN: llvm-cat -b -o %t4.o %t2.o %t1.o
17 ; RUN: llvm-lto2 -o %t5.o %t4.o -r %t4.o,main,px -r %t4.o,g, -r %t4.o,g,px
18 ; RUN: llvm-nm %t5.o.0 | FileCheck %s --check-prefix=NM0
19 ; RUN: llvm-nm %t5.o.1 | FileCheck %s --check-prefix=NM1
20
1521 target triple = "x86_64-unknown-linux-gnu"
1622 define i32 @g() {
1723 ret i32 0
0 ; RUN: opt -module-summary %s -o %t.o
1 ; RUN: llvm-cat -b -o %t2.o %t.o %t.o
2 ; RUN: not llvm-lto2 -o %t3.o %t2.o 2>&1 | FileCheck %s
3 ; CHECK: Expected at most one ThinLTO module per bitcode file
4
5 target triple = "x86_64-unknown-linux-gnu"