Index: test/ThinLTO/X86/alias_import.ll =================================================================== --- test/ThinLTO/X86/alias_import.ll +++ test/ThinLTO/X86/alias_import.ll @@ -2,6 +2,7 @@ ; RUN: opt -module-summary %p/Inputs/alias_import.ll -o %t2.bc ; RUN: llvm-lto -thinlto-action=thinlink -o %t.index.bc %t1.bc %t2.bc ; RUN: llvm-lto -thinlto-action=promote -thinlto-index %t.index.bc %t2.bc -o - | llvm-dis -o - | FileCheck %s --check-prefix=PROMOTE +; RUN: llvm-lto -thinlto-action=promote-internalize -thinlto-index %t.index.bc %t2.bc -o - | llvm-dis -o - | FileCheck %s --check-prefix=PROMOTE-INTERNALIZE ; RUN: llvm-lto -thinlto-action=import -thinlto-index %t.index.bc %t1.bc -o - | llvm-dis -o - | FileCheck %s --check-prefix=IMPORT ; @@ -86,7 +87,44 @@ ; IMPORT-DAG: declare void @weakfuncWeakODRAlias() ; IMPORT-DAG: declare void @weakfuncLinkonceODRAlias() - +; Promotion + internalization should internalize all of these (except for aliases of +; linkonce_odr functions for some reason). +; PROMOTE-INTERNALIZE-DAG: @globalfuncAlias = internal alias void (...), bitcast (void ()* @globalfunc to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @globalfuncWeakAlias = internal alias void (...), bitcast (void ()* @globalfunc to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @globalfuncLinkonceAlias = internal alias void (...), bitcast (void ()* @globalfunc to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @globalfuncWeakODRAlias = internal alias void (...), bitcast (void ()* @globalfunc to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @globalfuncLinkonceODRAlias = internal alias void (...), bitcast (void ()* @globalfunc to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @internalfuncAlias = internal alias void (...), bitcast (void ()* @internalfunc.llvm.0 to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @internalfuncWeakAlias = internal alias void (...), bitcast (void ()* @internalfunc.llvm.0 to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @internalfuncLinkonceAlias = internal alias void (...), bitcast (void ()* @internalfunc.llvm.0 to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @internalfuncWeakODRAlias = internal alias void (...), bitcast (void ()* @internalfunc.llvm.0 to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @internalfuncLinkonceODRAlias = internal alias void (...), bitcast (void ()* @internalfunc.llvm.0 to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @linkonceODRfuncAlias = alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @linkonceODRfuncWeakAlias = internal alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @linkonceODRfuncLinkonceAlias = internal alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @linkonceODRfuncWeakODRAlias = weak_odr alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @linkonceODRfuncLinkonceODRAlias = weak_odr alias void (...), bitcast (void ()* @linkonceODRfunc to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @weakODRfuncAlias = internal alias void (...), bitcast (void ()* @weakODRfunc to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @weakODRfuncWeakAlias = internal alias void (...), bitcast (void ()* @weakODRfunc to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @weakODRfuncLinkonceAlias = internal alias void (...), bitcast (void ()* @weakODRfunc to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @weakODRfuncWeakODRAlias = internal alias void (...), bitcast (void ()* @weakODRfunc to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @weakODRfuncLinkonceODRAlias = internal alias void (...), bitcast (void ()* @weakODRfunc to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @linkoncefuncAlias = internal alias void (...), bitcast (void ()* @linkoncefunc to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @linkoncefuncWeakAlias = internal alias void (...), bitcast (void ()* @linkoncefunc to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @linkoncefuncLinkonceAlias = internal alias void (...), bitcast (void ()* @linkoncefunc to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @linkoncefuncWeakODRAlias = internal alias void (...), bitcast (void ()* @linkoncefunc to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @linkoncefuncLinkonceODRAlias = internal alias void (...), bitcast (void ()* @linkoncefunc to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @weakfuncAlias = internal alias void (...), bitcast (void ()* @weakfunc to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @weakfuncWeakAlias = internal alias void (...), bitcast (void ()* @weakfunc to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @weakfuncLinkonceAlias = internal alias void (...), bitcast (void ()* @weakfunc to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @weakfuncWeakODRAlias = internal alias void (...), bitcast (void ()* @weakfunc to void (...)*) +; PROMOTE-INTERNALIZE-DAG: @weakfuncLinkonceODRAlias = internal alias void (...), bitcast (void ()* @weakfunc to void (...)*) +; PROMOTE-INTERNALIZE-DAG: define internal void @globalfunc() +; PROMOTE-INTERNALIZE-DAG: define internal void @internalfunc.llvm.0() +; PROMOTE-INTERNALIZE-DAG: define internal void @linkonceODRfunc() +; PROMOTE-INTERNALIZE-DAG: define internal void @weakODRfunc() +; PROMOTE-INTERNALIZE-DAG: define internal void @linkoncefunc() +; PROMOTE-INTERNALIZE-DAG: define internal void @weakfunc() define i32 @main() #0 { entry: Index: test/ThinLTO/X86/weak_resolution.ll =================================================================== --- test/ThinLTO/X86/weak_resolution.ll +++ test/ThinLTO/X86/weak_resolution.ll @@ -7,6 +7,7 @@ ; non-prevailing ODR are not kept when possible, but non-ODR non-prevailing ; are not affected. ; RUN: llvm-lto -thinlto-action=promote %t.bc -thinlto-index=%t3.bc -o - | llvm-dis -o - | FileCheck %s --check-prefix=MOD1 +; RUN: llvm-lto -thinlto-action=promote-internalize %t.bc -thinlto-index=%t3.bc -exported-symbol=linkoncefunc -o - | llvm-dis -o - | FileCheck %s --check-prefix=MOD1-INT ; RUN: llvm-lto -thinlto-action=promote %t2.bc -thinlto-index=%t3.bc -o - | llvm-dis -o - | FileCheck %s --check-prefix=MOD2 ; When exported, we always preserve a linkonce ; RUN: llvm-lto -thinlto-action=promote %t.bc -thinlto-index=%t3.bc -o - --exported-symbol=linkonceodrfuncInSingleModule | llvm-dis -o - | FileCheck %s --check-prefix=EXPORTED @@ -66,6 +67,7 @@ } ; MOD1: define linkonce_odr void @linkonceodrfuncInSingleModule() +; MOD1-INT: define internal void @linkonceodrfuncInSingleModule() ; EXPORTED: define weak_odr void @linkonceodrfuncInSingleModule() define linkonce_odr void @linkonceodrfuncInSingleModule() #0 { entry: Index: tools/llvm-lto/llvm-lto.cpp =================================================================== --- tools/llvm-lto/llvm-lto.cpp +++ tools/llvm-lto/llvm-lto.cpp @@ -72,6 +72,7 @@ THINPROMOTE, THINIMPORT, THININTERNALIZE, + THINPROMOTEINTERNALIZE, THINOPT, THINCODEGEN, THINALL @@ -95,6 +96,9 @@ clEnumValN(THININTERNALIZE, "internalize", "Perform internalization driven by -exported-symbol " "(requires -thinlto-index)."), + clEnumValN( + THINPROMOTEINTERNALIZE, "promote-internalize", + "Perform promotion and internalization (requires -thinlto-index)."), clEnumValN(THINOPT, "optimize", "Perform ThinLTO optimizations."), clEnumValN(THINCODEGEN, "codegen", "CodeGen (expected to match llc)"), clEnumValN(THINALL, "run", "Perform ThinLTO end-to-end"), @@ -413,6 +417,8 @@ return import(); case THININTERNALIZE: return internalize(); + case THINPROMOTEINTERNALIZE: + return promoteInternalize(); case THINOPT: return optimize(); case THINCODEGEN: @@ -533,6 +539,33 @@ } /// Load the combined index from disk, then load every file referenced by + /// the index and add them to the generator, finally perform promotion + /// and internalization on the files mentioned on the command line (these must + /// match the index content). + void promoteInternalize() { + if (InputFilenames.size() != 1 && !OutputFilename.empty()) + report_fatal_error("Can't handle a single output filename and multiple " + "input files, do not provide an output filename and " + "the output files will be suffixed from the input " + "ones."); + + auto Index = loadCombinedIndex(); + for (auto &Filename : InputFilenames) { + LLVMContext Ctx; + auto TheModule = loadModule(Filename, Ctx); + + ThinGenerator.promote(*TheModule, *Index); + ThinGenerator.internalize(*TheModule, *Index); + + std::string OutputName = OutputFilename; + if (OutputName.empty()) { + OutputName = Filename + ".thinlto.promoted.bc"; + } + writeModuleToFile(*TheModule, OutputName); + } + } + + /// Load the combined index from disk, then load every file referenced by /// the index and add them to the generator, then performs the promotion and /// cross module importing on the files mentioned on the command line /// (these must match the index content).