const SymbolResolution *&ResI, const SymbolResolution *ResE);
Error runRegularLTO(AddStreamFn AddStream);
- Error runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache,
- bool HasRegularLTO);
+ Error runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache);
mutable bool CalledGetMaxTasks = false;
};
LTO::RegularLTOState::RegularLTOState(unsigned ParallelCodeGenParallelismLevel,
Config &Conf)
: ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel),
- Ctx(Conf) {}
+ Ctx(Conf), CombinedModule(llvm::make_unique<Module>("ld-temp.o", Ctx)),
+ Mover(llvm::make_unique<IRMover>(*CombinedModule)) {}
LTO::ThinLTOState::ThinLTOState(ThinBackend Backend) : Backend(Backend) {
if (!Backend)
if (Conf.ResolutionFile)
writeToResolutionFile(*Conf.ResolutionFile, Input.get(), Res);
+ if (RegularLTO.CombinedModule->getTargetTriple().empty())
+ RegularLTO.CombinedModule->setTargetTriple(Input->getTargetTriple());
+
const SymbolResolution *ResI = Res.begin();
for (unsigned I = 0; I != Input->Mods.size(); ++I)
if (Error Err = addModule(*Input, I, ResI, Res.end()))
Error LTO::linkRegularLTO(RegularLTOState::AddedModule Mod,
bool LivenessFromIndex) {
- if (!RegularLTO.CombinedModule) {
- RegularLTO.CombinedModule =
- llvm::make_unique<Module>("ld-temp.o", RegularLTO.Ctx);
- RegularLTO.Mover = llvm::make_unique<IRMover>(*RegularLTO.CombinedModule);
- }
-
std::vector<GlobalValue *> Keep;
for (GlobalValue *GV : Mod.Keep) {
if (LivenessFromIndex && !ThinLTO.CombinedIndex.isGUIDLive(GV->getGUID()))
computeDeadSymbols(ThinLTO.CombinedIndex, GUIDPreservedSymbols);
- // Save the status of having a regularLTO combined module, as
- // this is needed for generating the ThinLTO Task ID, and
- // the CombinedModule will be moved at the end of runRegularLTO.
- bool HasRegularLTO = RegularLTO.CombinedModule != nullptr ||
- !RegularLTO.ModsWithSummaries.empty();
- // Invoke regular LTO if there was a regular LTO module to start with.
- if (HasRegularLTO)
- if (auto E = runRegularLTO(AddStream))
- return E;
- return runThinLTO(AddStream, Cache, HasRegularLTO);
+ if (auto E = runRegularLTO(AddStream))
+ return E;
+ return runThinLTO(AddStream, Cache);
}
Error LTO::runRegularLTO(AddStreamFn AddStream) {
};
}
-Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache,
- bool HasRegularLTO) {
+Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache) {
if (ThinLTO.ModuleMap.empty())
return Error::success();
ThinLTO.Backend(Conf, ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries,
AddStream, Cache);
- // Task numbers start at ParallelCodeGenParallelismLevel if an LTO
- // module is present, as tasks 0 through ParallelCodeGenParallelismLevel-1
- // are reserved for parallel code generation partitions.
- unsigned Task =
- HasRegularLTO ? RegularLTO.ParallelCodeGenParallelismLevel : 0;
+ // Tasks 0 through ParallelCodeGenParallelismLevel-1 are reserved for combined
+ // module and parallel code generation partitions.
+ unsigned Task = RegularLTO.ParallelCodeGenParallelismLevel;
for (auto &Mod : ThinLTO.ModuleMap) {
if (Error E = BackendProc->start(Task, Mod.second, ImportLists[Mod.first],
ExportLists[Mod.first],
; RUN: llvm-lto2 run %t -r %t,main,px -r %t,alias,p -r %t,external, \
; RUN: %t2 -r %t2,external,p \
; RUN: -save-temps -o %t3
-; RUN: llvm-nm %t3.1 | FileCheck %s
+; RUN: llvm-nm %t3.2 | FileCheck %s
; CHECK: D external
; RUN: opt -module-summary -o %t.bc %s
; RUN: llvm-lto2 run %t.bc -r %t.bc,foo,pl -o %t2
-; RUN: llvm-nm %t2.0 | FileCheck %s
+; RUN: llvm-nm %t2.1 | FileCheck %s
; CHECK: T foo
; CHECK: t foo_ifunc
; RUN: opt -module-summary %s -o %t.o
; RUN: llvm-lto2 run -o %t1.o %t.o -r %t.o,patatino,pr
-; RUN: llvm-readobj -t %t1.o.0 | FileCheck %s
+; RUN: llvm-readobj -t %t1.o.1 | FileCheck %s
; CHECK: Name: patatino
; CHECK-NEXT: Value:
; RUN: opt -module-summary -o %t %s
; RUN: llvm-lto2 run %t -O0 -r %t,foo,px -o %t2
-; RUN: llvm-nm %t2.0 | FileCheck %s
+; RUN: llvm-nm %t2.1 | FileCheck %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; RUN: llvm-lto2 run -o %t.out %t.bc -save-temps \
; RUN: -r %t.bc,test,px -r %t.bc,bar,x \
; RUN: -lto-sample-profile-file=%S/Inputs/load-sample-prof-icp.prof
-; RUN: llvm-dis %t.out.0.4.opt.bc -o - | FileCheck %s
+; RUN: llvm-dis %t.out.1.4.opt.bc -o - | FileCheck %s
; RUN: llvm-lto2 run -o %t.out %t.bc -save-temps \
; RUN: -r %t.bc,test,px -r %t.bc,bar,x -use-new-pm \
; RUN: -lto-sample-profile-file=%S/Inputs/load-sample-prof-icp.prof
-; RUN: llvm-dis %t.out.0.4.opt.bc -o - | FileCheck %s
+; RUN: llvm-dis %t.out.1.4.opt.bc -o - | FileCheck %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; RUN: llvm-lto2 run -o %t.out %t.bc -save-temps \
; RUN: -r %t.bc,foo,px -r %t.bc,bar,x \
; RUN: -lto-sample-profile-file=%S/Inputs/load-sample-prof.prof
-; RUN: llvm-dis %t.out.0.4.opt.bc -o - | FileCheck %s
+; RUN: llvm-dis %t.out.1.4.opt.bc -o - | FileCheck %s
;
; CHECK: !prof
; RUN: opt -module-summary -o %t.bc %s
; RUN: opt -module-summary -o %t2.bc %S/Inputs/mod-asm-used.ll
; RUN: llvm-lto2 run %t.bc -r %t.bc,foo,l %t2.bc -r %t2.bc,foo,pl -o %t3
-; RUN: llvm-nm %t3.1 | FileCheck %s
+; RUN: llvm-nm %t3.* | FileCheck %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; RUN: -r %t2.bc,_dead_func,l \
; RUN: -r %t2.bc,_another_dead_func,pl
; RUN: llvm-dis < %t.out.0.3.import.bc | FileCheck %s --check-prefix=LTO2
-; RUN: llvm-dis < %t.out.1.3.import.bc | FileCheck %s --check-prefix=LTO2-CHECK2
+; RUN: llvm-dis < %t.out.2.3.import.bc | FileCheck %s --check-prefix=LTO2-CHECK2
; RUN: llvm-nm %t.out.1 | FileCheck %s --check-prefix=CHECK2-NM
; RUN: llvm-bcanalyzer -dump %t.out.index.bc | FileCheck %s --check-prefix=COMBINED
; RUN: -r %t2.bc,main,plx \
; RUN: -r %t2.bc,foo,l \
; RUN: -r %t1.bc,foo,pl
-; RUN: llvm-dis < %t.out.1.3.import.bc | FileCheck %s
+; RUN: llvm-dis < %t.out.2.3.import.bc | FileCheck %s
; CHECK: distinct !DICompositeType(tag: DW_TAG_enumeration_type, name: "enum", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 50, size: 32, flags: DIFlagFwdDecl, identifier: "enum")
; CHECK: distinct !DICompositeType(tag: DW_TAG_class_type, name: "class", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 728, size: 448, flags: DIFlagFwdDecl, identifier: "class")
; RUN: -r %t2.bc,main,plx \
; RUN: -r %t2.bc,foo,l \
; RUN: -r %t1.bc,foo,pl
-; RUN: llvm-dis < %t.out.1.3.import.bc | FileCheck %s --check-prefix=FULL
+; RUN: llvm-dis < %t.out.2.3.import.bc | FileCheck %s --check-prefix=FULL
; FULL: distinct !DICompositeType(tag: DW_TAG_enumeration_type, name: "enum", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 50, size: 32, elements: !{{[0-9]+}}, identifier: "enum")
; FULL: distinct !DICompositeType(tag: DW_TAG_class_type, name: "class", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: 728, size: 448, elements: !{{[0-9]+}}, identifier: "class")
; IMPORT: define available_externally void @analias() !thinlto_src_module
; EXPORT: @G.llvm.
+target triple = "x86_64-unknown-linux-gnu"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
declare i32 @g(...)
--- /dev/null
+; RUN: opt -module-summary -o %t.bc %s
+
+; RUN: rm -f %t2.0
+; RUN: llvm-lto2 run %t.bc -r %t.bc,foo,pl -o %t2 -thinlto-distributed-indexes
+; RUN: llvm-readobj -h %t2.0 | FileCheck %s
+; RUN: llvm-nm %t2.0 | count 0
+
+; CHECK: Format: ELF64-x86-64
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+@foo = ifunc i32 (i32), i64 ()* @foo_ifunc
+
+define internal i64 @foo_ifunc() {
+entry:
+ ret i64 0
+}
; RUN: -r=%t1.bc,_foo,plx \
; RUN: -r=%t2.bc,_main,plx \
; RUN: -r=%t2.bc,_foo,l
-; RUN: llvm-dis %t.o.1.3.import.bc -o - | FileCheck %s
+; RUN: llvm-dis %t.o.2.3.import.bc -o - | FileCheck %s
; CHECK: define available_externally dso_local void @foo()
; We shouldn't do any importing at -O0
; RUN: -r=%t1.bc,_foo,plx \
; RUN: -r=%t2.bc,_main,plx \
; RUN: -r=%t2.bc,_foo,l
-; RUN: llvm-dis %t.o.1.3.import.bc -o - | FileCheck %s --check-prefix=CHECKO0
+; RUN: llvm-dis %t.o.2.3.import.bc -o - | FileCheck %s --check-prefix=CHECKO0
; CHECKO0: declare dso_local void @foo(...)
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
; RUN: -r=%t1.bc,_foo,pxl \
; RUN: -r=%t1.bc,_bar,pl \
; RUN: -r=%t1.bc,_linkonce_func,pl
-; RUN: llvm-dis < %t.o.0.2.internalize.bc | FileCheck %s --check-prefix=INTERNALIZE2
+; RUN: llvm-dis < %t.o.1.2.internalize.bc | FileCheck %s --check-prefix=INTERNALIZE2
; REGULAR: define void @foo
; RUN: -r=%t2.bc,func3,l \
; RUN: -r=%t2.bc,callglobalfunc,l \
; RUN: -r=%t2.bc,callweakfunc,l
-; RUN: llvm-nm %t.o.0 | FileCheck %s --check-prefix=NM0
-; RUN: llvm-nm %t.o.1 | FileCheck %s --check-prefix=NM1
+; RUN: llvm-nm %t.o.1 | FileCheck %s --check-prefix=NM0
+; RUN: llvm-nm %t.o.2 | FileCheck %s --check-prefix=NM1
; Check that local values b and x, which are referenced on
; llvm.used and llvm.compiler.used, respectively, are not promoted.
; RUN: -r=%t1.bc,_simplefunction,pl \
; RUN: -r=%t2.bc,main,plx \
; RUN: -r=%t2.bc,_simplefunction,l
-; RUN: llvm-nm %t.o.0 | FileCheck %s --check-prefix=NM0
-; RUN: llvm-nm %t.o.1 | FileCheck %s --check-prefix=NM1
+; RUN: llvm-nm %t.o.1 | FileCheck %s --check-prefix=NM0
+; RUN: llvm-nm %t.o.2 | FileCheck %s --check-prefix=NM1
; NM0: T foo
; NM1-NOT: foo
; RUN: -r %t1.bc,foo,l \
; RUN: -r %t1.bc,bar,p \
; RUN: -r %t1.bc,main,xp
-; RUN: llvm-readobj -t %t.o.1 | FileCheck %s
+; RUN: llvm-readobj -t %t.o.2 | FileCheck %s
; CHECK: Symbol {
; CHECK: Name: foo
; RUN: -r %t1.bc,personality_routine3,l \
; RUN: -r %t1.bc,main,xp \
; RUN: -r %t1.bc,bar,l
-; RUN: llvm-readobj -t %t.o.1 | FileCheck %s --check-prefix=BINDING
+; RUN: llvm-readobj -t %t.o.2 | FileCheck %s --check-prefix=BINDING
; BINDING: Symbol {
; BINDING: Name: personality_routine
target triple = "x86_64-apple-macosx10.11.0"
; We shouldn't promote the private because it has a section
-; RUN: llvm-dis < %t.o.0.2.internalize.bc | FileCheck %s --check-prefix=PROMOTE
+; RUN: llvm-dis < %t.o.1.2.internalize.bc | FileCheck %s --check-prefix=PROMOTE
; PROMOTE: @a = private global i8 0, section "__TEXT,__cstring,cstring_literals"
@a = private global i8 0, section "__TEXT,__cstring,cstring_literals"
@b = global i8 *@a
; We want foo to be imported in the main module!
-; RUN: llvm-dis < %t.o.1.3.import.bc | FileCheck %s --check-prefix=IMPORT
+; RUN: llvm-dis < %t.o.2.3.import.bc | FileCheck %s --check-prefix=IMPORT
; IMPORT: define available_externally dso_local i8** @foo()
define i8 **@foo() {
ret i8 **@b
; RUN: -r %t.bc,_Z4LinkPKcS0_,plx \
; RUN: -r %t.bc,link,l \
; RUN: -r %t2.bc,get_link,plx
-; RUN: llvm-nm %t.out.0 | FileCheck %s
+; RUN: llvm-nm %t.out.1 | FileCheck %s
; CHECK: U link
; REQUIRES: x86-registered-target
; IMPORTS2-NOT: Import _ZL3barv
; RUN: llvm-nm %t3.2 | FileCheck %s --check-prefix=NM
; NM: _ZL3barv
-; RUN: llvm-dis < %t3.2.2.internalize.bc | FileCheck %s --check-prefix=INTERNALIZE
+; RUN: llvm-dis < %t3.3.2.internalize.bc | FileCheck %s --check-prefix=INTERNALIZE
; INTERNALIZE: define dso_local void @_ZL3barv
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
; RUN: --plugin-opt=jobs=2 \
; RUN: --plugin-opt=obj-path=%t5.o \
; RUN: -shared %t.o %t2.o -o %t4
-; RUN: llvm-nm %t5.o | FileCheck %s --check-prefix=NM2
; RUN: llvm-nm %t5.o1 | FileCheck %s --check-prefix=NM2
+; RUN: llvm-nm %t5.o2 | FileCheck %s --check-prefix=NM2
+
+; Test to ensure that thinlto-index-only with obj-path creates the file.
+; RUN: rm -f %t5.o %t5.o1
+; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext \
+; RUN: -m elf_x86_64 \
+; RUN: --plugin-opt=thinlto \
+; RUN: --plugin-opt=jobs=2 \
+; RUN: --plugin-opt=thinlto-index-only \
+; RUN: --plugin-opt=obj-path=%t5.o \
+; RUN: -shared %t.o %t2.o -o %t4
+; RUN: llvm-readobj -h %t5.o | FileCheck %s --check-prefix=FORMAT
+; RUN: llvm-nm %t5.o | count 0
; NM: T f
; NM2: T {{f|g}}
+; FORMAT: Format: ELF64-x86-64
; The backend index for this module contains summaries from itself and
; Inputs/thinlto.ll, as it imports from the latter.