Skip to content

Commit dff11dd

Browse files
committed
Add clang-linker-wrapper option to specify the lto optimization pipeline
This does not change the default pipeline 'lto<On>' where 'n' is based on --opt-level. To override the default value, pass '-offload-lto-opt-pipeline=<pipeline>' to clang or flang. Or pass '--lto-opt-pipeline=<pipeline>' directly to clang-linker-wrapper. The optimization level may be omitted when using 'default' or 'lto'. Regex for most common values: '(default|lto)(<O[0123sz]>)?' Change-Id: Icc8a17b0e055b26595a3842d7069390aee6b916b
1 parent aa22487 commit dff11dd

File tree

7 files changed

+108
-0
lines changed

7 files changed

+108
-0
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,6 +1236,12 @@ def offload_host_device : Flag<["--"], "offload-host-device">,
12361236
Visibility<[ClangOption, FlangOption]>,
12371237
HelpText<"Compile for both the offloading host and device (default).">;
12381238

1239+
def offload_lto_opt_pipeline_EQ : Joined<["-"], "offload-lto-opt-pipeline=">,
1240+
Visibility<[ClangOption, FlangOption]>,
1241+
HelpText<"Optimization pipeline to use during offload linking. Defaults to"
1242+
" 'default<On>' where n is based on -O">;
1243+
1244+
12391245
def gpu_use_aux_triple_only : Flag<["--"], "gpu-use-aux-triple-only">,
12401246
InternalDriverOpt, HelpText<"Prepare '-aux-triple' only without populating "
12411247
"'-aux-target-cpu' and '-aux-target-feature'.">;

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9749,6 +9749,26 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
97499749
if (Args.getLastArg(options::OPT_save_temps_EQ))
97509750
CmdArgs.push_back("--save-temps");
97519751

9752+
if (const Arg *A =
9753+
Args.getLastArg(options::OPT_offload_lto_opt_pipeline_EQ)) {
9754+
CmdArgs.push_back(
9755+
Args.MakeArgString(Twine("--lto-opt-pipeline=") + A->getValue()));
9756+
} else if (D.getOffloadLTOMode() == LTOK_Full ||
9757+
D.getOffloadLTOMode() == LTOK_Thin ||
9758+
D.getLTOMode() == LTOK_Full || D.getLTOMode() == LTOK_Thin) {
9759+
StringRef val;
9760+
// OffloadLTOMode takes precedence over LTOMode
9761+
if (D.getOffloadLTOMode() == LTOK_Full)
9762+
val = "lto";
9763+
else if (D.getOffloadLTOMode() == LTOK_Thin)
9764+
val = "thinlto";
9765+
else if (D.getLTOMode() == LTOK_Full)
9766+
val = "lto";
9767+
else
9768+
val = "thinlto";
9769+
CmdArgs.push_back(Args.MakeArgString("--lto-opt-pipeline=" + val));
9770+
}
9771+
97529772
// Construct the link job so we can wrap around it.
97539773
Linker->ConstructJob(C, JA, Output, Inputs, Args, LinkingOutput);
97549774
const auto &LinkCommand = C.getJobs().getJobs().back();

clang/test/Driver/amdgpu-openmp-toolchain-new.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,13 @@
5252

5353
// RUN: %clang -### -target x86_64-pc-linux-gnu -fopenmp -fopenmp-targets=amdgcn-amd-amdhsa -Xopenmp-target=amdgcn-amd-amdhsa -march=gfx803 --no-opaque-offload-linker -lm --rocm-device-lib-path=%S/Inputs/rocm/amdgcn/bitcode %s 2>&1 | FileCheck %s --check-prefix=CHECK-LIB-DEVICE-NEW
5454
// CHECK-LIB-DEVICE-NEW: {{.*}}"-target-cpu" "gfx803"{{.*}}ocml.bc"{{.*}}oclc_daz_opt_on.bc"{{.*}}oclc_unsafe_math_off.bc"{{.*}}oclc_finite_only_off.bc"{{.*}}oclc_correctly_rounded_sqrt_on.bc"{{.*}}oclc_wavefrontsize64_on.bc"{{.*}}oclc_isa_version_803.bc"
55+
56+
// RUN: CLANG_USE_LINKER_WRAPPER=1 %clang -### --target=x86_64-unknown-linux-gnu -fopenmp -fopenmp-targets=amdgcn-amd-amdhsa -Xopenmp-target=amdgcn-amd-amdhsa -march=gfx803 -nogpulib %s 2>&1 | FileCheck %s --check-prefix=CHECK-LTO-OPT-PL-00
57+
// CHECK-LTO-OPT-PL-00-NOT: clang-linker-wrapper{{.*}} "--lto-opt-pipeline"
58+
59+
// RUN: CLANG_USE_LINKER_WRAPPER=1 %clang -### --target=x86_64-unknown-linux-gnu -fopenmp -fopenmp-targets=amdgcn-amd-amdhsa -Xopenmp-target=amdgcn-amd-amdhsa -march=gfx803 -nogpulib -offload-lto-opt-pipeline=lto %s 2>&1 | FileCheck %s --check-prefix=CHECK-LTO-OPT-PL-01
60+
// RUN: CLANG_USE_LINKER_WRAPPER=1 %clang -### --target=x86_64-unknown-linux-gnu -fopenmp -fopenmp-targets=amdgcn-amd-amdhsa -Xopenmp-target=amdgcn-amd-amdhsa -march=gfx803 -nogpulib -flto %s 2>&1 | FileCheck %s --check-prefix=CHECK-LTO-OPT-PL-01
61+
// CHECK-LTO-OPT-PL-01: clang-linker-wrapper{{.*}} "--lto-opt-pipeline=lto"
62+
63+
// RUN: CLANG_USE_LINKER_WRAPPER=1 %clang -### --target=x86_64-unknown-linux-gnu -fopenmp -fopenmp-targets=amdgcn-amd-amdhsa -Xopenmp-target=amdgcn-amd-amdhsa -march=gfx803 -nogpulib "-offload-lto-opt-pipeline=default<O3>" %s 2>&1 | FileCheck %s --check-prefix=CHECK-LTO-OPT-PL-02
64+
// CHECK-LTO-OPT-PL-02: clang-linker-wrapper{{.*}} "--lto-opt-pipeline=default<O3>"
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// REQUIRES: x86-registered-target
2+
// REQUIRES: amdgpu-registered-target
3+
// REQUIRES: system-linux
4+
5+
// An externally visible variable so static libraries extract.
6+
__attribute__((visibility("protected"), used)) int x;
7+
8+
// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.elf.o
9+
// RUN: %clang -cc1 %s -triple amdgcn-amd-amdhsa -emit-llvm-bc -o %t.amdgpu.bc
10+
11+
// RUN: clang-offload-packager -o %t.out \
12+
// RUN: --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908
13+
// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t.out
14+
15+
// RUN: clang-linker-wrapper --lto-opt-pipeline=default \
16+
// RUN: --dry-run --wrapper-verbose --host-triple=x86_64-unknown-linux-gnu \
17+
// RUN: --linker-path=/usr/bin/ld %t.o -o a.out \
18+
// RUN: 2>&1 | FileCheck %s --check-prefix=LTO-OPT-PL-00
19+
// LTO-OPT-PL-00: "{{.*}}clang" {{.*}} -Xlinker --lto-newpm-passes=default<O2>
20+
21+
// RUN: clang-linker-wrapper --lto-opt-pipeline=default --opt-level=O3 \
22+
// RUN: --dry-run --wrapper-verbose --host-triple=x86_64-unknown-linux-gnu \
23+
// RUN: --linker-path=/usr/bin/ld %t.o -o a.out \
24+
// RUN: 2>&1 | FileCheck %s --check-prefix=LTO-OPT-PL-01
25+
// LTO-OPT-PL-01: "{{.*}}clang" {{.*}} -Xlinker --lto-newpm-passes=default<O3>
26+
27+
// RUN: clang-linker-wrapper --lto-opt-pipeline=lto \
28+
// RUN: --dry-run --wrapper-verbose --host-triple=x86_64-unknown-linux-gnu \
29+
// RUN: --linker-path=/usr/bin/ld %t.o -o a.out \
30+
// RUN: 2>&1 | FileCheck %s --check-prefix=LTO-OPT-PL-02
31+
// LTO-OPT-PL-02: "{{.*}}clang" {{.*}} -Xlinker --lto-newpm-passes=lto<O2>
32+
33+
// RUN: clang-linker-wrapper --lto-opt-pipeline=lto --opt-level=O0 \
34+
// RUN: --dry-run --wrapper-verbose --host-triple=x86_64-unknown-linux-gnu \
35+
// RUN: --linker-path=/usr/bin/ld %t.o -o a.out \
36+
// RUN: 2>&1 | FileCheck %s --check-prefix=LTO-OPT-PL-03
37+
// LTO-OPT-PL-03: "{{.*}}clang" {{.*}} -Xlinker --lto-newpm-passes=lto<O0>
38+
39+
// RUN: clang-linker-wrapper \
40+
// RUN: --dry-run --wrapper-verbose --host-triple=x86_64-unknown-linux-gnu \
41+
// RUN: --linker-path=/usr/bin/ld %t.o -o a.out \
42+
// RUN: 2>&1 | FileCheck %s --check-prefix=LTO-OPT-PL-04
43+
// LTO-OPT-PL-04-NOT: --lto-newpm-passes

clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,17 @@ Expected<StringRef> clang(ArrayRef<StringRef> InputFiles, const ArgList &Args) {
604604

605605
for (StringRef Arg : Args.getAllArgValues(OPT_linker_arg_EQ))
606606
CmdArgs.append({"-Xlinker", Args.MakeArgString(Arg)});
607+
608+
StringRef ltoOptPipeline = Args.getLastArgValue(OPT_lto_opt_pipeline_EQ, "");
609+
if (ltoOptPipeline == "lto" || ltoOptPipeline == "default") {
610+
// for convenience, add "<On>"
611+
ltoOptPipeline = Args.MakeArgString(ltoOptPipeline + "<" + OptLevel + ">");
612+
}
613+
if (ltoOptPipeline.size()) {
614+
CmdArgs.append({"-Xlinker", Args.MakeArgString("--lto-newpm-passes=" +
615+
ltoOptPipeline)});
616+
}
617+
607618
for (StringRef Arg : Args.getAllArgValues(OPT_compiler_arg_EQ))
608619
CmdArgs.push_back(Args.MakeArgString(Arg));
609620

clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ def override_image : Joined<["--"], "override-image=">,
8181
Flags<[WrapperOnlyOption]>, MetaVarName<"<kind=file>">,
8282
HelpText<"Uses the provided file as if it were the output of the device link step">;
8383

84+
def lto_opt_pipeline_EQ : Joined<["--"], "lto-opt-pipeline=">,
85+
Flags<[WrapperOnlyOption]>,
86+
HelpText<"Optimization pipeline to use during LTO. Defaults to 'default<On>'"
87+
" where n is based on --opt-level">;
88+
8489
// Flags passed to the device linker.
8590
def arch_EQ : Joined<["--"], "arch=">,
8691
Flags<[DeviceOnlyOption, HelpHidden]>, MetaVarName<"<arch>">,
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
! Test forwarding/generation of -lto-opt-pipeline to the clang-linker-wrapper
2+
3+
! RUN: CLANG_USE_LINKER_WRAPPER=1 %flang -### %s -o %t 2>&1 -fopenmp --offload-arch=gfx90a --target=aarch64-unknown-linux-gnu -nogpulib | FileCheck %s --check-prefix=CHECK-LTO-OPT-PL-00
4+
! CHECK-LTO-OPT-PL-00-NOT: clang-linker-wrapper{{.*}} "--lto-opt-pipeline"
5+
6+
! RUN: CLANG_USE_LINKER_WRAPPER=1 %flang -### %s -o %t 2>&1 -fopenmp --offload-arch=gfx90a --target=aarch64-unknown-linux-gnu -nogpulib -offload-lto-opt-pipeline=lto | FileCheck %s --check-prefix=CHECK-LTO-OPT-PL-01
7+
! RUN: CLANG_USE_LINKER_WRAPPER=1 %flang -### %s -o %t 2>&1 -fopenmp --offload-arch=gfx90a --target=aarch64-unknown-linux-gnu -nogpulib -flto | FileCheck %s --check-prefix=CHECK-LTO-OPT-PL-01
8+
! CHECK-LTO-OPT-PL-01: clang-linker-wrapper{{.*}} "--lto-opt-pipeline=lto"
9+
10+
! RUN: CLANG_USE_LINKER_WRAPPER=1 %flang -### %s -o %t 2>&1 -fopenmp --offload-arch=gfx90a --target=aarch64-unknown-linux-gnu -nogpulib "-offload-lto-opt-pipeline=default<O3>" | FileCheck %s --check-prefix=CHECK-LTO-OPT-PL-02
11+
! CHECK-LTO-OPT-PL-02: clang-linker-wrapper{{.*}} "--lto-opt-pipeline=default<O3>"
12+
13+

0 commit comments

Comments
 (0)