Skip to content

Commit f371019

Browse files
committed
[OpenMP] Add -Xoffload-linker to forward input to the device linker
We use the clang-linker-wrapper to perform device linking of embedded offloading object files. This is done by generating those jobs inside of the linker-wrapper itself. This patch adds an argument in Clang and the linker-wrapper that allows users to forward input to the device linking phase. This can either be done for every device linker, or for a specific target triple. We use the `-Xoffload-linker <arg>` and the `-Xoffload-linker-<triple> <arg>` syntax to accomplish this. Reviewed By: markdewing, tra Differential Revision: https://reviews.llvm.org/D126226
1 parent f9c806a commit f371019

File tree

5 files changed

+55
-0
lines changed

5 files changed

+55
-0
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,9 @@ def z : Separate<["-"], "z">, Flags<[LinkerInput, RenderAsInput]>,
823823
def Xlinker : Separate<["-"], "Xlinker">, Flags<[LinkerInput, RenderAsInput]>,
824824
HelpText<"Pass <arg> to the linker">, MetaVarName<"<arg>">,
825825
Group<Link_Group>;
826+
def Xoffload_linker : JoinedAndSeparate<["-"], "Xoffload-linker">,
827+
HelpText<"Pass <arg> to the offload linkers or the ones idenfied by -<triple>">,
828+
MetaVarName<"<triple> <arg>">, Group<Link_Group>;
826829
def Xpreprocessor : Separate<["-"], "Xpreprocessor">, Group<Preprocessor_Group>,
827830
HelpText<"Pass <arg> to the preprocessor">, MetaVarName<"<arg>">;
828831
def X_Flag : Flag<["-"], "X">, Group<Link_Group>;

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8393,6 +8393,20 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
83938393
Linker->ConstructJob(C, JA, Output, Inputs, Args, LinkingOutput);
83948394
const auto &LinkCommand = C.getJobs().getJobs().back();
83958395

8396+
// Forward -Xoffload-linker<-triple> arguments to the device link job.
8397+
for (auto *Arg : Args.filtered(options::OPT_Xoffload_linker)) {
8398+
StringRef Val = Arg->getValue(0);
8399+
if (Val.empty())
8400+
CmdArgs.push_back(
8401+
Args.MakeArgString(Twine("-device-linker=") + Arg->getValue(1)));
8402+
else
8403+
CmdArgs.push_back(Args.MakeArgString(
8404+
"-device-linker=" +
8405+
ToolChain::getOpenMPTriple(Val.drop_front()).getTriple() + "=" +
8406+
Arg->getValue(1)));
8407+
}
8408+
Args.ClaimAllArgs(options::OPT_Xoffload_linker);
8409+
83968410
// Add the linker arguments to be forwarded by the wrapper.
83978411
CmdArgs.push_back("-linker-path");
83988412
CmdArgs.push_back(LinkCommand->getExecutable());

clang/test/Driver/linker-wrapper.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,15 @@
8080
// CUDA: nvlink{{.*}}-m64 -o {{.*}}.out -arch sm_52 {{.*}}.o
8181
// CUDA: nvlink{{.*}}-m64 -o {{.*}}.out -arch sm_70 {{.*}}.o {{.*}}.o
8282
// CUDA: fatbinary{{.*}}-64 --create {{.*}}.fatbin --image=profile=sm_52,file={{.*}}.out --image=profile=sm_70,file={{.*}}.out
83+
84+
// RUN: clang-offload-packager -o %t.out \
85+
// RUN: --image=file=%S/Inputs/dummy-elf.o,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 \
86+
// RUN: --image=file=%S/Inputs/dummy-elf.o,kind=openmp,triple=nvptx64-nvidia-cuda,arch=sm_70
87+
// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o \
88+
// RUN: -fembed-offload-object=%t.out
89+
// RUN: clang-linker-wrapper --dry-run --host-triple x86_64-unknown-linux-gnu -linker-path \
90+
// RUN: /usr/bin/ld --device-linker=a --device-linker=nvptx64-nvidia-cuda=b -- \
91+
// RUN: %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=LINKER_ARGS
92+
93+
// LINKER_ARGS: lld{{.*}}-flavor gnu --no-undefined -shared -o {{.*}}.out {{.*}}.o a
94+
// LINKER_ARGS: nvlink{{.*}}-m64 -o {{.*}}.out -arch sm_70 {{.*}}.o a b

clang/test/Driver/openmp-offload-gpu-new.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,9 @@
104104
// RUN: -foffload-lto %s 2>&1 | FileCheck --check-prefix=CHECK-LTO-LIBRARY %s
105105

106106
// CHECK-LTO-LIBRARY: {{.*}}-lomptarget{{.*}}-lomptarget.devicertl
107+
108+
// RUN: %clang -### --target=x86_64-unknown-linux-gnu -fopenmp --offload-arch=sm_52 -nogpulib \
109+
// RUN: -Xoffload-linker a -Xoffload-linker-nvptx64-nvidia-cuda b -Xoffload-linker-nvptx64 c \
110+
// RUN: %s 2>&1 | FileCheck --check-prefix=CHECK-XLINKER %s
111+
112+
// CHECK-XLINKER: -device-linker=a{{.*}}-device-linker=nvptx64-nvidia-cuda=b{{.*}}-device-linker=nvptx64-nvidia-cuda=c{{.*}}--

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,12 @@ static cl::list<std::string>
108108
cl::desc("Argument to pass to the ptxas invocation"),
109109
cl::cat(ClangLinkerWrapperCategory));
110110

111+
static cl::list<std::string>
112+
LinkerArgs("device-linker", cl::ZeroOrMore,
113+
cl::desc("Arguments to pass to the device linker invocation"),
114+
cl::value_desc("<value> or <triple>=<value>"),
115+
cl::cat(ClangLinkerWrapperCategory));
116+
111117
static cl::opt<bool> Verbose("v", cl::ZeroOrMore,
112118
cl::desc("Verbose output from tools"),
113119
cl::init(false),
@@ -226,6 +232,17 @@ void printCommands(ArrayRef<StringRef> CmdArgs) {
226232
llvm::errs() << *IC << (std::next(IC) != IE ? " " : "\n");
227233
}
228234

235+
// Forward user requested arguments to the device linking job.
236+
void renderXLinkerArgs(SmallVectorImpl<StringRef> &Args, StringRef Triple) {
237+
for (StringRef Arg : LinkerArgs) {
238+
auto TripleAndValue = Arg.split('=');
239+
if (TripleAndValue.second.empty())
240+
Args.push_back(TripleAndValue.first);
241+
else if (TripleAndValue.first == Triple)
242+
Args.push_back(TripleAndValue.second);
243+
}
244+
}
245+
229246
std::string getMainExecutable(const char *Name) {
230247
void *Ptr = (void *)(intptr_t)&getMainExecutable;
231248
auto COWPath = sys::fs::getMainExecutable(Name, Ptr);
@@ -531,6 +548,7 @@ Expected<std::string> link(ArrayRef<std::string> InputFiles, Triple TheTriple,
531548
for (StringRef Input : InputFiles)
532549
CmdArgs.push_back(Input);
533550

551+
renderXLinkerArgs(CmdArgs, TheTriple.getTriple());
534552
if (Error Err = executeCommands(*NvlinkPath, CmdArgs))
535553
return std::move(Err);
536554

@@ -599,6 +617,7 @@ Expected<std::string> link(ArrayRef<std::string> InputFiles, Triple TheTriple,
599617
for (StringRef Input : InputFiles)
600618
CmdArgs.push_back(Input);
601619

620+
renderXLinkerArgs(CmdArgs, TheTriple.getTriple());
602621
if (Error Err = executeCommands(*LLDPath, CmdArgs))
603622
return std::move(Err);
604623

@@ -676,6 +695,7 @@ Expected<std::string> link(ArrayRef<std::string> InputFiles, Triple TheTriple,
676695
for (StringRef Input : InputFiles)
677696
CmdArgs.push_back(Input);
678697

698+
renderXLinkerArgs(CmdArgs, TheTriple.getTriple());
679699
if (Error Err = executeCommands(LinkerUserPath, CmdArgs))
680700
return std::move(Err);
681701

0 commit comments

Comments
 (0)