Skip to content

Commit c2dab05

Browse files
authored
[SYCL] Support dynamic linking on new offloading model (#16055)
Dynamic linking was already supported in the old offloading model, so bring the support to the new offloading model.
1 parent d76b552 commit c2dab05

File tree

19 files changed

+584
-0
lines changed

19 files changed

+584
-0
lines changed

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11471,6 +11471,12 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
1147111471
if (Args.hasArg(options::OPT_fsycl_embed_ir))
1147211472
CmdArgs.push_back(Args.MakeArgString("-sycl-embed-ir"));
1147311473

11474+
if (Args.hasFlag(options::OPT_fsycl_allow_device_image_dependencies,
11475+
options::OPT_fno_sycl_allow_device_image_dependencies,
11476+
false))
11477+
CmdArgs.push_back(
11478+
Args.MakeArgString("-sycl-allow-device-image-dependencies"));
11479+
1147411480
// Formulate and add any offload-wrapper and AOT specific options. These
1147511481
// are additional options passed in via -Xsycl-target-linker and
1147611482
// -Xsycl-target-backend.

clang/test/Driver/sycl-offload-new-driver.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,3 +195,19 @@
195195
// RUN: --offload-new-driver 2>&1 \
196196
// RUN: | FileCheck -check-prefix NVPTX_CUDA_PATH %s
197197
// NVPTX_CUDA_PATH: clang-linker-wrapper{{.*}} "--cuda-path={{.*}}Inputs/CUDA_80/usr/local/cuda"
198+
199+
/// Check for -sycl-allow-device-image-dependencies transmission to clang-linker-wrapper tool
200+
// RUN: %clangxx -fsycl -### --offload-new-driver \
201+
// RUN: -fsycl-allow-device-image-dependencies %s 2>&1 \
202+
// RUN: | FileCheck -check-prefix CHECK_DYNAMIC_LINKING %s
203+
// CHECK_DYNAMIC_LINKING: clang-linker-wrapper{{.*}} "-sycl-allow-device-image-dependencies"
204+
205+
/// Check that -sycl-allow-device-image-dependencies is not passed to clang-linker-wrapper tool
206+
// RUN: %clangxx -fsycl -### --offload-new-driver \
207+
// RUN: -fno-sycl-allow-device-image-dependencies %s 2>&1 \
208+
// RUN: | FileCheck -check-prefix CHECK_NO_DYNAMIC_LINKING %s
209+
210+
/// Check that -sycl-allow-device-image-dependencies is not passed to clang-linker-wrapper tool
211+
// RUN: %clangxx -fsycl -### --offload-new-driver %s 2>&1 \
212+
// RUN: | FileCheck -check-prefix CHECK_NO_DYNAMIC_LINKING %s
213+
// CHECK_NO_DYNAMIC_LINKING-NOT: clang-linker-wrapper{{.*}} "-sycl-allow-device-image-dependencies"

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,7 @@ getTripleBasedSYCLPostLinkOpts(const ArgList &Args,
676676
if ((!Args.hasFlag(OPT_no_sycl_remove_unused_external_funcs,
677677
OPT_sycl_remove_unused_external_funcs, false) &&
678678
!SYCLNativeCPU) &&
679+
!Args.hasArg(OPT_sycl_allow_device_image_dependencies) &&
679680
!Triple.isNVPTX() && !Triple.isAMDGPU())
680681
PostLinkArgs.push_back("-emit-only-kernels-as-entry-points");
681682

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,3 +243,8 @@ Flags<[WrapperOnlyOption]>, HelpText<"Embed LLVM IR for runtime kernel fusion">
243243
def sycl_dump_device_code_EQ : Joined<["--", "-"], "sycl-dump-device-code=">,
244244
Flags<[WrapperOnlyOption]>,
245245
HelpText<"Path to the folder where the tool dumps SPIR-V device code. Other formats aren't dumped.">;
246+
247+
// Options to enable/disable device dynamic linking.
248+
def sycl_allow_device_image_dependencies : Flag<["--", "-"], "sycl-allow-device-image-dependencies">,
249+
Flags<[WrapperOnlyOption, HelpHidden]>,
250+
HelpText<"Allow dependencies between device code images">;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#define A_EXPORT
2+
#include "a.hpp"
3+
#include "b.hpp"
4+
#include <iostream>
5+
6+
A_DECLSPEC SYCL_EXTERNAL int levelA(int val) {
7+
#ifndef __SYCL_DEVICE_ONLY__
8+
std::cerr << "Host symbol used" << std::endl;
9+
val ^= 0x1234;
10+
#endif
11+
val = levelB(val);
12+
return val |= (0xA << 0);
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include <sycl/detail/core.hpp>
2+
3+
#if defined(MAKE_DLL)
4+
#ifdef A_EXPORT
5+
#define A_DECLSPEC __declspec(dllexport)
6+
#else
7+
#define A_DECLSPEC __declspec(dllimport)
8+
#endif
9+
#else
10+
#define A_DECLSPEC
11+
#endif
12+
13+
A_DECLSPEC SYCL_EXTERNAL int levelA(int val);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#define B_EXPORT
2+
#include "b.hpp"
3+
#include "c.hpp"
4+
#include <iostream>
5+
6+
B_DECLSPEC SYCL_EXTERNAL int levelB(int val) {
7+
#ifndef __SYCL_DEVICE_ONLY__
8+
std::cerr << "Host symbol used" << std::endl;
9+
val ^= 0x2345;
10+
#endif
11+
val = levelC(val);
12+
return val |= (0xB << 4);
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include <sycl/detail/core.hpp>
2+
3+
#if defined(MAKE_DLL)
4+
#ifdef B_EXPORT
5+
#define B_DECLSPEC __declspec(dllexport)
6+
#else
7+
#define B_DECLSPEC __declspec(dllimport)
8+
#endif
9+
#else
10+
#define B_DECLSPEC
11+
#endif
12+
13+
B_DECLSPEC SYCL_EXTERNAL int levelB(int val);
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#define C_EXPORT
2+
#include "c.hpp"
3+
#include "d.hpp"
4+
#include <iostream>
5+
6+
C_DECLSPEC SYCL_EXTERNAL int levelC(int val) {
7+
#ifndef __SYCL_DEVICE_ONLY__
8+
std::cerr << "Host symbol used" << std::endl;
9+
val ^= 0x3456;
10+
#endif
11+
val = levelD(val);
12+
return val |= (0xC << 8);
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include <sycl/detail/core.hpp>
2+
3+
#if defined(MAKE_DLL)
4+
#ifdef C_EXPORT
5+
#define C_DECLSPEC __declspec(dllexport)
6+
#else
7+
#define C_DECLSPEC __declspec(dllimport)
8+
#endif
9+
#else
10+
#define C_DECLSPEC
11+
#endif
12+
13+
C_DECLSPEC SYCL_EXTERNAL int levelC(int val);

0 commit comments

Comments
 (0)