Skip to content

Commit 3c639b8

Browse files
jdenny-ornljhuber6
andauthored
[Clang] Simplify specifying passes via -Xoffload-linker (#102483)
Make it possible to do things like the following, regardless of whether the offload target is nvptx or amdgpu: ``` $ clang -O1 -g -fopenmp --offload-arch=native test.c \ -Xoffload-linker -mllvm=-pass-remarks=inline \ -Xoffload-linker -mllvm=-force-remove-attribute=g.internalized:noinline\ -Xoffload-linker --lto-newpm-passes='forceattrs,default<O1>' \ -Xoffload-linker --lto-debug-pass-manager \ -foffload-lto ``` To accomplish that: - In clang-linker-wrapper, do not forward options via `-Wl` if they might have literal commas. Use `-Xlinker` instead. - In clang-nvlink-wrapper, accept `--lto-debug-pass-manager` and `--lto-newpm-passes`. - In clang-nvlink-wrapper, drop `-passes` because it's inconsistent with the interface of `lld`, which is used instead of clang-nvlink-wrapper when the target is amdgpu. Without this patch, `-passes` is passed to `nvlink`, producing an error anyway. --------- Co-authored-by: Joseph Huber <[email protected]>
1 parent 3bd63d4 commit 3c639b8

File tree

5 files changed

+35
-23
lines changed

5 files changed

+35
-23
lines changed

clang/test/Driver/linker-wrapper.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -238,9 +238,15 @@ __attribute__((visibility("protected"), used)) int x;
238238
// RUN: clang-offload-packager -o %t.out \
239239
// RUN: --image=file=%t.elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908
240240
// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t.out
241-
// RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run --offload-opt=-pass-remarks=foo \
242-
// RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=OFFLOAD-OPT
243-
// RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run -mllvm -pass-remarks=foo \
244-
// RUN: --linker-path=/usr/bin/ld %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=OFFLOAD-OPT
245-
246-
// OFFLOAD-OPT: clang{{.*}}-Wl,--plugin-opt=-pass-remarks=foo
241+
// RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run \
242+
// RUN: --offload-opt=-pass-remarks=foo,bar --linker-path=/usr/bin/ld \
243+
// RUN: %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=OFFLOAD-OPT
244+
// RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run \
245+
// RUN: -mllvm -pass-remarks=foo,bar --linker-path=/usr/bin/ld \
246+
// RUN: %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=MLLVM
247+
248+
// MLLVM: clang{{.*}}-Xlinker --plugin-opt=-pass-remarks=foo,bar
249+
// OFFLOAD-OPT: clang{{.*}}-Xlinker --plugin-opt=-pass-remarks=foo,bar
250+
// MLLVM-SAME: -Xlinker -mllvm=-pass-remarks=foo,bar
251+
// OFFLOAD-OPT-NOT: -Xlinker -mllvm=-pass-remarks=foo,bar
252+
// OFFLOAD-OPT-SAME: {{$}}

clang/test/Driver/nvlink-wrapper.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,11 @@ int baz() { return y + x; }
7070
// RUN: clang-nvlink-wrapper --dry-run %t.o %t-u.o %t-y.a \
7171
// RUN: -arch sm_52 --cuda-path/opt/cuda -o a.out 2>&1 | FileCheck %s --check-prefix=PATH
7272
// PATH-NOT: --cuda-path=/opt/cuda
73+
74+
//
75+
// Check that passes can be specified and debugged.
76+
//
77+
// RUN: clang-nvlink-wrapper --dry-run %t.o %t-u.o %t-y.a \
78+
// RUN: --lto-debug-pass-manager --lto-newpm-passes=forceattrs \
79+
// RUN: -arch sm_52 -o a.out 2>&1 | FileCheck %s --check-prefix=PASSES
80+
// PASSES: Running pass: ForceFunctionAttrsPass

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -528,8 +528,9 @@ Expected<StringRef> clang(ArrayRef<StringRef> InputFiles, const ArgList &Args) {
528528
// Forward all of the `--offload-opt` and similar options to the device.
529529
if (linkerSupportsLTO(Args)) {
530530
for (auto &Arg : Args.filtered(OPT_offload_opt_eq_minus, OPT_mllvm))
531-
CmdArgs.push_back(
532-
Args.MakeArgString("-Wl,--plugin-opt=" + StringRef(Arg->getValue())));
531+
CmdArgs.append(
532+
{"-Xlinker",
533+
Args.MakeArgString("--plugin-opt=" + StringRef(Arg->getValue()))});
533534
}
534535

535536
if (!Triple.isNVPTX())
@@ -572,8 +573,8 @@ Expected<StringRef> clang(ArrayRef<StringRef> InputFiles, const ArgList &Args) {
572573

573574
// Pass on -mllvm options to the linker invocation.
574575
for (const opt::Arg *Arg : Args.filtered(OPT_mllvm))
575-
CmdArgs.push_back(
576-
Args.MakeArgString("-Wl,-mllvm=" + StringRef(Arg->getValue())));
576+
CmdArgs.append({"-Xlinker", Args.MakeArgString(
577+
"-mllvm=" + StringRef(Arg->getValue()))});
577578

578579
if (Args.hasArg(OPT_debug))
579580
CmdArgs.push_back("-g");

clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -84,18 +84,6 @@ static cl::list<std::string>
8484
PassPlugins("load-pass-plugin",
8585
cl::desc("Load passes from plugin library"));
8686

87-
static cl::opt<std::string> PassPipeline(
88-
"passes",
89-
cl::desc(
90-
"A textual description of the pass pipeline. To have analysis passes "
91-
"available before a certain pass, add 'require<foo-analysis>'. "
92-
"'-passes' overrides the pass pipeline (but not all effects) from "
93-
"specifying '--opt-level=O?' (O2 is the default) to "
94-
"clang-linker-wrapper. Be sure to include the corresponding "
95-
"'default<O?>' in '-passes'."));
96-
static cl::alias PassPipeline2("p", cl::aliasopt(PassPipeline),
97-
cl::desc("Alias for -passes"));
98-
9987
static void printVersion(raw_ostream &OS) {
10088
OS << clang::getClangToolFullVersion("clang-nvlink-wrapper") << '\n';
10189
}
@@ -365,8 +353,9 @@ Expected<std::unique_ptr<lto::LTO>> createLTO(const ArgList &Args) {
365353
Conf.OptLevel = Args.getLastArgValue(OPT_O, "2")[0] - '0';
366354
Conf.DefaultTriple = Triple.getTriple();
367355

368-
Conf.OptPipeline = PassPipeline;
356+
Conf.OptPipeline = Args.getLastArgValue(OPT_lto_newpm_passes, "");
369357
Conf.PassPlugins = PassPlugins;
358+
Conf.DebugPassManager = Args.hasArg(OPT_lto_debug_pass_manager);
370359

371360
Conf.DiagHandler = diagnosticHandler;
372361
Conf.CGFileType = CodeGenFileType::AssemblyFile;

clang/tools/clang-nvlink-wrapper/NVLinkOpts.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// We try to create options similar to lld's. That way, options passed to clang
2+
// -Xoffload-linker can be the same whether offloading to nvptx or amdgpu.
3+
14
include "llvm/Option/OptParser.td"
25

36
def WrapperOnlyOption : OptionFlag;
@@ -70,6 +73,11 @@ def plugin_opt : Joined<["--", "-"], "plugin-opt=">, Flags<[WrapperOnlyOption]>,
7073
HelpText<"Options passed to LLVM, not including the Clang invocation. Use "
7174
"'--plugin-opt=--help' for a list of options.">;
7275

76+
def lto_newpm_passes : Joined<["--"], "lto-newpm-passes=">,
77+
Flags<[WrapperOnlyOption]>, HelpText<"Passes to run during LTO">;
78+
def lto_debug_pass_manager : Flag<["--"], "lto-debug-pass-manager">,
79+
Flags<[WrapperOnlyOption]>, HelpText<"Debug new pass manager">;
80+
7381
def save_temps : Flag<["--", "-"], "save-temps">,
7482
Flags<[WrapperOnlyOption]>, HelpText<"Save intermediate results">;
7583

0 commit comments

Comments
 (0)