llvm.org GIT mirror llvm / f8c4f81
[ThinLTO] Fix ThinLTOCodegenerator to export llvm.used symbols Summary: Reapply r357931 with fixes to ThinLTO testcases and llvm-lto tool. ThinLTOCodeGenerator currently does not preserve llvm.used symbols and it can internalize them. In order to pass the necessary information to the legacy ThinLTOCodeGenerator, the input to the code generator is rewritten to be based on lto::InputFile. Now ThinLTO using the legacy LTO API will requires data layout in Module. "internalize" thinlto action in llvm-lto is updated to run both "promote" and "internalize" with the same configuration as ThinLTOCodeGenerator. The old "promote" + "internalize" option does not produce the same output as ThinLTOCodeGenerator. This fixes: PR41236 rdar://problem/49293439 Reviewers: tejohnson, pcc, kromanova, dexonsmith Reviewed By: tejohnson Subscribers: ormris, bd1976llvm, mehdi_amini, inglorion, eraman, hiraditya, jkorous, dexonsmith, arphaman, dang, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D60421 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358601 91177308-0d34-0410-b5e6-96231b3b80d8 Steven Wu 1 year, 7 months ago
26 changed file(s) with 231 addition(s) and 116 deletion(s). Raw diff Collapse all Expand all
130130 using irsymtab::Symbol::isWeak;
131131 using irsymtab::Symbol::isIndirect;
132132 using irsymtab::Symbol::getName;
133 using irsymtab::Symbol::getIRName;
133134 using irsymtab::Symbol::getVisibility;
134135 using irsymtab::Symbol::canBeOmittedFromSymbolTable;
135136 using irsymtab::Symbol::isTLS;
159160
160161 // Returns a table with all the comdats used by this file.
161162 ArrayRef getComdatTable() const { return ComdatTable; }
163
164 // Returns the only BitcodeModule from InputFile.
165 BitcodeModule &getSingleBitcodeModule();
162166
163167 private:
164168 ArrayRef module_symbols(unsigned I) const {
1818 #include "llvm/ADT/StringSet.h"
1919 #include "llvm/ADT/Triple.h"
2020 #include "llvm/IR/ModuleSummaryIndex.h"
21 #include "llvm/LTO/LTO.h"
2122 #include "llvm/Support/CachePruning.h"
2223 #include "llvm/Support/CodeGen.h"
2324 #include "llvm/Support/MemoryBuffer.h"
2930 class StringRef;
3031 class LLVMContext;
3132 class TargetMachine;
32
33 /// Wrapper around MemoryBufferRef, owning the identifier
34 class ThinLTOBuffer {
35 std::string OwnedIdentifier;
36 StringRef Buffer;
37
38 public:
39 ThinLTOBuffer(StringRef Buffer, StringRef Identifier)
40 : OwnedIdentifier(Identifier), Buffer(Buffer) {}
41
42 MemoryBufferRef getMemBuffer() const {
43 return MemoryBufferRef(Buffer,
44 {OwnedIdentifier.c_str(), OwnedIdentifier.size()});
45 }
46 StringRef getBuffer() const { return Buffer; }
47 StringRef getBufferIdentifier() const { return OwnedIdentifier; }
48 };
4933
5034 /// Helper to gather options relevant to the target machine creation
5135 struct TargetMachineBuilder {
266250 * and additionally resolve weak and linkonce symbols.
267251 * Index is updated to reflect linkage changes from weak resolution.
268252 */
269 void promote(Module &Module, ModuleSummaryIndex &Index);
253 void promote(Module &Module, ModuleSummaryIndex &Index,
254 const lto::InputFile &File);
270255
271256 /**
272257 * Compute and emit the imported files for module at \p ModulePath.
273258 */
274259 void emitImports(Module &Module, StringRef OutputName,
275 ModuleSummaryIndex &Index);
260 ModuleSummaryIndex &Index,
261 const lto::InputFile &File);
276262
277263 /**
278264 * Perform cross-module importing for the module identified by
279265 * ModuleIdentifier.
280266 */
281 void crossModuleImport(Module &Module, ModuleSummaryIndex &Index);
267 void crossModuleImport(Module &Module, ModuleSummaryIndex &Index,
268 const lto::InputFile &File);
282269
283270 /**
284271 * Compute the list of summaries needed for importing into module.
285272 */
286273 void gatherImportedSummariesForModule(
287274 Module &Module, ModuleSummaryIndex &Index,
288 std::map &ModuleToSummariesForIndex);
275 std::map &ModuleToSummariesForIndex,
276 const lto::InputFile &File);
289277
290278 /**
291279 * Perform internalization. Index is updated to reflect linkage changes.
292280 */
293 void internalize(Module &Module, ModuleSummaryIndex &Index);
281 void internalize(Module &Module, ModuleSummaryIndex &Index,
282 const lto::InputFile &File);
294283
295284 /**
296285 * Perform post-importing ThinLTO optimizations.
312301
313302 /// Vector holding the input buffers containing the bitcode modules to
314303 /// process.
315 std::vector<ThinLTOBuffer> Modules;
304 std::vector<std::unique_ptr> Modules;
316305
317306 /// Set of symbols that need to be preserved outside of the set of bitcode
318307 /// files.
419419 return Mods[0].getModuleIdentifier();
420420 }
421421
422 BitcodeModule &InputFile::getSingleBitcodeModule() {
423 assert(Mods.size() == 1 && "Expect only one bitcode module");
424 return Mods[0];
425 }
426
422427 LTO::RegularLTOState::RegularLTOState(unsigned ParallelCodeGenParallelismLevel,
423428 Config &Conf)
424429 : ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel),
134134 }
135135 }
136136
137 static StringMap
138 generateModuleMap(const std::vector &Modules) {
139 StringMap ModuleMap;
140 for (auto &ModuleBuffer : Modules) {
141 assert(ModuleMap.find(ModuleBuffer.getBufferIdentifier()) ==
142 ModuleMap.end() &&
137 static StringMap
138 generateModuleMap(std::vector> &Modules) {
139 StringMap ModuleMap;
140 for (auto &M : Modules) {
141 assert(ModuleMap.find(M->getName()) == ModuleMap.end() &&
143142 "Expect unique Buffer Identifier");
144 ModuleMap[ModuleBuffer.getBufferIdentifier()] = ModuleBuffer.getMemBuffer();
143 ModuleMap[M->getName()] = M.get();
145144 }
146145 return ModuleMap;
147146 }
174173 }
175174 }
176175
177 static std::unique_ptr
178 loadModuleFromBuffer(const MemoryBufferRef &Buffer, LLVMContext &Context,
179 bool Lazy, bool IsImporting) {
176 static std::unique_ptr loadModuleFromInput(lto::InputFile *Input,
177 LLVMContext &Context,
178 bool Lazy,
179 bool IsImporting) {
180 auto &Mod = Input->getSingleBitcodeModule();
180181 SMDiagnostic Err;
181182 Expected> ModuleOrErr =
182 Lazy
183 ? getLazyBitcodeModule(Buffer, Context,
184 /* ShouldLazyLoadMetadata */ true, IsImporting)
185 : parseBitcodeFile(Buffer, Context);
183 Lazy ? Mod.getLazyModule(Context,
184 /* ShouldLazyLoadMetadata */ true, IsImporting)
185 : Mod.parseModule(Context);
186186 if (!ModuleOrErr) {
187187 handleAllErrors(ModuleOrErr.takeError(), [&](ErrorInfoBase &EIB) {
188 SMDiagnostic Err = SMDiagnostic(Buffer.getBufferIdentifier(),
188 SMDiagnostic Err = SMDiagnostic(Mod.getModuleIdentifier(),
189189 SourceMgr::DK_Error, EIB.message());
190190 Err.print("ThinLTO", errs());
191191 });
193193 }
194194 if (!Lazy)
195195 verifyLoadedModule(*ModuleOrErr.get());
196 return std::move(ModuleOrErr.get());
196 return std::move(*ModuleOrErr);
197197 }
198198
199199 static void
200200 crossImportIntoModule(Module &TheModule, const ModuleSummaryIndex &Index,
201 StringMap<MemoryBufferRef> &ModuleMap,
201 StringMap<lto::InputFile*> &ModuleMap,
202202 const FunctionImporter::ImportMapTy &ImportList) {
203203 auto Loader = [&](StringRef Identifier) {
204 return loadModuleFromBuffer(ModuleMap[Identifier], TheModule.getContext(),
205 /*Lazy=*/true, /*IsImporting*/ true);
204 auto &Input = ModuleMap[Identifier];
205 return loadModuleFromInput(Input, TheModule.getContext(),
206 /*Lazy=*/true, /*IsImporting*/ true);
206207 };
207208
208209 FunctionImporter Importer(Index, Loader);
245246 PMB.populateThinLTOPassManager(PM);
246247
247248 PM.run(TheModule);
249 }
250
251 static void
252 addUsedSymbolToPreservedGUID(const lto::InputFile &File,
253 DenseSet &PreservedGUID) {
254 for (const auto &Sym : File.symbols()) {
255 if (Sym.isUsed())
256 PreservedGUID.insert(GlobalValue::getGUID(Sym.getIRName()));
257 }
248258 }
249259
250260 // Convert the PreservedSymbols map from "Name" based to "GUID" based.
380390
381391 static std::unique_ptr
382392 ProcessThinLTOModule(Module &TheModule, ModuleSummaryIndex &Index,
383 StringMap<MemoryBufferRef> &ModuleMap, TargetMachine &TM,
393 StringMap<lto::InputFile *> &ModuleMap, TargetMachine &TM,
384394 const FunctionImporter::ImportMapTy &ImportList,
385395 const FunctionImporter::ExportSetTy &ExportList,
386396 const DenseSet &GUIDPreservedSymbols,
487497 } // end anonymous namespace
488498
489499 void ThinLTOCodeGenerator::addModule(StringRef Identifier, StringRef Data) {
490 ThinLTOBuffer Buffer(Data, Identifier);
491 LLVMContext Context;
492 StringRef TripleStr;
493 ErrorOr TripleOrErr = expectedToErrorOrAndEmitErrors(
494 Context, getBitcodeTargetTriple(Buffer.getMemBuffer()));
495
496 if (TripleOrErr)
497 TripleStr = *TripleOrErr;
498
500 MemoryBufferRef Buffer(Data, Identifier);
501
502 auto InputOrError = lto::InputFile::create(Buffer);
503 if (!InputOrError)
504 report_fatal_error("ThinLTO cannot create input file: " +
505 toString(InputOrError.takeError()));
506
507 auto TripleStr = (*InputOrError)->getTargetTriple();
499508 Triple TheTriple(TripleStr);
500509
501510 if (Modules.empty())
507516 initTMBuilder(TMBuilder, Triple(TMBuilder.TheTriple.merge(TheTriple)));
508517 }
509518
510 Modules.push_back(Buffer);
519 Modules.emplace_back(std::move(*InputOrError));
511520 }
512521
513522 void ThinLTOCodeGenerator::preserveSymbol(StringRef Name) {
548557 std::unique_ptr CombinedIndex =
549558 llvm::make_unique(/*HaveGVs=*/false);
550559 uint64_t NextModuleId = 0;
551 for (auto &ModuleBuffer : Modules) {
552 if (Error Err = readModuleSummaryIndex(ModuleBuffer.getMemBuffer(),
553 *CombinedIndex, NextModuleId++)) {
560 for (auto &Mod : Modules) {
561 auto &M = Mod->getSingleBitcodeModule();
562 if (Error Err =
563 M.readSummary(*CombinedIndex, Mod->getName(), NextModuleId++)) {
554564 // FIXME diagnose
555565 logAllUnhandledErrors(
556566 std::move(Err), errs(),
592602 * Perform promotion and renaming of exported internal functions.
593603 * Index is updated to reflect linkage changes from weak resolution.
594604 */
595 void ThinLTOCodeGenerator::promote(Module &TheModule,
596 ModuleSummaryIndex &Index) {
605 void ThinLTOCodeGenerator::promote(Module &TheModule, ModuleSummaryIndex &Index,
606 const lto::InputFile &File) {
597607 auto ModuleCount = Index.modulePaths().size();
598608 auto ModuleIdentifier = TheModule.getModuleIdentifier();
599609
604614 // Convert the preserved symbols set from string to GUID
605615 auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
606616 PreservedSymbols, Triple(TheModule.getTargetTriple()));
617
618 // Add used symbol to the preserved symbols.
619 addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
607620
608621 // Compute "dead" symbols, we don't want to import/export these!
609622 computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
632645 * Perform cross-module importing for the module identified by ModuleIdentifier.
633646 */
634647 void ThinLTOCodeGenerator::crossModuleImport(Module &TheModule,
635 ModuleSummaryIndex &Index) {
648 ModuleSummaryIndex &Index,
649 const lto::InputFile &File) {
636650 auto ModuleMap = generateModuleMap(Modules);
637651 auto ModuleCount = Index.modulePaths().size();
638652
643657 // Convert the preserved symbols set from string to GUID
644658 auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
645659 PreservedSymbols, Triple(TheModule.getTargetTriple()));
660
661 addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
646662
647663 // Compute "dead" symbols, we don't want to import/export these!
648664 computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
662678 */
663679 void ThinLTOCodeGenerator::gatherImportedSummariesForModule(
664680 Module &TheModule, ModuleSummaryIndex &Index,
665 std::map &ModuleToSummariesForIndex) {
681 std::map &ModuleToSummariesForIndex,
682 const lto::InputFile &File) {
666683 auto ModuleCount = Index.modulePaths().size();
667684 auto ModuleIdentifier = TheModule.getModuleIdentifier();
668685
673690 // Convert the preserved symbols set from string to GUID
674691 auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
675692 PreservedSymbols, Triple(TheModule.getTargetTriple()));
693
694 addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
676695
677696 // Compute "dead" symbols, we don't want to import/export these!
678697 computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
692711 * Emit the list of files needed for importing into module.
693712 */
694713 void ThinLTOCodeGenerator::emitImports(Module &TheModule, StringRef OutputName,
695 ModuleSummaryIndex &Index) {
714 ModuleSummaryIndex &Index,
715 const lto::InputFile &File) {
696716 auto ModuleCount = Index.modulePaths().size();
697717 auto ModuleIdentifier = TheModule.getModuleIdentifier();
698718
703723 // Convert the preserved symbols set from string to GUID
704724 auto GUIDPreservedSymbols = computeGUIDPreservedSymbols(
705725 PreservedSymbols, Triple(TheModule.getTargetTriple()));
726
727 addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
706728
707729 // Compute "dead" symbols, we don't want to import/export these!
708730 computeDeadSymbolsInIndex(Index, GUIDPreservedSymbols);
726748 }
727749
728750 /**
729 * Perform internalization. Index is updated to reflect linkage changes.
751 * Perform internalization. Runs promote and internalization together.
752 * Index is updated to reflect linkage changes.
730753 */
731754 void ThinLTOCodeGenerator::internalize(Module &TheModule,
732 ModuleSummaryIndex &Index) {
755 ModuleSummaryIndex &Index,
756 const lto::InputFile &File) {
733757 initTMBuilder(TMBuilder, Triple(TheModule.getTargetTriple()));
734758 auto ModuleCount = Index.modulePaths().size();
735759 auto ModuleIdentifier = TheModule.getModuleIdentifier();
737761 // Convert the preserved symbols set from string to GUID
738762 auto GUIDPreservedSymbols =
739763 computeGUIDPreservedSymbols(PreservedSymbols, TMBuilder.TheTriple);
764
765 addUsedSymbolToPreservedGUID(File, GUIDPreservedSymbols);
740766
741767 // Collect for each module the list of function it defines (GUID -> Summary).
742768 StringMap ModuleToDefinedGVSummaries(ModuleCount);
757783 if (ExportList.empty() && GUIDPreservedSymbols.empty())
758784 return;
759785
786 // Resolve prevailing symbols
787 StringMap> ResolvedODR;
788 resolvePrevailingInIndex(Index, ResolvedODR);
789
790 // Promote the exported values in the index, so that they are promoted
791 // in the module.
792 internalizeAndPromoteInIndex(ExportLists, GUIDPreservedSymbols, Index);
793
794 promoteModule(TheModule, Index);
795
760796 // Internalization
761 internalizeAndPromoteInIndex(ExportLists, GUIDPreservedSymbols, Index);
797 thinLTOResolvePrevailingInModule(
798 TheModule, ModuleToDefinedGVSummaries[ModuleIdentifier]);
799
762800 thinLTOInternalizeModule(TheModule,
763801 ModuleToDefinedGVSummaries[ModuleIdentifier]);
764802 }
829867 // Perform only parallel codegen and return.
830868 ThreadPool Pool;
831869 int count = 0;
832 for (auto &ModuleBuffer : Modules) {
870 for (auto &Mod : Modules) {
833871 Pool.async([&](int count) {
834872 LLVMContext Context;
835873 Context.setDiscardValueNames(LTODiscardValueNames);
836874
837875 // Parse module now
838 auto TheModule =
839 loadModuleFromBuffer(ModuleBuffer.getMemBuffer(), Context, false,
840 /*IsImporting*/ false);
876 auto TheModule = loadModuleFromInput(Mod.get(), Context, false,
877 /*IsImporting*/ false);
841878
842879 // CodeGen
843880 auto OutputBuffer = codegenModule(*TheModule, *TMBuilder.create());
880917 auto GUIDPreservedSymbols =
881918 computeGUIDPreservedSymbols(PreservedSymbols, TMBuilder.TheTriple);
882919
920 // Add used symbol from inputs to the preserved symbols.
921 for (const auto &M : Modules)
922 addUsedSymbolToPreservedGUID(*M, GUIDPreservedSymbols);
923
883924 // Compute "dead" symbols, we don't want to import/export these!
884925 computeDeadSymbolsInIndex(*Index, GUIDPreservedSymbols);
885926
912953 // GVSummary and ResolvedODR maps to enable threaded access to these maps
913954 // below.
914955 for (auto &Module : Modules) {
915 auto ModuleIdentifier = Module.getBufferIdentifier();
956 auto ModuleIdentifier = Module->getName();
916957 ExportLists[ModuleIdentifier];
917958 ImportLists[ModuleIdentifier];
918959 ResolvedODR[ModuleIdentifier];
926967 ModulesOrdering.resize(Modules.size());
927968 std::iota(ModulesOrdering.begin(), ModulesOrdering.end(), 0);
928969 llvm::sort(ModulesOrdering, [&](int LeftIndex, int RightIndex) {
929 auto LSize = Modules[LeftIndex].getBuffer().size();
930 auto RSize = Modules[RightIndex].getBuffer().size();
970 auto LSize =
971 Modules[LeftIndex]->getSingleBitcodeModule().getBuffer().size();
972 auto RSize =
973 Modules[RightIndex]->getSingleBitcodeModule().getBuffer().size();
931974 return LSize > RSize;
932975 });
933976
935978 {
936979 ThreadPool Pool(ThreadCount);
937980 for (auto IndexCount : ModulesOrdering) {
938 auto &ModuleBuffer = Modules[IndexCount];
981 auto &Mod = Modules[IndexCount];
939982 Pool.async([&](int count) {
940 auto ModuleIdentifier = ModuleBuffer.getBufferIdentifier();
983 auto ModuleIdentifier = Mod->getName();
941984 auto &ExportList = ExportLists[ModuleIdentifier];
942985
943986 auto &DefinedGVSummaries = ModuleToDefinedGVSummaries[ModuleIdentifier];
9811024 }
9821025
9831026 // Parse module now
984 auto TheModule =
985 loadModuleFromBuffer(ModuleBuffer.getMemBuffer(), Context, false,
986 /*IsImporting*/ false);
1027 auto TheModule = loadModuleFromInput(Mod.get(), Context, false,
1028 /*IsImporting*/ false);
9871029
9881030 // Save temps: original file.
9891031 saveTempBitcode(*TheModule, SaveTempsDir, count, ".0.original.bc");
0 ; Needs a function for the combined index to be populated
1 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
2
13 define void @bar() {
24 ret void
35 }
2727 ; COMBINED-DAG:
2828 ; COMBINED-DAG:
2929
30 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
3031
3132 ; Need a function for the combined index to be populated.
3233 define void @foo() {
None
1
2
0 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
31
42 @globalfuncAlias = alias void (...), bitcast (void ()* @globalfunc to void (...)*)
53 @globalfuncWeakAlias = weak alias void (...), bitcast (void ()* @globalfunc to void (...)*)
None
1
2
0 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
31
42 @globalfuncAlias = alias void (...), bitcast (void ()* @globalfunc to void (...)*)
53 @globalfuncWeakAlias = weak alias void (...), bitcast (void ()* @globalfunc to void (...)*)
0 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
1
2 define void @g() {
13 entry:
24 ret void
0 target triple = "x86_64-apple-macosx10.11.0"
1 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
0 ; An internal global variable that can't be renamed because it has a section
1 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
12 @var_with_section = internal global i32 0, section "some_section"
23
34 ; @reference_gv_with_section() can't be imported
0 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
1 target triple = "x86_64-apple-macosx10.15.0"
2
3 define i32 @main() {
4 entry:
5 %call = call i32 @bar()
6 ret i32 0
7 }
8
9 declare i32 @bar()
8282 ; IMPORT-DAG: declare void @linkonceODRfuncLinkonceAlias()
8383 ; IMPORT-DAG: define available_externally void @linkonceODRfuncLinkonceODRAlias()
8484
85 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
86
8587 define i32 @main() #0 {
8688 entry:
8789 call void @globalfuncAlias()
4242 ; PROMOTE_MOD1: @weakfuncLinkonceODRAlias = weak_odr alias void (...), bitcast (void ()* @weakfunc.mod1 to void (...)*)
4343 ; PROMOTE_MOD2: @weakfuncLinkonceODRAlias = linkonce_odr alias void (...), bitcast (void ()* @weakfunc to void (...)*)
4444
45 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
4546
4647 @linkonceODRfuncAlias = alias void (...), bitcast (void ()* @linkonceODRfunc.mod1 to void (...)*)
4748 @linkonceODRfuncWeakAlias = weak alias void (...), bitcast (void ()* @linkonceODRfunc.mod1 to void (...)*)
44 ; RUN: opt -module-summary %p/Inputs/deadstrip.ll -o %t2.bc
55 ; RUN: llvm-lto -thinlto-action=thinlink -o %t.index.bc %t1.bc %t2.bc
66
7 ; RUN: llvm-lto -exported-symbol=_main -thinlto-action=promote %t1.bc -thinlto-index=%t.index.bc -o - | llvm-lto -exported-symbol=_main -thinlto-action=internalize -thinlto-index %t.index.bc -thinlto-module-id=%t1.bc - -o - | llvm-dis -o - | FileCheck %s
8 ; RUN: llvm-lto -exported-symbol=_main -thinlto-action=promote %t2.bc -thinlto-index=%t.index.bc -o - | llvm-lto -exported-symbol=_main -thinlto-action=internalize -thinlto-index %t.index.bc -thinlto-module-id=%t2.bc - -o - | llvm-dis -o - | FileCheck %s --check-prefix=CHECK2
7 ; RUN: llvm-lto -exported-symbol=_main -thinlto-action=internalize %t1.bc -thinlto-index=%t.index.bc -o - | llvm-dis -o - | FileCheck %s
8 ; RUN: llvm-lto -exported-symbol=_main -thinlto-action=internalize %t2.bc -thinlto-index=%t.index.bc -o - | llvm-dis -o - | FileCheck %s --check-prefix=CHECK2
99
1010 ; RUN: llvm-lto -exported-symbol=_main -thinlto-action=run -stats %t1.bc %t2.bc 2>&1 | FileCheck %s --check-prefix=STATS
1111 ; RUN: llvm-nm %t1.bc.thinlto.o | FileCheck %s --check-prefix=CHECK-NM
4545 ; RUN: llvm-dis %t1.bc.thinlto.bc -o - | FileCheck %s --check-prefix=DIS
4646 ; DIS: aliasee: null
4747
48 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
49
4850 declare void @g(...)
4951 declare void @analias(...)
5052
3232 ; INTERNALIZE: define internal void @linkonce_func()
3333 ; INTERNALIZE-OPTION-DISABLE: define void @foo
3434 ; INTERNALIZE-OPTION-DISABLE: define void @bar
35 ; INTERNALIZE-OPTION-DISABLE: define linkonce void @linkonce_func()
35 ; INTERNALIZE-OPTION-DISABLE: define weak void @linkonce_func()
3636 ; INTERNALIZE2: define dso_local void @foo
3737 ; INTERNALIZE2: define internal void @bar
3838 ; INTERNALIZE2: define internal void @linkonce_func()
55 ; RUN: llvm-lto -thinlto-action=thinlink -o %t3.bc %t.bc %t2.bc
66 ; RUN: llvm-lto -thinlto-action=promote %t.bc -thinlto-index=%t3.bc -o - | llvm-dis -o - | FileCheck %s
77
8 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
9
810 ; CHECK: @linkonceodrunnamed = weak_odr hidden unnamed_addr constant i32 0
911 @linkonceodrunnamed = linkonce_odr unnamed_addr constant i32 0
33 ; RUN: llvm-dis < %t1.bc.thinlto.imported.bc | FileCheck %s --check-prefix=CHECK1
44 ; RUN: llvm-dis < %t2.bc.thinlto.imported.bc | FileCheck %s --check-prefix=CHECK2
55
6 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
67 target triple = "x86_64-apple-macosx10.12.0"
78
89 ; CHECK1: target triple = "x86_64-apple-macosx10.12.0"
99 ; RUN: llvm-lto -thinlto-action=distributedindexes -thinlto-prefix-replace="%t/oldpath/;%t/newpath/" -thinlto-index %t.index.bc %t/oldpath/prefix_replace.o
1010
1111 ; RUN: ls %t/newpath/prefix_replace.o.thinlto.bc
12 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
1213
1314 define void @f() {
1415 entry:
1111 ; IMPORT: declare void @reference_gv_with_section()
1212 ; Canary to check that importing is correctly set up.
1313 ; IMPORT: define available_externally void @foo()
14 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
1415
1516
1617 define i32 @main() {
0 ; RUN: opt -module-summary -o %t.bc %s
1 ; RUN: opt -module-summary -o %t-main.bc %S/Inputs/thinlto-internalize-used2.ll
2 ; RUN: llvm-lto -thinlto-action=thinlink %t.bc %t-main.bc -o %t-index.bc
3 ; RUN: llvm-lto -thinlto-action=internalize -thinlto-index %t-index.bc %t.bc -o %t.promote.bc
4 ; RUN: llvm-dis %t.promote.bc -o - | FileCheck %s
5
6 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
7 target triple = "x86_64-apple-macosx10.15.0"
8
9 @llvm.used = appending global [1 x i8*] [i8* bitcast (i32 ()* @foo to i8*)], section "llvm.metadata"
10
11 ; Make sure foo is not internalized.
12 ; CHECK: define i32 @foo()
13 define i32 @foo() {
14 ret i32 0
15 }
16
17 define hidden i32 @bar() {
18 ret i32 0
19 }
20
66 ; non-prevailing ODR are not kept when possible, but non-ODR non-prevailing
77 ; are not affected.
88 ; RUN: llvm-lto -thinlto-action=promote %t.bc -thinlto-index=%t3.bc -o - | llvm-dis -o - | FileCheck %s --check-prefix=MOD1
9 ; RUN: llvm-lto -thinlto-action=promote %t.bc -thinlto-index=%t3.bc -exported-symbol=linkoncefunc -o - | llvm-lto -thinlto-action=internalize -thinlto-module-id=%t.bc - -thinlto-index=%t3.bc -exported-symbol=linkoncefunc -o - | llvm-dis -o - | FileCheck %s --check-prefix=MOD1-INT
9 ; RUN: llvm-lto -thinlto-action=internalize %t.bc -thinlto-index=%t3.bc -exported-symbol=linkoncefunc -o - | llvm-dis -o - | FileCheck %s --check-prefix=MOD1-INT
1010 ; RUN: llvm-lto -thinlto-action=promote %t2.bc -thinlto-index=%t3.bc -o - | llvm-dis -o - | FileCheck %s --check-prefix=MOD2
1111 ; When exported, we always preserve a linkonce
1212 ; RUN: llvm-lto -thinlto-action=promote %t.bc -thinlto-index=%t3.bc -o - --exported-symbol=linkonceodrfuncInSingleModule | llvm-dis -o - | FileCheck %s --check-prefix=EXPORTED
0 ; RUN: opt -module-summary %s -o %t.bc
11 ; RUN: llvm-lto -thinlto-action=thinlink -o %t2.bc %t.bc
22
3 ; RUN: llvm-lto -thinlto-action=promote %t.bc -thinlto-index=%t2.bc -exported-symbol=foo -o - | llvm-lto -thinlto-action=internalize -thinlto-module-id=%t.bc - -thinlto-index=%t2.bc -exported-symbol=foo -o - | llvm-dis -o - | FileCheck %s
3 ; RUN: llvm-lto -thinlto-action=internalize %t.bc -thinlto-index=%t2.bc -exported-symbol=foo -o - | llvm-dis -o - | FileCheck %s
44
55 ; CHECK: define weak_odr void @foo()
6 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
67 define linkonce_odr void @foo() {
78 ret void
89 }
2626
2727 ; BCA:
2828
29 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
30
2931 ; CHECK: @g = global i8 42
3032 @g = global i8 42
3133
448448 return ExitOnErr(getModuleSummaryIndexForFile(ThinLTOIndex));
449449 }
450450
451 static std::unique_ptr loadModule(StringRef Filename,
452 LLVMContext &Ctx) {
453 SMDiagnostic Err;
454 std::unique_ptr M(parseIRFile(Filename, Err, Ctx));
455 if (!M) {
456 Err.print("llvm-lto", errs());
457 report_fatal_error("Can't load module for file " + Filename);
458 }
459 maybeVerifyModule(*M);
460
451 static std::unique_ptr loadFile(StringRef Filename) {
452 ExitOnError ExitOnErr("llvm-lto: error loading file '" + Filename.str() +
453 "': ");
454 return ExitOnErr(errorOrToExpected(MemoryBuffer::getFileOrSTDIN(Filename)));
455 }
456
457 static std::unique_ptr loadInputFile(MemoryBufferRef Buffer) {
458 ExitOnError ExitOnErr("llvm-lto: error loading input '" +
459 Buffer.getBufferIdentifier().str() + "': ");
460 return ExitOnErr(lto::InputFile::create(Buffer));
461 }
462
463 static std::unique_ptr loadModuleFromInput(lto::InputFile &File,
464 LLVMContext &CTX) {
465 auto &Mod = File.getSingleBitcodeModule();
466 auto ModuleOrErr = Mod.parseModule(CTX);
467 if (!ModuleOrErr) {
468 handleAllErrors(ModuleOrErr.takeError(), [&](ErrorInfoBase &EIB) {
469 SMDiagnostic Err = SMDiagnostic(Mod.getModuleIdentifier(),
470 SourceMgr::DK_Error, EIB.message());
471 Err.print("llvm-lto", errs());
472 });
473 report_fatal_error("Can't load module, abort.");
474 }
475 maybeVerifyModule(**ModuleOrErr);
461476 if (ThinLTOModuleId.getNumOccurrences()) {
462477 if (InputFilenames.size() != 1)
463478 report_fatal_error("Can't override the module id for multiple files");
464 M->setModuleIdentifier(ThinLTOModuleId);
465 }
466 return M;
479 (*ModuleOrErr)->setModuleIdentifier(ThinLTOModuleId);
480 }
481 return std::move(*ModuleOrErr);
467482 }
468483
469484 static void writeModuleToFile(Module &TheModule, StringRef Filename) {
561576 auto Index = loadCombinedIndex();
562577 for (auto &Filename : InputFilenames) {
563578 LLVMContext Ctx;
564 auto TheModule = loadModule(Filename, Ctx);
579 auto Buffer = loadFile(Filename);
580 auto Input = loadInputFile(Buffer->getMemBufferRef());
581 auto TheModule = loadModuleFromInput(*Input, Ctx);
565582
566583 // Build a map of module to the GUIDs and summary objects that should
567584 // be written to its index.
568585 std::map ModuleToSummariesForIndex;
569 ThinGenerator.gatherImportedSummariesForModule(*TheModule, *Index,
570 ModuleToSummariesForIndex);
586 ThinGenerator.gatherImportedSummariesForModule(
587 *TheModule, *Index, ModuleToSummariesForIndex, *Input);
571588
572589 std::string OutputName = OutputFilename;
573590 if (OutputName.empty()) {
596613 auto Index = loadCombinedIndex();
597614 for (auto &Filename : InputFilenames) {
598615 LLVMContext Ctx;
599 auto TheModule = loadModule(Filename, Ctx);
616 auto Buffer = loadFile(Filename);
617 auto Input = loadInputFile(Buffer->getMemBufferRef());
618 auto TheModule = loadModuleFromInput(*Input, Ctx);
600619 std::string OutputName = OutputFilename;
601620 if (OutputName.empty()) {
602621 OutputName = Filename + ".imports";
603622 }
604 OutputName = getThinLTOOutputFile(OutputName, OldPrefix, NewPrefix);
605 ThinGenerator.emitImports(*TheModule, OutputName, *Index);
623 OutputName =
624 getThinLTOOutputFile(OutputName, OldPrefix, NewPrefix);
625 ThinGenerator.emitImports(*TheModule, OutputName, *Index, *Input);
606626 }
607627 }
608628
620640 auto Index = loadCombinedIndex();
621641 for (auto &Filename : InputFilenames) {
622642 LLVMContext Ctx;
623 auto TheModule = loadModule(Filename, Ctx);
624
625 ThinGenerator.promote(*TheModule, *Index);
643 auto Buffer = loadFile(Filename);
644 auto Input = loadInputFile(Buffer->getMemBufferRef());
645 auto TheModule = loadModuleFromInput(*Input, Ctx);
646
647 ThinGenerator.promote(*TheModule, *Index, *Input);
626648
627649 std::string OutputName = OutputFilename;
628650 if (OutputName.empty()) {
651673
652674 for (auto &Filename : InputFilenames) {
653675 LLVMContext Ctx;
654 auto TheModule = loadModule(Filename, Ctx);
655
656 ThinGenerator.crossModuleImport(*TheModule, *Index);
676 auto Buffer = loadFile(Filename);
677 auto Input = loadInputFile(Buffer->getMemBufferRef());
678 auto TheModule = loadModuleFromInput(*Input, Ctx);
679
680 ThinGenerator.crossModuleImport(*TheModule, *Index, *Input);
657681
658682 std::string OutputName = OutputFilename;
659683 if (OutputName.empty()) {
682706
683707 for (auto &Filename : InputFilenames) {
684708 LLVMContext Ctx;
685 auto TheModule = loadModule(Filename, Ctx);
686
687 ThinGenerator.internalize(*TheModule, *Index);
709 auto Buffer = loadFile(Filename);
710 auto Input = loadInputFile(Buffer->getMemBufferRef());
711 auto TheModule = loadModuleFromInput(*Input, Ctx);
712
713 ThinGenerator.internalize(*TheModule, *Index, *Input);
688714
689715 std::string OutputName = OutputFilename;
690716 if (OutputName.empty()) {
705731
706732 for (auto &Filename : InputFilenames) {
707733 LLVMContext Ctx;
708 auto TheModule = loadModule(Filename, Ctx);
734 auto Buffer = loadFile(Filename);
735 auto Input = loadInputFile(Buffer->getMemBufferRef());
736 auto TheModule = loadModuleFromInput(*Input, Ctx);
709737
710738 ThinGenerator.optimize(*TheModule);
711739