[clang] [flang] [clang] Add option to specify opt pipeline during offload lto (PR #114401)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 31 06:21:43 PDT 2024
https://github.com/macurtis-amd created https://github.com/llvm/llvm-project/pull/114401
Especially useful for experimenting with 'default' vs 'lto' pipelines.
New driver option '-offload-lto-opt-pipeline=<value>' is forwarded to clang-linker-wrapper as '-lto-opt-pipeline=<value>' which is then forwarded to clang as '-Xlinker --lto-newpm-passes=<value>' and then finally as '--lto-newpm-passes=<value>' to lld.
>From 2c4ddda58ee35141a1b59e92f1894d76b7bac43e Mon Sep 17 00:00:00 2001
From: Matthew Curtis <macurtis at amd.com>
Date: Thu, 31 Oct 2024 08:06:29 -0500
Subject: [PATCH] [clang] Add option to specify opt pipeline during offload lto
Especially useful for experimenting with 'default' vs 'lto' pipelines.
New driver option '-offload-lto-opt-pipeline=<value>' is forwarded to
clang-linker-wrapper as '-lto-opt-pipeline=<value>' which is then forwarded to
clang as '-Xlinker --lto-newpm-passes=<value>' and then finally as
'--lto-newpm-passes=<value>' to lld.
---
clang/include/clang/Driver/Options.td | 4 +++
clang/lib/Driver/ToolChains/Clang.cpp | 6 ++++
clang/test/Driver/amdgpu-openmp-toolchain.c | 18 ++++++++++
clang/test/Driver/linker-wrapper.c | 34 +++++++++++++++++--
.../ClangLinkerWrapper.cpp | 12 +++++++
.../clang-linker-wrapper/LinkerWrapperOpts.td | 4 +++
flang/test/Driver/offload-lto-pipeline.f90 | 20 +++++++++++
7 files changed, 96 insertions(+), 2 deletions(-)
create mode 100644 flang/test/Driver/offload-lto-pipeline.f90
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 2b9ee1a0e669ed..c78eb23e134e04 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1231,6 +1231,10 @@ def offload_host_device : Flag<["--"], "offload-host-device">,
Visibility<[ClangOption, FlangOption]>,
HelpText<"Compile for both the offloading host and device (default).">;
+def offload_lto_opt_pipeline_EQ : Joined<["-"], "offload-lto-opt-pipeline=">,
+ Visibility<[ClangOption, FlangOption]>, Flags<[HelpHidden]>,
+ HelpText<"Optimization pipeline to use during offload linking.">;
+
def gpu_use_aux_triple_only : Flag<["--"], "gpu-use-aux-triple-only">,
InternalDriverOpt, HelpText<"Prepare '-aux-triple' only without populating "
"'-aux-target-cpu' and '-aux-target-feature'.">;
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 4c6f508f1f24a6..128b9f29358bf4 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -9228,6 +9228,12 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
if (Args.getLastArg(options::OPT_save_temps_EQ))
CmdArgs.push_back("--save-temps");
+ if (const Arg *A =
+ Args.getLastArg(options::OPT_offload_lto_opt_pipeline_EQ)) {
+ CmdArgs.push_back(
+ Args.MakeArgString(Twine("--lto-opt-pipeline=") + A->getValue()));
+ }
+
// Construct the link job so we can wrap around it.
Linker->ConstructJob(C, JA, Output, Inputs, Args, LinkingOutput);
const auto &LinkCommand = C.getJobs().getJobs().back();
diff --git a/clang/test/Driver/amdgpu-openmp-toolchain.c b/clang/test/Driver/amdgpu-openmp-toolchain.c
index f596708047c154..57aedb35024ac1 100644
--- a/clang/test/Driver/amdgpu-openmp-toolchain.c
+++ b/clang/test/Driver/amdgpu-openmp-toolchain.c
@@ -81,3 +81,21 @@
// RUN: %clang -### --target=x86_64-unknown-linux-gnu -emit-llvm -S -fopenmp --offload-arch=gfx803 \
// RUN: -stdlib=libc++ -nogpulib %s 2>&1 | FileCheck %s --check-prefix=LIBCXX
// LIBCXX-NOT: include/amdgcn-amd-amdhsa/c++/v1
+
+// RUN: %clang -### --target=x86_64-unknown-linux-gnu -fopenmp \
+// RUN: -fopenmp-targets=amdgcn-amd-amdhsa -Xopenmp-target=amdgcn-amd-amdhsa \
+// RUN: -march=gfx803 -nogpulib %s \
+// RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-LTO-OPT-PL-00
+// CHECK-LTO-OPT-PL-00-NOT: clang-linker-wrapper{{.*}} "--lto-opt-pipeline"
+
+// RUN: %clang -### --target=x86_64-unknown-linux-gnu -fopenmp \
+// RUN: -fopenmp-targets=amdgcn-amd-amdhsa -Xopenmp-target=amdgcn-amd-amdhsa \
+// RUN: -march=gfx803 -nogpulib -offload-lto-opt-pipeline=lto %s \
+// RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-LTO-OPT-PL-01
+// CHECK-LTO-OPT-PL-01: clang-linker-wrapper{{.*}} "--lto-opt-pipeline=lto"
+
+// RUN: %clang -### --target=x86_64-unknown-linux-gnu -fopenmp \
+// RUN: -fopenmp-targets=amdgcn-amd-amdhsa -Xopenmp-target=amdgcn-amd-amdhsa \
+// RUN: -march=gfx803 -nogpulib "-offload-lto-opt-pipeline=default<O3>" %s \
+// RUN: 2>&1 | FileCheck %s --check-prefix=CHECK-LTO-OPT-PL-02
+// CHECK-LTO-OPT-PL-02: clang-linker-wrapper{{.*}} "--lto-opt-pipeline=default<O3>"
diff --git a/clang/test/Driver/linker-wrapper.c b/clang/test/Driver/linker-wrapper.c
index 470af4d5d70cac..da4a3fe31afd07 100644
--- a/clang/test/Driver/linker-wrapper.c
+++ b/clang/test/Driver/linker-wrapper.c
@@ -30,7 +30,7 @@ __attribute__((visibility("protected"), used)) int x;
// RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run --device-debug -O0 \
// RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=NVPTX-LINK-DEBUG
-// NVPTX-LINK-DEBUG: clang{{.*}} -o {{.*}}.img --target=nvptx64-nvidia-cuda -march=sm_70 -O2 -flto {{.*}}.o {{.*}}.o -g
+// NVPTX-LINK-DEBUG: clang{{.*}} -o {{.*}}.img --target=nvptx64-nvidia-cuda -march=sm_70 -O2 -flto {{.*}}.o {{.*}}.o -g
// RUN: clang-offload-packager -o %t.out \
// RUN: --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 \
@@ -93,7 +93,7 @@ __attribute__((visibility("protected"), used)) int x;
// CUDA: clang{{.*}} -o [[IMG_SM70:.+]] --target=nvptx64-nvidia-cuda -march=sm_70
// CUDA: clang{{.*}} -o [[IMG_SM52:.+]] --target=nvptx64-nvidia-cuda -march=sm_52
-// CUDA: fatbinary{{.*}}-64 --create {{.*}}.fatbin --image=profile=sm_70,file=[[IMG_SM70]] --image=profile=sm_52,file=[[IMG_SM52]]
+// CUDA: fatbinary{{.*}}-64 --create {{.*}}.fatbin --image=profile=sm_70,file=[[IMG_SM70]] --image=profile=sm_52,file=[[IMG_SM52]]
// CUDA: usr/bin/ld{{.*}} {{.*}}.openmp.image.{{.*}}.o {{.*}}.cuda.image.{{.*}}.o
// RUN: clang-offload-packager -o %t.out \
@@ -254,3 +254,33 @@ __attribute__((visibility("protected"), used)) int x;
// Error handling when --linker-path is not provided for clang-linker-wrapper
// RUN: not clang-linker-wrapper 2>&1 | FileCheck --check-prefix=LINKER-PATH-NOT-PROVIDED %s
// LINKER-PATH-NOT-PROVIDED: linker path missing, must pass 'linker-path'
+
+// RUN: clang-linker-wrapper --lto-opt-pipeline=default \
+// RUN: --dry-run --wrapper-verbose --host-triple=x86_64-unknown-linux-gnu \
+// RUN: --linker-path=/usr/bin/ld %t.o -o a.out \
+// RUN: 2>&1 | FileCheck %s --check-prefix=LTO-OPT-PL-00
+// LTO-OPT-PL-00: "{{.*}}clang" {{.*}} -Xlinker --lto-newpm-passes=default<O2>
+
+// RUN: clang-linker-wrapper --lto-opt-pipeline=default --opt-level=O3 \
+// RUN: --dry-run --wrapper-verbose --host-triple=x86_64-unknown-linux-gnu \
+// RUN: --linker-path=/usr/bin/ld %t.o -o a.out \
+// RUN: 2>&1 | FileCheck %s --check-prefix=LTO-OPT-PL-01
+// LTO-OPT-PL-01: "{{.*}}clang" {{.*}} -Xlinker --lto-newpm-passes=default<O3>
+
+// RUN: clang-linker-wrapper --lto-opt-pipeline=lto \
+// RUN: --dry-run --wrapper-verbose --host-triple=x86_64-unknown-linux-gnu \
+// RUN: --linker-path=/usr/bin/ld %t.o -o a.out \
+// RUN: 2>&1 | FileCheck %s --check-prefix=LTO-OPT-PL-02
+// LTO-OPT-PL-02: "{{.*}}clang" {{.*}} -Xlinker --lto-newpm-passes=lto<O2>
+
+// RUN: clang-linker-wrapper --lto-opt-pipeline=lto --opt-level=O0 \
+// RUN: --dry-run --wrapper-verbose --host-triple=x86_64-unknown-linux-gnu \
+// RUN: --linker-path=/usr/bin/ld %t.o -o a.out \
+// RUN: 2>&1 | FileCheck %s --check-prefix=LTO-OPT-PL-03
+// LTO-OPT-PL-03: "{{.*}}clang" {{.*}} -Xlinker --lto-newpm-passes=lto<O0>
+
+// RUN: clang-linker-wrapper \
+// RUN: --dry-run --wrapper-verbose --host-triple=x86_64-unknown-linux-gnu \
+// RUN: --linker-path=/usr/bin/ld %t.o -o a.out \
+// RUN: 2>&1 | FileCheck %s --check-prefix=LTO-OPT-PL-04
+// LTO-OPT-PL-04-NOT: --lto-newpm-passes
diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
index ebafd7eb7774ec..10b82a533aaddd 100644
--- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
@@ -570,6 +570,18 @@ Expected<StringRef> clang(ArrayRef<StringRef> InputFiles, const ArgList &Args) {
for (StringRef Arg : Args.getAllArgValues(OPT_linker_arg_EQ))
CmdArgs.append({"-Xlinker", Args.MakeArgString(Arg)});
+
+ StringRef LTOOptPipeline = Args.getLastArgValue(OPT_lto_opt_pipeline_EQ, "");
+ if (LTOOptPipeline == "default" || LTOOptPipeline == "lto" ||
+ LTOOptPipeline == "thinlto") {
+ // for convenience, add "<On>"
+ LTOOptPipeline = Args.MakeArgString(LTOOptPipeline + "<" + OptLevel + ">");
+ }
+ if (LTOOptPipeline.size()) {
+ CmdArgs.append({"-Xlinker", Args.MakeArgString("--lto-newpm-passes=" +
+ LTOOptPipeline)});
+ }
+
for (StringRef Arg : Args.getAllArgValues(OPT_compiler_arg_EQ))
CmdArgs.push_back(Args.MakeArgString(Arg));
diff --git a/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td b/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td
index 57d918db0a73ce..acd50067d98dc6 100644
--- a/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td
+++ b/clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td
@@ -71,6 +71,10 @@ def override_image : Joined<["--"], "override-image=">,
Flags<[WrapperOnlyOption]>, MetaVarName<"<kind=file>">,
HelpText<"Uses the provided file as if it were the output of the device link step">;
+def lto_opt_pipeline_EQ : Joined<["--"], "lto-opt-pipeline=">,
+ Flags<[WrapperOnlyOption]>,
+ HelpText<"Optimization pipeline to use during LTO.">;
+
// Flags passed to the device linker.
def arch_EQ : Joined<["--"], "arch=">,
Flags<[DeviceOnlyOption, HelpHidden]>, MetaVarName<"<arch>">,
diff --git a/flang/test/Driver/offload-lto-pipeline.f90 b/flang/test/Driver/offload-lto-pipeline.f90
new file mode 100644
index 00000000000000..c81762307820ab
--- /dev/null
+++ b/flang/test/Driver/offload-lto-pipeline.f90
@@ -0,0 +1,20 @@
+! Test forwarding/generation of -lto-opt-pipeline to the clang-linker-wrapper
+
+! RUN: %flang -### %s -o %t 2>&1 -fopenmp --offload-arch=gfx90a \
+! RUN: --target=aarch64-unknown-linux-gnu -nogpulib \
+! RUN: | FileCheck %s --check-prefix=CHECK-LTO-OPT-PL-00
+! CHECK-LTO-OPT-PL-00-NOT: clang-linker-wrapper{{.*}} "--lto-opt-pipeline"
+
+! RUN: %flang -### %s -o %t 2>&1 -fopenmp --offload-arch=gfx90a \
+! RUN: --target=aarch64-unknown-linux-gnu -nogpulib \
+! RUN: -offload-lto-opt-pipeline=lto \
+! RUN: | FileCheck %s --check-prefix=CHECK-LTO-OPT-PL-01
+! CHECK-LTO-OPT-PL-01: clang-linker-wrapper{{.*}} "--lto-opt-pipeline=lto"
+
+! RUN: %flang -### %s -o %t 2>&1 -fopenmp --offload-arch=gfx90a \
+! RUN: --target=aarch64-unknown-linux-gnu -nogpulib \
+! RUN: "-offload-lto-opt-pipeline=default<O3>" \
+! RUN: | FileCheck %s --check-prefix=CHECK-LTO-OPT-PL-02
+! CHECK-LTO-OPT-PL-02: clang-linker-wrapper{{.*}} "--lto-opt-pipeline=default<O3>"
+
+
More information about the cfe-commits
mailing list