Skip to content

Commit 1e94ef3

Browse files
authored
[Driver][SYCL] Enable generation of spv based fat objects (#4608)
When generating fat objects with -fsycl, our default behavior is to generate and store the LLVM-IR for the device side compilation. Update the behavior, introducing -fsycl-device-obj=arg (where arg is spirv or llvmir) to create the desired 'object' contents. This is a precursor to the enabling the ability to consume these spv based objects (or llvm-ir) seamlessly.
1 parent 38fd188 commit 1e94ef3

File tree

4 files changed

+60
-16
lines changed

4 files changed

+60
-16
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2687,10 +2687,16 @@ defm sycl_id_queries_fit_in_int: BoolFOption<"sycl-id-queries-fit-in-int",
26872687
LangOpts<"SYCLValueFitInMaxInt">, DefaultTrue,
26882688
PosFlag<SetTrue, [], "Assume">, NegFlag<SetFalse, [], "Do not assume">,
26892689
BothFlags<[CC1Option, CoreOption], " that SYCL ID queries fit within MAX_INT.">>;
2690+
def fsycl_device_obj_EQ : Joined<["-"], "fsycl-device-obj=">,
2691+
Flags<[CoreOption]>, Values<"spirv,llvmir">, HelpText<"Specify format of "
2692+
"device code stored in the resulting object. Valid values are: spirv, llvmir "
2693+
"(default)">;
26902694
def fsycl_use_bitcode : Flag<["-"], "fsycl-use-bitcode">,
2691-
Flags<[CC1Option, CoreOption]>, HelpText<"Use LLVM bitcode instead of SPIR-V in fat objects">;
2695+
Alias<fsycl_device_obj_EQ>, AliasArgs<["llvmir"]>, Flags<[CoreOption]>,
2696+
HelpText<"Use LLVM bitcode instead of SPIR-V in fat objects">;
26922697
def fno_sycl_use_bitcode : Flag<["-"], "fno-sycl-use-bitcode">,
2693-
Flags<[CC1Option, CoreOption]>, HelpText<"Use SPIR-V instead of LLVM bitcode in fat objects">;
2698+
Alias<fsycl_device_obj_EQ>, AliasArgs<["spirv"]>, Flags<[CoreOption]>,
2699+
HelpText<"Use SPIR-V instead of LLVM bitcode in fat objects">;
26942700
def fsycl_link_EQ : Joined<["-"], "fsycl-link=">,
26952701
Flags<[CC1Option, CoreOption]>, HelpText<"Generate partially linked device and host object to be used at various stages of compilation">, Values<"image,early">;
26962702
def fsycl_link : Flag<["-"], "fsycl-link">, Alias<fsycl_link_EQ>,

clang/lib/Driver/Driver.cpp

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4202,19 +4202,22 @@ class OffloadingActionBuilder final {
42024202
if ((SYCLDeviceOnly || Args.hasArg(options::OPT_emit_llvm)) &&
42034203
Args.hasArg(options::OPT_S))
42044204
OutputType = types::TY_LLVM_IR;
4205-
if (SYCLDeviceOnly) {
4206-
if (Args.hasFlag(options::OPT_fno_sycl_use_bitcode,
4207-
options::OPT_fsycl_use_bitcode, false)) {
4208-
auto *CompileAction =
4209-
C.MakeAction<CompileJobAction>(A, types::TY_LLVM_BC);
4210-
A = C.MakeAction<SPIRVTranslatorJobAction>(CompileAction,
4211-
types::TY_SPIRV);
4205+
// Use of -fsycl-device-obj=spirv converts the original LLVM-IR
4206+
// file to SPIR-V for later consumption.
4207+
if ((SYCLDeviceOnly || FinalPhase != phases::Link) &&
4208+
Args.getLastArgValue(options::OPT_fsycl_device_obj_EQ)
4209+
.equals_insensitive("spirv")) {
4210+
auto *CompileAction =
4211+
C.MakeAction<CompileJobAction>(A, types::TY_LLVM_BC);
4212+
A = C.MakeAction<SPIRVTranslatorJobAction>(CompileAction,
4213+
types::TY_SPIRV);
4214+
if (SYCLDeviceOnly)
42124215
continue;
4213-
}
4216+
} else {
4217+
if (Args.hasArg(options::OPT_fsyntax_only))
4218+
OutputType = types::TY_Nothing;
4219+
A = C.MakeAction<CompileJobAction>(A, OutputType);
42144220
}
4215-
if (Args.hasArg(options::OPT_fsyntax_only))
4216-
OutputType = types::TY_Nothing;
4217-
A = C.MakeAction<CompileJobAction>(A, OutputType);
42184221
DeviceCompilerInput = A;
42194222
}
42204223
const DeviceTargetInfo &DevTarget = SYCLTargetInfoList.back();

clang/lib/Driver/ToolChains/SYCL.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -350,9 +350,8 @@ void SYCL::Linker::ConstructJob(Compilation &C, const JobAction &JA,
350350
for (const auto &II : Inputs) {
351351
if (!II.isFilename())
352352
continue;
353-
if (Args.hasFlag(options::OPT_fsycl_use_bitcode,
354-
options::OPT_fno_sycl_use_bitcode, true) ||
355-
Args.hasArg(options::OPT_foffload_static_lib_EQ))
353+
if (!Args.getLastArgValue(options::OPT_fsycl_device_obj_EQ)
354+
.equals_insensitive("spirv"))
356355
SpirvInputs.push_back(II);
357356
else {
358357
const char *LLVMSpirvOutputFile = constructLLVMSpirvCommand(

clang/test/Driver/sycl-spirv-obj.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
///
2+
/// Tests for SPIR-V related objects
3+
///
4+
5+
// REQUIRES: clang-driver
6+
7+
/// -fsycl-device-obj=spirv
8+
// RUN: %clangxx -target x86_64-unknown-linux-gnu -c -fsycl -fsycl-device-obj=spirv -### %s 2>&1 | \
9+
// RUN: FileCheck %s -check-prefix SPIRV_DEVICE_OBJ
10+
// SPIRV_DEVICE_OBJ: clang{{.*}} "-cc1" "-triple" "spir64-unknown-unknown"
11+
// SPIRV_DEVICE_OBJ-SAME: "-aux-triple" "x86_64-unknown-linux-gnu"
12+
// SPIRV_DEVICE_OBJ-SAME: "-fsycl-is-device"
13+
// SPIRV_DEVICE_OBJ-SAME: "-o" "[[DEVICE_BC:.+\.bc]]"
14+
// SPIRV_DEVICE_OBJ: llvm-spirv{{.*}} "-o" "[[DEVICE_SPV:.+\.spv]]"
15+
// SPIRV_DEVICE_OBJ-SAME: "[[DEVICE_BC]]"
16+
// SPIRV_DEVICE_OBJ: clang{{.*}} "-cc1" "-triple" "x86_64-unknown-linux-gnu"
17+
// SPIRV_DEVICE_OBJ-SAME: "-fsycl-is-host"
18+
// SPIRV_DEVICE_OBJ-SAME: "-o" "[[HOST_OBJ:.+\.o]]"
19+
// SPIRV_DEVICE_OBJ: clang-offload-bundler{{.*}} "-type=o"
20+
// SPIRV_DEVICE_OBJ-SAME: "-inputs=[[DEVICE_SPV]],[[HOST_OBJ]]"
21+
22+
// RUN: %clangxx -target x86_64-unknown-linux-gnu -c -fsycl -fsycl-device-obj=spirv -ccc-print-phases %s 2>&1 | \
23+
// RUN: FileCheck %s -check-prefix SPIRV_DEVICE_OBJ_PHASES
24+
// SPIRV_DEVICE_OBJ_PHASES: 0: input, "[[INPUTSRC:.+\.cpp]]", c++, (device-sycl)
25+
// SPIRV_DEVICE_OBJ_PHASES: 1: preprocessor, {0}, c++-cpp-output, (device-sycl)
26+
// SPIRV_DEVICE_OBJ_PHASES: 2: compiler, {1}, ir, (device-sycl)
27+
// SPIRV_DEVICE_OBJ_PHASES: 3: llvm-spirv, {2}, spirv, (device-sycl)
28+
// SPIRV_DEVICE_OBJ_PHASES: 4: offload, "device-sycl (spir64-unknown-unknown)" {3}, spirv
29+
// SPIRV_DEVICE_OBJ_PHASES: 5: input, "[[INPUTSRC]]", c++, (host-sycl)
30+
// SPIRV_DEVICE_OBJ_PHASES: 6: append-footer, {5}, c++, (host-sycl)
31+
// SPIRV_DEVICE_OBJ_PHASES: 7: preprocessor, {6}, c++-cpp-output, (host-sycl)
32+
// SPIRV_DEVICE_OBJ_PHASES: 8: offload, "host-sycl (x86_64-unknown-linux-gnu)" {7}, "device-sycl (spir64-unknown-unknown)" {3}, c++-cpp-output
33+
// SPIRV_DEVICE_OBJ_PHASES: 9: compiler, {8}, ir, (host-sycl)
34+
// SPIRV_DEVICE_OBJ_PHASES: 10: backend, {9}, assembler, (host-sycl)
35+
// SPIRV_DEVICE_OBJ_PHASES: 11: assembler, {10}, object, (host-sycl)
36+
// SPIRV_DEVICE_OBJ_PHASES: 12: clang-offload-bundler, {4, 11}, object, (host-sycl)

0 commit comments

Comments
 (0)