From 367bd5c3e8de87c379fb152680802e356f7d45cc Mon Sep 17 00:00:00 2001 From: Michael D Toguchi Date: Mon, 6 May 2024 15:01:45 -0700 Subject: [PATCH 1/3] [Driver][SYCL][NewOffloadModel] Hook up -fsycl-device-only behaviors When using -fsycl-device-only with the new offloading model, update the behaviors to properly restrict the compilation flow to only produce the device binary. This more tightly integrates with the existing --offload-device-only option that is commonly used. --- clang/lib/Driver/Driver.cpp | 27 ++++++++++++--------- clang/lib/Driver/ToolChains/Clang.cpp | 2 +- clang/lib/Driver/ToolChains/Cuda.cpp | 4 +-- clang/lib/Driver/ToolChains/HIPAMD.cpp | 4 +-- clang/test/Driver/sycl-offload-new-driver.c | 13 ++++++++++ 5 files changed, 33 insertions(+), 17 deletions(-) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index b6e0fa33dd9f5..a68ed40df8a51 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -1733,12 +1733,13 @@ Compilation *Driver::BuildCompilation(ArrayRef ArgList) { if (Args.getLastArg(options::OPT_fsycl_dump_device_code_EQ)) DumpDeviceCode = true; - if (const Arg *A = Args.getLastArg(options::OPT_offload_host_only, - options::OPT_offload_device_only, - options::OPT_offload_host_device)) { + if (const Arg *A = Args.getLastArg( + options::OPT_offload_host_only, options::OPT_offload_device_only, + options::OPT_offload_host_device, options::OPT_fsycl_device_only)) { if (A->getOption().matches(options::OPT_offload_host_only)) Offload = OffloadHost; - else if (A->getOption().matches(options::OPT_offload_device_only)) + else if (A->getOption().matches(options::OPT_offload_device_only) || + A->getOption().matches(options::OPT_fsycl_device_only)) Offload = OffloadDevice; else Offload = OffloadHostDevice; @@ -4944,7 +4945,7 @@ class OffloadingActionBuilder final { getDeviceDependences(OffloadAction::DeviceDependences &DA, phases::ID CurPhase, phases::ID FinalPhase, PhasesTy &Phases) override { - bool SYCLDeviceOnly = Args.hasArg(options::OPT_fsycl_device_only); + bool SYCLDeviceOnly = C.getDriver().offloadDeviceOnly(); if (CurPhase == phases::Preprocess) { // Do not perform the host compilation when doing preprocessing only // with -fsycl-device-only. @@ -8130,12 +8131,14 @@ Action *Driver::ConstructPhaseAction( return C.MakeAction(Input, Output); } if (Args.hasArg(options::OPT_emit_llvm) || - (((Input->getOffloadingToolChain() && - Input->getOffloadingToolChain()->getTriple().isAMDGPU()) || - TargetDeviceOffloadKind == Action::OFK_HIP) && - (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc, - false) || - TargetDeviceOffloadKind == Action::OFK_OpenMP))) { + ((TargetDeviceOffloadKind == Action::OFK_SYCL && + C.getDriver().getUseNewOffloadingDriver() && offloadDeviceOnly()) || + (((Input->getOffloadingToolChain() && + Input->getOffloadingToolChain()->getTriple().isAMDGPU()) || + TargetDeviceOffloadKind == Action::OFK_HIP) && + (Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc, + false) || + TargetDeviceOffloadKind == Action::OFK_OpenMP)))) { types::ID Output = Args.hasArg(options::OPT_S) && (TargetDeviceOffloadKind == Action::OFK_None || @@ -9392,7 +9395,7 @@ const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA, if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o)) return C.addResultFile(FinalOutput->getValue(), &JA); // Output to destination for -fsycl-device-only and Windows -o - if (C.getArgs().hasArg(options::OPT_fsycl_device_only)) + if (offloadDeviceOnly() && JA.getOffloadingDeviceKind() == Action::OFK_SYCL) if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT__SLASH_o)) return C.addResultFile(FinalOutput->getValue(), &JA); } diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index e079b1e5aa53a..306677c812dcf 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -10359,7 +10359,7 @@ static void getOtherSPIRVTransOpts(Compilation &C, C.getDriver().getFinalPhase(C.getArgs()) != phases::Link && TCArgs.getLastArgValue(options::OPT_fsycl_device_obj_EQ) .equals_insensitive("spirv") && - !TCArgs.hasArg(options::OPT_fsycl_device_only); + !C.getDriver().offloadDeviceOnly(); bool ShouldPreserveMetadataInFinalImage = TCArgs.hasArg(options::OPT_fsycl_preserve_device_nonsemantic_metadata); bool ShouldPreserveMetadata = diff --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp index a0c5dd5ed9b7b..20eb94e141220 100644 --- a/clang/lib/Driver/ToolChains/Cuda.cpp +++ b/clang/lib/Driver/ToolChains/Cuda.cpp @@ -980,8 +980,8 @@ void CudaToolChain::addClangTargetOptions( } } - auto NoLibSpirv = DriverArgs.hasArg(options::OPT_fno_sycl_libspirv, - options::OPT_fsycl_device_only); + auto NoLibSpirv = DriverArgs.hasArg(options::OPT_fno_sycl_libspirv) || + getDriver().offloadDeviceOnly(); if (DeviceOffloadingKind == Action::OFK_SYCL && !NoLibSpirv) { std::string LibSpirvFile; diff --git a/clang/lib/Driver/ToolChains/HIPAMD.cpp b/clang/lib/Driver/ToolChains/HIPAMD.cpp index 567982e9a88ec..f223357a95e4c 100644 --- a/clang/lib/Driver/ToolChains/HIPAMD.cpp +++ b/clang/lib/Driver/ToolChains/HIPAMD.cpp @@ -284,8 +284,8 @@ void HIPAMDToolChain::addClangTargetOptions( CC1Args); } - auto NoLibSpirv = DriverArgs.hasArg(options::OPT_fno_sycl_libspirv, - options::OPT_fsycl_device_only); + auto NoLibSpirv = DriverArgs.hasArg(options::OPT_fno_sycl_libspirv) || + getDriver().offloadDeviceOnly(); if (DeviceOffloadingKind == Action::OFK_SYCL && !NoLibSpirv) { std::string LibSpirvFile; diff --git a/clang/test/Driver/sycl-offload-new-driver.c b/clang/test/Driver/sycl-offload-new-driver.c index 113d7ab3bfa95..1bcd078d58556 100644 --- a/clang/test/Driver/sycl-offload-new-driver.c +++ b/clang/test/Driver/sycl-offload-new-driver.c @@ -52,3 +52,16 @@ // RUN: | FileCheck -check-prefix WRAPPER_OPTIONS_POSTLINK %s // WRAPPER_OPTIONS_POSTLINK: clang-linker-wrapper{{.*}} "--triple=spir64" // WRAPPER_OPTIONS_POSTLINK-SAME: "--sycl-post-link-options=-post-link-opt" + +// -fsycl-device-only behavior +// RUN: %clangxx --target=x86_64-unknown-linux-gnu -fsycl --offload-new-driver \ +// RUN: -fsycl-device-only -ccc-print-phases %s 2>&1 \ +// RUN | FileCheck -check-prefix DEVICE_ONLY %s +// RUN: %clangxx --target=x86_64-unknown-linux-gnu -fsycl --offload-new-driver \ +// RUN: --offload-device-only -ccc-print-phases %s 2>&1 \ +// RUN: | FileCheck -check-prefix DEVICE_ONLY %s +// DEVICE_ONLY: 0: input, "{{.*}}", c++, (device-sycl) +// DEVICE_ONLY: 1: preprocessor, {0}, c++-cpp-output, (device-sycl) +// DEVICE_ONLY: 2: compiler, {1}, ir, (device-sycl) +// DEVICE_ONLY: 3: backend, {2}, ir, (device-sycl) +// DEVICE_ONLY: 4: offload, "device-sycl (spir64-unknown-unknown)" {3}, none From 2cdc416e3c53031df9f9250338a75f08cad8cdb6 Mon Sep 17 00:00:00 2001 From: Michael D Toguchi Date: Mon, 6 May 2024 17:32:03 -0700 Subject: [PATCH 2/3] Adjust behaviors to allow for the backend step for all passes --- clang/lib/Driver/Driver.cpp | 2 +- clang/test/Driver/sycl-offload-new-driver.c | 26 ++++++++++----------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index a68ed40df8a51..379ab9bb1150a 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -8132,7 +8132,7 @@ Action *Driver::ConstructPhaseAction( } if (Args.hasArg(options::OPT_emit_llvm) || ((TargetDeviceOffloadKind == Action::OFK_SYCL && - C.getDriver().getUseNewOffloadingDriver() && offloadDeviceOnly()) || + C.getDriver().getUseNewOffloadingDriver()) || (((Input->getOffloadingToolChain() && Input->getOffloadingToolChain()->getTriple().isAMDGPU()) || TargetDeviceOffloadKind == Action::OFK_HIP) && diff --git a/clang/test/Driver/sycl-offload-new-driver.c b/clang/test/Driver/sycl-offload-new-driver.c index 9ce55d4de911c..e30f60b5e2a9a 100644 --- a/clang/test/Driver/sycl-offload-new-driver.c +++ b/clang/test/Driver/sycl-offload-new-driver.c @@ -10,20 +10,18 @@ // OFFLOAD-NEW-DRIVER: 4: input, "[[INPUT]]", c++, (device-sycl) // OFFLOAD-NEW-DRIVER: 5: preprocessor, {4}, c++-cpp-output, (device-sycl) // OFFLOAD-NEW-DRIVER: 6: compiler, {5}, ir, (device-sycl) -// OFFLOAD-NEW-DRIVER: 7: backend, {6}, assembler, (device-sycl) -// OFFLOAD-NEW-DRIVER: 8: assembler, {7}, object, (device-sycl) -// OFFLOAD-NEW-DRIVER: 9: offload, "device-sycl (nvptx64-nvidia-cuda)" {8}, object -// OFFLOAD-NEW-DRIVER: 10: input, "[[INPUT]]", c++, (device-sycl) -// OFFLOAD-NEW-DRIVER: 11: preprocessor, {10}, c++-cpp-output, (device-sycl) -// OFFLOAD-NEW-DRIVER: 12: compiler, {11}, ir, (device-sycl) -// OFFLOAD-NEW-DRIVER: 13: backend, {12}, assembler, (device-sycl) -// OFFLOAD-NEW-DRIVER: 14: assembler, {13}, object, (device-sycl) -// OFFLOAD-NEW-DRIVER: 15: offload, "device-sycl (spir64-unknown-unknown)" {14}, object -// OFFLOAD-NEW-DRIVER: 16: clang-offload-packager, {9, 15}, image, (device-sycl) -// OFFLOAD-NEW-DRIVER: 17: offload, "host-sycl (x86_64-unknown-linux-gnu)" {3}, "device-sycl (x86_64-unknown-linux-gnu)" {16}, ir -// OFFLOAD-NEW-DRIVER: 18: backend, {17}, assembler, (host-sycl) -// OFFLOAD-NEW-DRIVER: 19: assembler, {18}, object, (host-sycl) -// OFFLOAD-NEW-DRIVER: 20: clang-linker-wrapper, {19}, image, (host-sycl) +// OFFLOAD-NEW-DRIVER: 7: backend, {6}, ir, (device-sycl) +// OFFLOAD-NEW-DRIVER: 8: offload, "device-sycl (nvptx64-nvidia-cuda)" {7}, ir +// OFFLOAD-NEW-DRIVER: 9: input, "[[INPUT]]", c++, (device-sycl) +// OFFLOAD-NEW-DRIVER: 10: preprocessor, {9}, c++-cpp-output, (device-sycl) +// OFFLOAD-NEW-DRIVER: 11: compiler, {10}, ir, (device-sycl) +// OFFLOAD-NEW-DRIVER: 12: backend, {11}, ir, (device-sycl) +// OFFLOAD-NEW-DRIVER: 13: offload, "device-sycl (spir64-unknown-unknown)" {12}, ir +// OFFLOAD-NEW-DRIVER: 14: clang-offload-packager, {8, 13}, image, (device-sycl) +// OFFLOAD-NEW-DRIVER: 15: offload, "host-sycl (x86_64-unknown-linux-gnu)" {3}, "device-sycl (x86_64-unknown-linux-gnu)" {14}, ir +// OFFLOAD-NEW-DRIVER: 16: backend, {15}, assembler, (host-sycl) +// OFFLOAD-NEW-DRIVER: 17: assembler, {16}, object, (host-sycl) +// OFFLOAD-NEW-DRIVER: 18: clang-linker-wrapper, {17}, image, (host-sycl) /// Check the toolflow for SYCL compilation using new offload model // RUN: %clangxx -### --target=x86_64-unknown-linux-gnu -fsycl -fsycl-targets=spir64 --offload-new-driver %s 2>&1 | FileCheck -check-prefix=CHK-FLOW %s From 17651cc95f0c14f4d1f15ef3014ddc528bba66c5 Mon Sep 17 00:00:00 2001 From: Michael D Toguchi Date: Tue, 7 May 2024 08:39:36 -0700 Subject: [PATCH 3/3] Adjust phases used to allow for textual IR generation --- clang/lib/Driver/Driver.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 0b6c073c16b97..4b180c19cfd29 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -7882,9 +7882,9 @@ Action *Driver::BuildOffloadingActions(Compilation &C, break; } - // Backend/Assemble actions are not used for the SYCL device side - if (Kind == Action::OFK_SYCL && - (Phase == phases::Backend || Phase == phases::Assemble)) + // Assemble actions are not used for the SYCL device side. Both compile + // and backend actions are used to generate IR and textual IR if needed. + if (Kind == Action::OFK_SYCL && Phase == phases::Assemble) continue; auto TCAndArch = TCAndArchs.begin();