Skip to content

Commit 26b4a0a

Browse files
authored
Add 'unifiedlto' option to gold plugin (#121336)
Option allows using full LTO when linking bitcode files compiled with unified LTO pipeline.
1 parent d080f78 commit 26b4a0a

File tree

3 files changed

+94
-1
lines changed

3 files changed

+94
-1
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
2+
target triple = "x86_64-pc-linux-gnu"
3+
4+
@_g = dso_local local_unnamed_addr global i32 0, align 4
5+
@llvm.compiler.used = appending global [1 x ptr] [ptr @_g], section "llvm.metadata"
6+
7+
define dso_local i32 @foo(i32 noundef %0) #0 {
8+
%2 = add nsw i32 %0, 42
9+
store i32 %2, ptr @_g, align 4
10+
ret i32 %2
11+
}
12+
13+
attributes #0 = { noinline }
14+
15+
16+
!llvm.module.flags = !{!0, !1}
17+
18+
!0 = !{i32 1, !"EnableSplitLTOUnit", i32 1}
19+
!1 = !{i32 1, !"UnifiedLTO", i32 1}
20+
21+
^0 = module: (path: "unified-lto-foo.o", hash: (1995435377, 1643957463, 3737953841, 2630641917, 1043992145))
22+
^1 = gv: (name: "foo", summaries: (function: (module: ^0, flags: (linkage: external, visibility: default, notEligibleToImport: 0, live: 0, dsoLocal: 1, canAutoHide: 0), insts: 3, funcFlags: (readNone: 0, readOnly: 0, noRecurse: 1, returnDoesNotAlias: 0, noInline: 1, alwaysInline: 0, noUnwind: 1, mayThrow: 0, hasUnknownCall: 0, mustBeUnreachable: 0), refs: (writeonly ^2)))) ; guid = 6699318081062747564
23+
^2 = gv: (name: "_g", summaries: (variable: (module: ^0, flags: (linkage: external, visibility: default, notEligibleToImport: 0, live: 0, dsoLocal: 1, canAutoHide: 0), varFlags: (readonly: 1, writeonly: 1, constant: 0)))) ; guid = 9713702464056781075
24+
^3 = gv: (name: "llvm.compiler.used", summaries: (variable: (module: ^0, flags: (linkage: appending, visibility: default, notEligibleToImport: 0, live: 1, dsoLocal: 0, canAutoHide: 0), varFlags: (readonly: 0, writeonly: 0, constant: 0), refs: (^3)))) ; guid = 9610627770985738006
25+
^4 = flags: 520
26+
^5 = blockcount: 0
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
; Check that we can use full LTO with gold plugin when inputs
2+
; are compiled using unified LTO pipeline
3+
; RUN: llvm-as %s -o %t.bc
4+
; RUN: llvm-as %p/Inputs/unified-lto-foo.ll -o %t-foo.bc
5+
; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext \
6+
; RUN: -m elf_x86_64 \
7+
; RUN: -plugin-opt=unifiedlto \
8+
; RUN: -plugin-opt=save-temps \
9+
; RUN: -u main \
10+
; RUN: %t.bc %t-foo.bc \
11+
; RUN: -o %t-out
12+
; RUN: llvm-dis %t-out.0.5.precodegen.bc -o - | FileCheck %s
13+
14+
; Check thin LTO as well
15+
; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext \
16+
; RUN: -m elf_x86_64 \
17+
; RUN: -plugin-opt=unifiedlto \
18+
; RUN: -plugin-opt=thinlto \
19+
; RUN: -plugin-opt=save-temps \
20+
; RUN: -u main \
21+
; RUN: %t.bc %t-foo.bc \
22+
; RUN: -o %t-out
23+
; RUN: llvm-dis %t.bc.5.precodegen.bc -o - | FileCheck %s --check-prefix=THIN
24+
25+
; Constant propagation is not supported by thin LTO.
26+
; With full LTO we fold argument into constant 43
27+
; CHECK: define dso_local noundef i32 @main()
28+
; CHECK-NEXT: tail call fastcc void @foo()
29+
; CHECK-NEXT: ret i32 43
30+
31+
; CHECK: define internal fastcc void @foo()
32+
; CHECK-NEXT: store i32 43, ptr @_g, align 4
33+
34+
; ThinLTO doesn't import foo, because the latter has noinline attribute
35+
; THIN: define dso_local i32 @main()
36+
; THIN-NEXT: %1 = tail call i32 @foo(i32 noundef 1)
37+
38+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
39+
target triple = "x86_64-pc-linux-gnu"
40+
41+
define dso_local i32 @main() {
42+
%1 = tail call i32 @foo(i32 noundef 1)
43+
ret i32 %1
44+
}
45+
46+
declare i32 @foo(i32 noundef)
47+
48+
!llvm.module.flags = !{!0, !1}
49+
50+
!0 = !{i32 1, !"EnableSplitLTOUnit", i32 1}
51+
!1 = !{i32 1, !"UnifiedLTO", i32 1}
52+
53+
^0 = module: (path: "unified-lto.o", hash: (2850108895, 1189778381, 479678006, 1191715608, 4095117687))
54+
^1 = gv: (name: "foo") ; guid = 6699318081062747564
55+
^2 = gv: (name: "main", summaries: (function: (module: ^0, flags: (linkage: external, visibility: default, notEligibleToImport: 0, live: 0, dsoLocal: 1, canAutoHide: 0), insts: 2, funcFlags: (readNone: 0, readOnly: 0, noRecurse: 0, returnDoesNotAlias: 0, noInline: 0, alwaysInline: 0, noUnwind: 1, mayThrow: 0, hasUnknownCall: 0, mustBeUnreachable: 0), calls: ((callee: ^1, tail: 1))))) ; guid = 15822663052811949562
56+
^3 = flags: 520
57+
^4 = blockcount: 0

llvm/tools/gold/gold-plugin.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ namespace options {
154154
static std::string extra_library_path;
155155
static std::string triple;
156156
static std::string mcpu;
157+
// Tells plugin to use unified lto
158+
static bool unifiedlto = false;
157159
// When the thinlto plugin option is specified, only read the function
158160
// the information from intermediate files and write a combined
159161
// global index for the ThinLTO backends.
@@ -248,6 +250,8 @@ namespace options {
248250
TheOutputType = OT_DISABLE;
249251
} else if (opt == "emit-asm") {
250252
TheOutputType = OT_ASM_ONLY;
253+
} else if (opt == "unifiedlto") {
254+
unifiedlto = true;
251255
} else if (opt == "thinlto") {
252256
thinlto = true;
253257
} else if (opt == "thinlto-index-only") {
@@ -893,6 +897,7 @@ static std::unique_ptr<LTO> createLTO(IndexWriteCallback OnIndexWrite,
893897
Conf.OptLevel = options::OptLevel;
894898
Conf.PTO.LoopVectorization = options::OptLevel > 1;
895899
Conf.PTO.SLPVectorization = options::OptLevel > 1;
900+
Conf.PTO.UnifiedLTO = options::unifiedlto;
896901
Conf.AlwaysEmitRegularLTOObj = !options::obj_path.empty();
897902

898903
if (options::thinlto_index_only) {
@@ -972,8 +977,13 @@ static std::unique_ptr<LTO> createLTO(IndexWriteCallback OnIndexWrite,
972977
Conf.TimeTraceEnabled = !options::time_trace_file.empty();
973978
Conf.TimeTraceGranularity = options::time_trace_granularity;
974979

980+
LTO::LTOKind ltoKind = LTO::LTOK_Default;
981+
if (options::unifiedlto)
982+
ltoKind =
983+
options::thinlto ? LTO::LTOK_UnifiedThin : LTO::LTOK_UnifiedRegular;
975984
return std::make_unique<LTO>(std::move(Conf), Backend,
976-
options::ParallelCodeGenParallelismLevel);
985+
options::ParallelCodeGenParallelismLevel,
986+
ltoKind);
977987
}
978988

979989
// Write empty files that may be expected by a distributed build

0 commit comments

Comments
 (0)