[clang] [llvm] [Driver][SYCL] Add initial SYCL offload compilation support (PR #107493)
Michael Toguchi via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 5 09:44:14 PST 2024
https://github.com/mdtoguchi updated https://github.com/llvm/llvm-project/pull/107493
>From 411203429a789330f044d6d7b2c0216cf21d816b Mon Sep 17 00:00:00 2001
From: Michael D Toguchi <michael.d.toguchi at intel.com>
Date: Thu, 29 Aug 2024 16:39:42 -0700
Subject: [PATCH 1/9] [Driver][SYCL] Add initial SYCL offload compilation
support
Introduces the SYCL based toolchain and initial toolchain construction
when using the '-fsycl' option. This option will enable SYCL based
offloading, creating a SPIR-V based IR file packaged into the compiled
host object.
This includes early support for creating the host/device object using
the new offloading model. The device object is created using the
spir64-unknown-unknown target triple.
New/Updated Options:
-fsycl Enables SYCL offloading for host and device
-fsycl-device-only
Enables device only compilation for SYCL
-fsycl-host-only
Enables host only compilation for SYCL
RFC Reference: https://discourse.llvm.org/t/rfc-sycl-driver-enhancements/74092
---
clang/include/clang/Driver/Action.h | 1 +
clang/include/clang/Driver/Driver.h | 4 +
clang/include/clang/Driver/Options.td | 15 +-
clang/include/clang/Driver/ToolChain.h | 4 +
clang/lib/Driver/Action.cpp | 8 +-
clang/lib/Driver/CMakeLists.txt | 1 +
clang/lib/Driver/Compilation.cpp | 9 +-
clang/lib/Driver/Driver.cpp | 109 ++++++++++++-
clang/lib/Driver/ToolChain.cpp | 3 +
clang/lib/Driver/ToolChains/Clang.cpp | 45 +++++-
clang/lib/Driver/ToolChains/Gnu.cpp | 3 +-
clang/lib/Driver/ToolChains/Gnu.h | 2 +
clang/lib/Driver/ToolChains/Linux.cpp | 5 +
clang/lib/Driver/ToolChains/Linux.h | 2 +
clang/lib/Driver/ToolChains/MSVC.cpp | 7 +-
clang/lib/Driver/ToolChains/MSVC.h | 5 +
clang/lib/Driver/ToolChains/SYCL.cpp | 202 ++++++++++++++++++++++++
clang/lib/Driver/ToolChains/SYCL.h | 82 ++++++++++
clang/test/Driver/sycl-offload-jit.cpp | 77 +++++++++
llvm/include/llvm/TargetParser/Triple.h | 7 +
20 files changed, 565 insertions(+), 26 deletions(-)
create mode 100644 clang/lib/Driver/ToolChains/SYCL.cpp
create mode 100644 clang/lib/Driver/ToolChains/SYCL.h
create mode 100644 clang/test/Driver/sycl-offload-jit.cpp
diff --git a/clang/include/clang/Driver/Action.h b/clang/include/clang/Driver/Action.h
index 04fa8b01b418f8..feeabae89d6b1c 100644
--- a/clang/include/clang/Driver/Action.h
+++ b/clang/include/clang/Driver/Action.h
@@ -94,6 +94,7 @@ class Action {
OFK_Cuda = 0x02,
OFK_OpenMP = 0x04,
OFK_HIP = 0x08,
+ OFK_SYCL = 0x10,
};
static const char *getClassName(ActionClass AC);
diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h
index 9177d56718ee77..ddadefaa079dd5 100644
--- a/clang/include/clang/Driver/Driver.h
+++ b/clang/include/clang/Driver/Driver.h
@@ -582,6 +582,10 @@ class Driver {
/// @name Helper Methods
/// @{
+ /// MakeSYCLDeviceTriple - Returns the SYCL device triple for the
+ /// specified ArchType.
+ llvm::Triple MakeSYCLDeviceTriple(StringRef TargetArch = "spir64") const;
+
/// PrintActions - Print the list of actions.
void PrintActions(const Compilation &C) const;
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 83cf753e824845..bd632f9270f382 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -182,7 +182,8 @@ def opencl_Group : OptionGroup<"<opencl group>">, Group<f_Group>,
DocName<"OpenCL options">;
def sycl_Group : OptionGroup<"<SYCL group>">, Group<f_Group>,
- DocName<"SYCL options">;
+ DocName<"SYCL options">,
+ Visibility<[ClangOption, CLOption]>;
def cuda_Group : OptionGroup<"<CUDA group>">, Group<f_Group>,
DocName<"CUDA options">,
@@ -6691,12 +6692,16 @@ defm : FlangIgnoredDiagOpt<"frontend-loop-interchange">;
defm : FlangIgnoredDiagOpt<"target-lifetime">;
// C++ SYCL options
+let Group = sycl_Group in {
def fsycl : Flag<["-"], "fsycl">,
- Visibility<[ClangOption, CLOption]>,
- Group<sycl_Group>, HelpText<"Enables SYCL kernels compilation for device">;
+ HelpText<"Enables SYCL kernels compilation for device">;
def fno_sycl : Flag<["-"], "fno-sycl">,
- Visibility<[ClangOption, CLOption]>,
- Group<sycl_Group>, HelpText<"Disables SYCL kernels compilation for device">;
+ HelpText<"Disables SYCL kernels compilation for device">;
+def fsycl_device_only : Flag<["-"], "fsycl-device-only">,
+ Alias<offload_device_only>, HelpText<"Compile SYCL kernels for device only">;
+def fsycl_host_only : Flag<["-"], "fsycl-host-only">,
+ Alias<offload_host_only>, HelpText<"Compile SYCL kernels for host only">;
+} // let Group = sycl_Group
// OS-specific options
let Flags = [TargetSpecific] in {
diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h
index 5347e29be91439..0bc2a28bceb923 100644
--- a/clang/include/clang/Driver/ToolChain.h
+++ b/clang/include/clang/Driver/ToolChain.h
@@ -762,6 +762,10 @@ class ToolChain {
virtual void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const;
+ /// Add arguments to use SYCL specific includes.
+ virtual void AddSYCLIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const;
+
/// Add arguments to use MCU GCC toolchain includes.
virtual void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const;
diff --git a/clang/lib/Driver/Action.cpp b/clang/lib/Driver/Action.cpp
index 849bf6035ebd2e..23dbcebc9a1ca1 100644
--- a/clang/lib/Driver/Action.cpp
+++ b/clang/lib/Driver/Action.cpp
@@ -111,6 +111,8 @@ std::string Action::getOffloadingKindPrefix() const {
return "device-openmp";
case OFK_HIP:
return "device-hip";
+ case OFK_SYCL:
+ return "device-sycl";
// TODO: Add other programming models here.
}
@@ -128,6 +130,8 @@ std::string Action::getOffloadingKindPrefix() const {
Res += "-hip";
if (ActiveOffloadKindMask & OFK_OpenMP)
Res += "-openmp";
+ if (ActiveOffloadKindMask & OFK_SYCL)
+ Res += "-sycl";
// TODO: Add other programming models here.
@@ -164,6 +168,8 @@ StringRef Action::GetOffloadKindName(OffloadKind Kind) {
return "openmp";
case OFK_HIP:
return "hip";
+ case OFK_SYCL:
+ return "sycl";
// TODO: Add other programming models here.
}
@@ -320,7 +326,7 @@ void OffloadAction::DeviceDependences::add(Action &A, const ToolChain &TC,
DeviceBoundArchs.push_back(BoundArch);
// Add each active offloading kind from a mask.
- for (OffloadKind OKind : {OFK_OpenMP, OFK_Cuda, OFK_HIP})
+ for (OffloadKind OKind : {OFK_OpenMP, OFK_Cuda, OFK_HIP, OFK_SYCL})
if (OKind & OffloadKindMask)
DeviceOffloadKinds.push_back(OKind);
}
diff --git a/clang/lib/Driver/CMakeLists.txt b/clang/lib/Driver/CMakeLists.txt
index 32a4378ab499fa..4cc5f730424cd5 100644
--- a/clang/lib/Driver/CMakeLists.txt
+++ b/clang/lib/Driver/CMakeLists.txt
@@ -85,6 +85,7 @@ add_clang_library(clangDriver
ToolChains/PPCFreeBSD.cpp
ToolChains/InterfaceStubs.cpp
ToolChains/ZOS.cpp
+ ToolChains/SYCL.cpp
Types.cpp
XRayArgs.cpp
diff --git a/clang/lib/Driver/Compilation.cpp b/clang/lib/Driver/Compilation.cpp
index ad077d5bbfa69a..283487548f4cf2 100644
--- a/clang/lib/Driver/Compilation.cpp
+++ b/clang/lib/Driver/Compilation.cpp
@@ -217,10 +217,11 @@ static bool ActionFailed(const Action *A,
if (FailingCommands.empty())
return false;
- // CUDA/HIP can have the same input source code compiled multiple times so do
- // not compiled again if there are already failures. It is OK to abort the
- // CUDA pipeline on errors.
- if (A->isOffloading(Action::OFK_Cuda) || A->isOffloading(Action::OFK_HIP))
+ // CUDA/HIP/SYCL can have the same input source code compiled multiple times
+ // so do not compile again if there are already failures. It is OK to abort
+ // the CUDA pipeline on errors.
+ if (A->isOffloading(Action::OFK_Cuda) || A->isOffloading(Action::OFK_HIP) ||
+ A->isOffloading(Action::OFK_SYCL))
return true;
for (const auto &CI : FailingCommands)
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 43002add33774b..b8d7401f6e01cc 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -43,6 +43,7 @@
#include "ToolChains/PS4CPU.h"
#include "ToolChains/RISCVToolchain.h"
#include "ToolChains/SPIRV.h"
+#include "ToolChains/SYCL.h"
#include "ToolChains/Solaris.h"
#include "ToolChains/TCE.h"
#include "ToolChains/VEToolchain.h"
@@ -767,6 +768,26 @@ Driver::OpenMPRuntimeKind Driver::getOpenMPRuntime(const ArgList &Args) const {
return RT;
}
+static const char *getDefaultSYCLArch(Compilation &C) {
+ if (C.getDefaultToolChain().getTriple().getArch() == llvm::Triple::x86)
+ return "spir";
+ return "spir64";
+}
+
+static bool addSYCLDefaultTriple(Compilation &C,
+ SmallVectorImpl<llvm::Triple> &SYCLTriples) {
+ for (const auto &SYCLTriple : SYCLTriples) {
+ if (SYCLTriple.getSubArch() == llvm::Triple::NoSubArch &&
+ SYCLTriple.isSPIROrSPIRV())
+ return false;
+ }
+ // Add the default triple as it was not found.
+ llvm::Triple DefaultTriple =
+ C.getDriver().MakeSYCLDeviceTriple(getDefaultSYCLArch(C));
+ SYCLTriples.insert(SYCLTriples.begin(), DefaultTriple);
+ return true;
+}
+
void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
InputList &Inputs) {
@@ -979,6 +1000,44 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
return;
}
+ //
+ // SYCL
+ //
+ // We need to generate a SYCL toolchain if the user specified -fsycl.
+ // If -fsycl is supplied we will assume SPIR-V.
+ bool IsSYCL =
+ C.getInputArgs().hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
+ false);
+
+ auto argSYCLIncompatible = [&](OptSpecifier OptId) {
+ if (!IsSYCL)
+ return;
+ if (Arg *IncompatArg = C.getInputArgs().getLastArg(OptId))
+ Diag(clang::diag::err_drv_argument_not_allowed_with)
+ << IncompatArg->getSpelling() << "-fsycl";
+ };
+ // -static-libstdc++ is not compatible with -fsycl.
+ argSYCLIncompatible(options::OPT_static_libstdcxx);
+ // -ffreestanding cannot be used with -fsycl
+ argSYCLIncompatible(options::OPT_ffreestanding);
+
+ llvm::SmallVector<llvm::Triple, 4> UniqueSYCLTriplesVec;
+
+ // If -fsycl is supplied we will assume SPIR-V.
+ if (IsSYCL) {
+ addSYCLDefaultTriple(C, UniqueSYCLTriplesVec);
+
+ // We'll need to use the SYCL and host triples as the key into
+ // getOffloadingDeviceToolChain, because the device toolchains we're
+ // going to create will depend on both.
+ const ToolChain *HostTC = C.getSingleOffloadToolChain<Action::OFK_Host>();
+ for (const auto &TT : UniqueSYCLTriplesVec) {
+ auto SYCLTC = &getOffloadingDeviceToolChain(C.getInputArgs(), TT, *HostTC,
+ Action::OFK_SYCL);
+ C.addOffloadDeviceToolChain(SYCLTC, Action::OFK_SYCL);
+ }
+ }
+
//
// TODO: Add support for other offloading programming models here.
//
@@ -2001,6 +2060,19 @@ void Driver::PrintHelp(bool ShowHidden) const {
VisibilityMask);
}
+llvm::Triple Driver::MakeSYCLDeviceTriple(StringRef TargetArch) const {
+ SmallVector<StringRef, 5> SYCLAlias = { "spir", "spir64", "spirv32", "spirv64"};
+ if (std::find(SYCLAlias.begin(), SYCLAlias.end(), TargetArch) !=
+ SYCLAlias.end()) {
+ llvm::Triple TT;
+ TT.setArchName(TargetArch);
+ TT.setVendor(llvm::Triple::UnknownVendor);
+ TT.setOS(llvm::Triple::UnknownOS);
+ return TT;
+ }
+ return llvm::Triple(TargetArch);
+}
+
void Driver::PrintVersion(const Compilation &C, raw_ostream &OS) const {
if (IsFlangMode()) {
OS << getClangToolFullVersion("flang-new") << '\n';
@@ -4155,6 +4227,7 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
bool UseNewOffloadingDriver =
C.isOffloadingHostKind(Action::OFK_OpenMP) ||
+ C.isOffloadingHostKind(Action::OFK_SYCL) ||
Args.hasFlag(options::OPT_foffload_via_llvm,
options::OPT_fno_offload_via_llvm, false) ||
Args.hasFlag(options::OPT_offload_new_driver,
@@ -4565,6 +4638,8 @@ Driver::getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args,
Archs.insert(OffloadArchToString(OffloadArch::HIPDefault));
else if (Kind == Action::OFK_OpenMP)
Archs.insert(StringRef());
+ else if (Kind == Action::OFK_SYCL)
+ Archs.insert(StringRef());
} else {
Args.ClaimAllArgs(options::OPT_offload_arch_EQ);
Args.ClaimAllArgs(options::OPT_no_offload_arch_EQ);
@@ -4589,7 +4664,7 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
OffloadAction::DeviceDependences DDeps;
const Action::OffloadKind OffloadKinds[] = {
- Action::OFK_OpenMP, Action::OFK_Cuda, Action::OFK_HIP};
+ Action::OFK_OpenMP, Action::OFK_Cuda, Action::OFK_HIP, Action::OFK_SYCL};
for (Action::OffloadKind Kind : OffloadKinds) {
SmallVector<const ToolChain *, 2> ToolChains;
@@ -4634,6 +4709,11 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
break;
}
+ // 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();
for (Action *&A : DeviceActions) {
if (A->getType() == types::TY_Nothing)
@@ -4867,12 +4947,13 @@ Action *Driver::ConstructPhaseAction(
return C.MakeAction<BackendJobAction>(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 ||
+ (((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 ||
@@ -6553,6 +6634,20 @@ const ToolChain &Driver::getOffloadingDeviceToolChain(
HostTC, Args);
break;
}
+ case Action::OFK_SYCL:
+ // TODO: Add additional Arch values for Ahead of Time support for SYCL.
+ switch (Target.getArch()) {
+ case llvm::Triple::spir:
+ case llvm::Triple::spir64:
+ case llvm::Triple::spirv32:
+ case llvm::Triple::spirv64:
+ TC = std::make_unique<toolchains::SYCLToolChain>(*this, Target, HostTC,
+ Args);
+ break;
+ default:
+ break;
+ }
+ break;
default:
break;
}
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 76901875c66959..f5b7837e3e3fc4 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -1441,6 +1441,9 @@ void ToolChain::AddCudaIncludeArgs(const ArgList &DriverArgs,
void ToolChain::AddHIPIncludeArgs(const ArgList &DriverArgs,
ArgStringList &CC1Args) const {}
+void ToolChain::AddSYCLIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const {}
+
llvm::SmallVector<ToolChain::BitCodeLibraryInfo, 12>
ToolChain::getDeviceLibs(const ArgList &DriverArgs) const {
return {};
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index df86941950e46e..c8398113313bc4 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -24,6 +24,7 @@
#include "Hexagon.h"
#include "MSP430.h"
#include "PS4CPU.h"
+#include "SYCL.h"
#include "clang/Basic/CLWarnings.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/CodeGenOptions.h"
@@ -1073,6 +1074,8 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
getToolChain().AddCudaIncludeArgs(Args, CmdArgs);
if (JA.isOffloading(Action::OFK_HIP))
getToolChain().AddHIPIncludeArgs(Args, CmdArgs);
+ if (JA.isOffloading(Action::OFK_SYCL))
+ getToolChain().AddSYCLIncludeArgs(Args, CmdArgs);
// If we are offloading to a target via OpenMP we need to include the
// openmp_wrappers folder which contains alternative system headers.
@@ -4969,17 +4972,21 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// second input. Module precompilation accepts a list of header files to
// include as part of the module. API extraction accepts a list of header
// files whose API information is emitted in the output. All other jobs are
- // expected to have exactly one input.
+ // expected to have exactly one input. SYCL compilation only expects a
+ // single input.
bool IsCuda = JA.isOffloading(Action::OFK_Cuda);
bool IsCudaDevice = JA.isDeviceOffloading(Action::OFK_Cuda);
bool IsHIP = JA.isOffloading(Action::OFK_HIP);
bool IsHIPDevice = JA.isDeviceOffloading(Action::OFK_HIP);
+ bool IsSYCL = JA.isOffloading(Action::OFK_SYCL);
+ bool IsSYCLDevice = JA.isDeviceOffloading(Action::OFK_SYCL);
bool IsOpenMPDevice = JA.isDeviceOffloading(Action::OFK_OpenMP);
bool IsExtractAPI = isa<ExtractAPIJobAction>(JA);
bool IsDeviceOffloadAction = !(JA.isDeviceOffloading(Action::OFK_None) ||
JA.isDeviceOffloading(Action::OFK_Host));
bool IsHostOffloadingAction =
JA.isHostOffloading(Action::OFK_OpenMP) ||
+ JA.isHostOffloading(Action::OFK_SYCL) ||
(JA.isHostOffloading(C.getActiveOffloadKinds()) &&
Args.hasFlag(options::OPT_offload_new_driver,
options::OPT_no_offload_new_driver, false));
@@ -5029,10 +5036,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
bool IsWindowsMSVC = RawTriple.isWindowsMSVCEnvironment();
bool IsIAMCU = RawTriple.isOSIAMCU();
- // Adjust IsWindowsXYZ for CUDA/HIP compilations. Even when compiling in
+ // Adjust IsWindowsXYZ for CUDA/HIP/SYCL compilations. Even when compiling in
// device mode (i.e., getToolchain().getTriple() is NVPTX/AMDGCN, not
// Windows), we need to pass Windows-specific flags to cc1.
- if (IsCuda || IsHIP)
+ if (IsCuda || IsHIP || IsSYCL)
IsWindowsMSVC |= AuxTriple && AuxTriple->isWindowsMSVCEnvironment();
// C++ is not supported for IAMCU.
@@ -5116,15 +5123,39 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (const Arg *PF = Args.getLastArg(options::OPT_mprintf_kind_EQ))
PF->claim();
- if (Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false)) {
+ Arg *SYCLStdArg = Args.getLastArg(options::OPT_sycl_std_EQ);
+
+ if (IsSYCLDevice) {
+ // Host triple is needed when doing SYCL device compilations.
+ llvm::Triple AuxT = C.getDefaultToolChain().getTriple();
+ std::string NormalizedTriple = AuxT.normalize();
+ CmdArgs.push_back("-aux-triple");
+ CmdArgs.push_back(Args.MakeArgString(NormalizedTriple));
+
+ // We want to compile sycl kernels.
CmdArgs.push_back("-fsycl-is-device");
- if (Arg *A = Args.getLastArg(options::OPT_sycl_std_EQ)) {
- A->render(Args, CmdArgs);
+ // Set O2 optimization level by default
+ if (!Args.getLastArg(options::OPT_O_Group))
+ CmdArgs.push_back("-O2");
+ }
+
+ if (IsSYCL) {
+ // Set options for both host and device
+ if (SYCLStdArg) {
+ SYCLStdArg->render(Args, CmdArgs);
} else {
// Ensure the default version in SYCL mode is 2020.
CmdArgs.push_back("-sycl-std=2020");
}
+
+ // Add any options that are needed specific to SYCL offload while
+ // performing the host side compilation.
+ if (!IsSYCLDevice) {
+ // Let the front-end host compilation flow know about SYCL offload
+ // compilation.
+ CmdArgs.push_back("-fsycl-is-host");
+ }
}
if (IsOpenMPDevice) {
@@ -6061,7 +6092,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// Prepare `-aux-target-cpu` and `-aux-target-feature` unless
// `--gpu-use-aux-triple-only` is specified.
if (!Args.getLastArg(options::OPT_gpu_use_aux_triple_only) &&
- (IsCudaDevice || IsHIPDevice)) {
+ (IsCudaDevice || IsHIPDevice || IsSYCLDevice)) {
const ArgList &HostArgs =
C.getArgsForToolChain(nullptr, StringRef(), Action::OFK_None);
std::string HostCPU =
diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
index 52c2ee90b1b286..129413af750614 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -3051,7 +3051,8 @@ bool Generic_GCC::GCCInstallationDetector::ScanGentooGccConfig(
Generic_GCC::Generic_GCC(const Driver &D, const llvm::Triple &Triple,
const ArgList &Args)
: ToolChain(D, Triple, Args), GCCInstallation(D),
- CudaInstallation(D, Triple, Args), RocmInstallation(D, Triple, Args) {
+ CudaInstallation(D, Triple, Args), RocmInstallation(D, Triple, Args),
+ SYCLInstallation(D) {
getProgramPaths().push_back(getDriver().Dir);
}
diff --git a/clang/lib/Driver/ToolChains/Gnu.h b/clang/lib/Driver/ToolChains/Gnu.h
index 0b664a182d75e1..4c5ecf5401746a 100644
--- a/clang/lib/Driver/ToolChains/Gnu.h
+++ b/clang/lib/Driver/ToolChains/Gnu.h
@@ -12,6 +12,7 @@
#include "Cuda.h"
#include "LazyDetector.h"
#include "ROCm.h"
+#include "SYCL.h"
#include "clang/Driver/Tool.h"
#include "clang/Driver/ToolChain.h"
#include <set>
@@ -288,6 +289,7 @@ class LLVM_LIBRARY_VISIBILITY Generic_GCC : public ToolChain {
GCCInstallationDetector GCCInstallation;
LazyDetector<CudaInstallationDetector> CudaInstallation;
LazyDetector<RocmInstallationDetector> RocmInstallation;
+ SYCLInstallationDetector SYCLInstallation;
public:
Generic_GCC(const Driver &D, const llvm::Triple &Triple,
diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp
index 96680b3412a2db..bf5d61fa3a7f00 100644
--- a/clang/lib/Driver/ToolChains/Linux.cpp
+++ b/clang/lib/Driver/ToolChains/Linux.cpp
@@ -755,6 +755,11 @@ void Linux::AddIAMCUIncludeArgs(const ArgList &DriverArgs,
}
}
+void Linux::AddSYCLIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const {
+ SYCLInstallation.AddSYCLIncludeArgs(DriverArgs, CC1Args);
+}
+
bool Linux::isPIEDefault(const llvm::opt::ArgList &Args) const {
return CLANG_DEFAULT_PIE_ON_LINUX || getTriple().isAndroid() ||
getTriple().isMusl() || getSanitizerArgs(Args).requiresPIE();
diff --git a/clang/lib/Driver/ToolChains/Linux.h b/clang/lib/Driver/ToolChains/Linux.h
index 2d9e674e50a630..cdec2fd39bbfa0 100644
--- a/clang/lib/Driver/ToolChains/Linux.h
+++ b/clang/lib/Driver/ToolChains/Linux.h
@@ -41,6 +41,8 @@ class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF {
llvm::opt::ArgStringList &CmdArgs) const override;
void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const override;
+ void AddSYCLIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const override;
RuntimeLibType GetDefaultRuntimeLibType() const override;
unsigned GetDefaultDwarfVersion() const override;
CXXStdlibType GetDefaultCXXStdlibType() const override;
diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp
index ca266e3e1d1d3c..5ccad55d675335 100644
--- a/clang/lib/Driver/ToolChains/MSVC.cpp
+++ b/clang/lib/Driver/ToolChains/MSVC.cpp
@@ -427,7 +427,7 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
MSVCToolChain::MSVCToolChain(const Driver &D, const llvm::Triple &Triple,
const ArgList &Args)
: ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args),
- RocmInstallation(D, Triple, Args) {
+ RocmInstallation(D, Triple, Args), SYCLInstallation(D) {
getProgramPaths().push_back(getDriver().Dir);
std::optional<llvm::StringRef> VCToolsDir, VCToolsVersion;
@@ -506,6 +506,11 @@ void MSVCToolChain::AddHIPIncludeArgs(const ArgList &DriverArgs,
RocmInstallation->AddHIPIncludeArgs(DriverArgs, CC1Args);
}
+void MSVCToolChain::AddSYCLIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const {
+ SYCLInstallation.AddSYCLIncludeArgs(DriverArgs, CC1Args);
+}
+
void MSVCToolChain::AddHIPRuntimeLibArgs(const ArgList &Args,
ArgStringList &CmdArgs) const {
CmdArgs.append({Args.MakeArgString(StringRef("-libpath:") +
diff --git a/clang/lib/Driver/ToolChains/MSVC.h b/clang/lib/Driver/ToolChains/MSVC.h
index 3950a8ed38e8b4..6485fe6ba63a1e 100644
--- a/clang/lib/Driver/ToolChains/MSVC.h
+++ b/clang/lib/Driver/ToolChains/MSVC.h
@@ -12,6 +12,7 @@
#include "AMDGPU.h"
#include "Cuda.h"
#include "LazyDetector.h"
+#include "SYCL.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Tool.h"
#include "clang/Driver/ToolChain.h"
@@ -100,6 +101,9 @@ class LLVM_LIBRARY_VISIBILITY MSVCToolChain : public ToolChain {
void AddHIPRuntimeLibArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const override;
+ void AddSYCLIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const override;
+
bool getWindowsSDKLibraryPath(
const llvm::opt::ArgList &Args, std::string &path) const;
bool getUniversalCRTLibraryPath(const llvm::opt::ArgList &Args,
@@ -138,6 +142,7 @@ class LLVM_LIBRARY_VISIBILITY MSVCToolChain : public ToolChain {
llvm::ToolsetLayout VSLayout = llvm::ToolsetLayout::OlderVS;
LazyDetector<CudaInstallationDetector> CudaInstallation;
LazyDetector<RocmInstallationDetector> RocmInstallation;
+ SYCLInstallationDetector SYCLInstallation;
};
} // end namespace toolchains
diff --git a/clang/lib/Driver/ToolChains/SYCL.cpp b/clang/lib/Driver/ToolChains/SYCL.cpp
new file mode 100644
index 00000000000000..a82cc8f775707e
--- /dev/null
+++ b/clang/lib/Driver/ToolChains/SYCL.cpp
@@ -0,0 +1,202 @@
+//===--- SYCL.cpp - SYCL Tool and ToolChain Implementations -----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#include "SYCL.h"
+#include "CommonArgs.h"
+#include "clang/Driver/Action.h"
+#include "clang/Driver/Compilation.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/InputInfo.h"
+#include "clang/Driver/Options.h"
+#include "llvm/Option/Option.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include <algorithm>
+#include <sstream>
+
+using namespace clang::driver;
+using namespace clang::driver::toolchains;
+using namespace clang::driver::tools;
+using namespace clang;
+using namespace llvm::opt;
+
+SYCLInstallationDetector::SYCLInstallationDetector(const Driver &D)
+ : D(D), InstallationCandidates() {
+ InstallationCandidates.emplace_back(D.Dir + "/..");
+}
+
+void SYCLInstallationDetector::AddSYCLIncludeArgs(
+ const ArgList &DriverArgs, ArgStringList &CC1Args) const {
+ // Add the SYCL header search locations in the specified order.
+ // ../include/sycl
+ // ../include/sycl/stl_wrappers
+ // ../include
+ SmallString<128> IncludePath(D.Dir);
+ llvm::sys::path::append(IncludePath, "..");
+ llvm::sys::path::append(IncludePath, "include");
+ SmallString<128> SYCLPath(IncludePath);
+ llvm::sys::path::append(SYCLPath, "sycl");
+ // This is used to provide our wrappers around STL headers that provide
+ // additional functions/template specializations when the user includes those
+ // STL headers in their programs (e.g., <complex>).
+ SmallString<128> STLWrappersPath(SYCLPath);
+ llvm::sys::path::append(STLWrappersPath, "stl_wrappers");
+ CC1Args.push_back("-internal-isystem");
+ CC1Args.push_back(DriverArgs.MakeArgString(SYCLPath));
+ CC1Args.push_back("-internal-isystem");
+ CC1Args.push_back(DriverArgs.MakeArgString(STLWrappersPath));
+ CC1Args.push_back("-internal-isystem");
+ CC1Args.push_back(DriverArgs.MakeArgString(IncludePath));
+}
+
+void SYCLInstallationDetector::print(llvm::raw_ostream &OS) const {
+ if (!InstallationCandidates.size())
+ return;
+ OS << "SYCL Installation Candidates: \n";
+ for (const auto &IC : InstallationCandidates) {
+ OS << IC << "\n";
+ }
+}
+
+// Unsupported options for SYCL device compilation
+// -fcf-protection, -fsanitize, -fprofile-generate, -fprofile-instr-generate
+// -ftest-coverage, -fcoverage-mapping, -fcreate-profile, -fprofile-arcs
+// -fcs-profile-generate -forder-file-instrumentation, --coverage
+static std::vector<OptSpecifier> getUnsupportedOpts(void) {
+ std::vector<OptSpecifier> UnsupportedOpts = {
+ options::OPT_fsanitize_EQ,
+ options::OPT_fcf_protection_EQ,
+ options::OPT_fprofile_generate,
+ options::OPT_fprofile_generate_EQ,
+ options::OPT_fno_profile_generate,
+ options::OPT_ftest_coverage,
+ options::OPT_fno_test_coverage,
+ options::OPT_fcoverage_mapping,
+ options::OPT_fno_coverage_mapping,
+ options::OPT_coverage,
+ options::OPT_fprofile_instr_generate,
+ options::OPT_fprofile_instr_generate_EQ,
+ options::OPT_fprofile_arcs,
+ options::OPT_fno_profile_arcs,
+ options::OPT_fno_profile_instr_generate,
+ options::OPT_fcreate_profile,
+ options::OPT_fprofile_instr_use,
+ options::OPT_fprofile_instr_use_EQ,
+ options::OPT_forder_file_instrumentation,
+ options::OPT_fcs_profile_generate,
+ options::OPT_fcs_profile_generate_EQ};
+ return UnsupportedOpts;
+}
+
+SYCLToolChain::SYCLToolChain(const Driver &D, const llvm::Triple &Triple,
+ const ToolChain &HostTC, const ArgList &Args)
+ : ToolChain(D, Triple, Args), HostTC(HostTC), SYCLInstallation(D) {
+ // Lookup binaries into the driver directory, this is used to discover any
+ // dependent SYCL offload compilation tools.
+ getProgramPaths().push_back(getDriver().Dir);
+
+ // Diagnose unsupported options only once.
+ for (OptSpecifier Opt : getUnsupportedOpts()) {
+ if (const Arg *A = Args.getLastArg(Opt)) {
+ // All sanitizer options are not currently supported, except
+ // AddressSanitizer
+ if (A->getOption().getID() == options::OPT_fsanitize_EQ &&
+ A->getValues().size() == 1) {
+ std::string SanitizeVal = A->getValue();
+ if (SanitizeVal == "address")
+ continue;
+ }
+ D.Diag(clang::diag::warn_drv_unsupported_option_for_target)
+ << A->getAsString(Args) << getTriple().str();
+ }
+ }
+}
+
+void SYCLToolChain::addClangTargetOptions(
+ const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
+ Action::OffloadKind DeviceOffloadingKind) const {
+ HostTC.addClangTargetOptions(DriverArgs, CC1Args, DeviceOffloadingKind);
+}
+
+llvm::opt::DerivedArgList *
+SYCLToolChain::TranslateArgs(const llvm::opt::DerivedArgList &Args,
+ StringRef BoundArch,
+ Action::OffloadKind DeviceOffloadKind) const {
+ DerivedArgList *DAL =
+ HostTC.TranslateArgs(Args, BoundArch, DeviceOffloadKind);
+
+ bool IsNewDAL = false;
+ if (!DAL) {
+ DAL = new DerivedArgList(Args.getBaseArgs());
+ IsNewDAL = true;
+ }
+
+ for (Arg *A : Args) {
+ // Filter out any options we do not want to pass along to the device
+ // compilation.
+ auto Opt(A->getOption());
+ bool Unsupported = false;
+ for (OptSpecifier UnsupportedOpt : getUnsupportedOpts()) {
+ if (Opt.matches(UnsupportedOpt)) {
+ if (Opt.getID() == options::OPT_fsanitize_EQ &&
+ A->getValues().size() == 1) {
+ std::string SanitizeVal = A->getValue();
+ if (SanitizeVal == "address") {
+ if (IsNewDAL)
+ DAL->append(A);
+ continue;
+ }
+ }
+ if (!IsNewDAL)
+ DAL->eraseArg(Opt.getID());
+ Unsupported = true;
+ }
+ }
+ if (Unsupported)
+ continue;
+ if (IsNewDAL)
+ DAL->append(A);
+ }
+
+ const OptTable &Opts = getDriver().getOpts();
+ if (!BoundArch.empty()) {
+ DAL->eraseArg(options::OPT_march_EQ);
+ DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_march_EQ),
+ BoundArch);
+ }
+ return DAL;
+}
+
+void SYCLToolChain::addClangWarningOptions(ArgStringList &CC1Args) const {
+ HostTC.addClangWarningOptions(CC1Args);
+}
+
+ToolChain::CXXStdlibType
+SYCLToolChain::GetCXXStdlibType(const ArgList &Args) const {
+ return HostTC.GetCXXStdlibType(Args);
+}
+
+void SYCLToolChain::AddSYCLIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const {
+ SYCLInstallation.AddSYCLIncludeArgs(DriverArgs, CC1Args);
+}
+
+void SYCLToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const {
+ HostTC.AddClangSystemIncludeArgs(DriverArgs, CC1Args);
+}
+
+void SYCLToolChain::AddClangCXXStdlibIncludeArgs(const ArgList &Args,
+ ArgStringList &CC1Args) const {
+ HostTC.AddClangCXXStdlibIncludeArgs(Args, CC1Args);
+}
+
+SanitizerMask SYCLToolChain::getSupportedSanitizers() const {
+ return SanitizerKind::Address;
+}
diff --git a/clang/lib/Driver/ToolChains/SYCL.h b/clang/lib/Driver/ToolChains/SYCL.h
new file mode 100644
index 00000000000000..80dd5b204d53f3
--- /dev/null
+++ b/clang/lib/Driver/ToolChains/SYCL.h
@@ -0,0 +1,82 @@
+//===--- SYCL.h - SYCL ToolChain Implementations ----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_SYCL_H
+#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_SYCL_H
+
+#include "clang/Driver/Tool.h"
+#include "clang/Driver/ToolChain.h"
+
+namespace clang {
+namespace driver {
+
+class SYCLInstallationDetector {
+public:
+ SYCLInstallationDetector(const Driver &D);
+ void AddSYCLIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const;
+ void print(llvm::raw_ostream &OS) const;
+
+private:
+ const Driver &D;
+ llvm::SmallVector<llvm::SmallString<128>, 4> InstallationCandidates;
+};
+
+namespace toolchains {
+
+class LLVM_LIBRARY_VISIBILITY SYCLToolChain : public ToolChain {
+public:
+ SYCLToolChain(const Driver &D, const llvm::Triple &Triple,
+ const ToolChain &HostTC, const llvm::opt::ArgList &Args);
+
+ const llvm::Triple *getAuxTriple() const override {
+ return &HostTC.getTriple();
+ }
+
+ llvm::opt::DerivedArgList *
+ TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
+ Action::OffloadKind DeviceOffloadKind) const override;
+ void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args,
+ Action::OffloadKind DeviceOffloadKind) const override;
+
+ bool useIntegratedAs() const override { return true; }
+ bool isPICDefault() const override { return false; }
+ llvm::codegenoptions::DebugInfoFormat getDefaultDebugFormat() const override {
+ if (this->HostTC.getTriple().isWindowsMSVCEnvironment())
+ return this->HostTC.getDefaultDebugFormat();
+ return ToolChain::getDefaultDebugFormat();
+ }
+ bool isPIEDefault(const llvm::opt::ArgList &Args) const override {
+ return false;
+ }
+ bool isPICDefaultForced() const override { return false; }
+
+ void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override;
+ CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override;
+ void AddSYCLIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const override;
+ void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args) const override;
+ void AddClangCXXStdlibIncludeArgs(
+ const llvm::opt::ArgList &Args,
+ llvm::opt::ArgStringList &CC1Args) const override;
+
+ SanitizerMask getSupportedSanitizers() const override;
+
+ const ToolChain &HostTC;
+
+ SYCLInstallationDetector SYCLInstallation;
+};
+
+} // end namespace toolchains
+
+} // end namespace driver
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_SYCL_H
diff --git a/clang/test/Driver/sycl-offload-jit.cpp b/clang/test/Driver/sycl-offload-jit.cpp
new file mode 100644
index 00000000000000..7f2fd76b673132
--- /dev/null
+++ b/clang/test/Driver/sycl-offload-jit.cpp
@@ -0,0 +1,77 @@
+///
+/// Perform several driver tests for SYCL offloading for JIT
+///
+
+/// Check the phases graph with -fsycl. Use of -fsycl enables offload
+// RUN: %clang -ccc-print-phases --target=x86_64-unknown-linux-gnu \
+// RUN: -fsycl %s 2>&1 \
+// RUN: | FileCheck -check-prefixes=CHK-PHASES %s
+// RUN: %clang -ccc-print-phases --target=x86_64-unknown-linux-gnu -fsycl \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefixes=CHK-PHASES %s
+// RUN: %clang_cl -ccc-print-phases --target=x86_64-pc-windows-msvc -fsycl \
+// RUN: %s 2>&1 \
+// RUN: | FileCheck -check-prefixes=CHK-PHASES %s
+// CHK-PHASES: 0: input, "[[INPUT:.+\.cpp]]", c++, (host-sycl)
+// CHK-PHASES: 1: preprocessor, {0}, c++-cpp-output, (host-sycl)
+// CHK-PHASES: 2: compiler, {1}, ir, (host-sycl)
+// CHK-PHASES: 3: input, "[[INPUT]]", c++, (device-sycl)
+// CHK-PHASES: 4: preprocessor, {3}, c++-cpp-output, (device-sycl)
+// CHK-PHASES: 5: compiler, {4}, ir, (device-sycl)
+// CHK-PHASES: 6: backend, {5}, ir, (device-sycl)
+// CHK-PHASES: 7: offload, "device-sycl (spir64-unknown-unknown)" {6}, ir
+// CHK-PHASES: 8: clang-offload-packager, {7}, image, (device-sycl)
+// CHK-PHASES: 9: offload, "host-sycl (x86_64{{.*}})" {2}, "device-sycl (x86_64{{.*}})" {8}, ir
+// CHK-PHASES: 10: backend, {9}, assembler, (host-sycl)
+// CHK-PHASES: 11: assembler, {10}, object, (host-sycl)
+// CHK-PHASES: 12: clang-linker-wrapper, {11}, image, (host-sycl)
+
+/// Check expected default values for device compilation when using -fsycl as
+/// well as clang-offload-packager inputs.
+// RUN: %clang -### -fsycl -c --target=x86_64-unknown-linux-gnu %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-DEVICE-TRIPLE %s
+// CHK-DEVICE-TRIPLE: clang{{.*}} "-triple" "spir64-unknown-unknown"
+// CHK-DEVICE-TRIPLE-SAME: "-aux-triple" "x86_64-unknown-linux-gnu"
+// CHK-DEVICE-TRIPLE-SAME: "-fsycl-is-device"
+// CHK-DEVICE-TRIPLE-SAME: "-O2"
+// CHK-DEVICE-TRIPLE: clang-offload-packager{{.*}} "--image=file={{.*}}.bc,triple=spir64-unknown-unknown,arch=,kind=sycl"
+
+/// Check -fsycl-is-device is passed when compiling for the device.
+/// Check -fsycl-is-host is passed when compiling for host.
+// RUN: %clang -### -fsycl -c %s 2>&1 \
+// RUN: | FileCheck -check-prefixes=CHK-FSYCL-IS-DEVICE,CHK-FSYCL-IS-HOST %s
+// RUN: %clang -### -fsycl -fsycl-device-only %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-FSYCL-IS-DEVICE %s
+// RUN: %clang_cl -### -fsycl -c %s 2>&1 \
+// RUN: | FileCheck -check-prefixes=CHK-FSYCL-IS-DEVICE,CHK-FSYCL-IS-HOST %s
+// RUN: %clang -### -fsycl -fsycl-host-only %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-FSYCL-IS-HOST %s
+// CHK-FSYCL-IS-DEVICE: clang{{.*}} "-fsycl-is-device" {{.*}} "-emit-llvm-bc"
+// CHK-FSYCL-IS-HOST: clang{{.*}} "-fsycl-is-host"
+
+// Verify header search dirs are added with -fsycl
+// RUN: %clang -### -fsycl %s 2>&1 \
+// RUN: | FileCheck %s -check-prefixes=CHECK-HEADER-DIR
+// RUN: %clang_cl -### -fsycl %s 2>&1 \
+// RUN: | FileCheck %s -check-prefixes=CHECK-HEADER-DIR
+// CHECK-HEADER-DIR: clang{{.*}} "-fsycl-is-device"
+// CHECK-HEADER-DIR-SAME: "-internal-isystem" "[[ROOT:[^"]*]]bin{{[/\\]+}}..{{[/\\]+}}include{{[/\\]+}}sycl"
+// CHECK-HEADER-DIR-NOT: -internal-isystem
+// CHECK-HEADER-DIR-SAME: "-internal-isystem" "[[ROOT]]bin{{[/\\]+}}..{{[/\\]+}}include{{[/\\]+}}sycl{{[/\\]+}}stl_wrappers"
+// CHECK-HEADER-DIR-NOT: -internal-isystem
+// CHECK-HEADER-DIR-SAME: "-internal-isystem" "[[ROOT]]bin{{[/\\]+}}..{{[/\\]+}}include"
+// CHECK-HEADER-DIR: clang{{.*}} "-fsycl-is-host"
+// CHECK-HEADER-DIR-SAME: "-internal-isystem" "[[ROOT]]bin{{[/\\]+}}..{{[/\\]+}}include{{[/\\]+}}sycl"
+// CHECK-HEADER-DIR-NOT: -internal-isystem
+// CHECK-HEADER-DIR-SAME: "-internal-isystem" "[[ROOT]]bin{{[/\\]+}}..{{[/\\]+}}include{{[/\\]+}}sycl{{[/\\]+}}stl_wrappers"
+// CHECK-HEADER-DIR-NOT: -internal-isystem
+// CHECK-HEADER-DIR-SAME: "-internal-isystem" "[[ROOT]]bin{{[/\\]+}}..{{[/\\]+}}include"
+
+/// Check for option incompatibility with -fsycl
+// RUN: not %clang -### -fsycl -ffreestanding %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-INCOMPATIBILITY %s \
+// RUN: -DINCOMPATOPT=-ffreestanding
+// RUN: not %clang -### -fsycl --offload-new-driver -static-libstdc++ %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHK-INCOMPATIBILITY %s \
+// RUN: -DINCOMPATOPT=-static-libstdc++
+// CHK-INCOMPATIBILITY: error: invalid argument '[[INCOMPATOPT]]' not allowed with '-fsycl'
diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
index e504128714c556..5564a041d2b59e 100644
--- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -831,6 +831,13 @@ class Triple {
getArch() == Triple::spirv;
}
+ // Tests whether the target is SPIR-V or SPIR. Currently, we use spir-based
+ // target triples to represent JIT compilation targets for SYCL. We will
+ // transition to using spir-v based target triples to represent JIT
+ // compilation targets for SYCL very soon. This helper function is used
+ // (instead of isSPIR) to ease that transition.
+ bool isSPIROrSPIRV() const { return isSPIR() || isSPIRV(); }
+
/// Tests whether the target is SPIR-V Logical
bool isSPIRVLogical() const {
return getArch() == Triple::spirv;
>From 47cc84678be04c81da6e8bd3a7b00cd1f7291c8a Mon Sep 17 00:00:00 2001
From: Michael D Toguchi <michael.d.toguchi at intel.com>
Date: Mon, 23 Sep 2024 13:40:06 -0700
Subject: [PATCH 2/9] Adjust toolchain files to address a few review comments
- Improve commenting for unsupported sanitizer options
- Update visibility of the HostTC, SYCLInstallation and debug info
- cleanup un-needed header file inclusions
---
clang/lib/Driver/ToolChains/SYCL.cpp | 44 ++++++++++------------------
clang/lib/Driver/ToolChains/SYCL.h | 6 ++--
2 files changed, 17 insertions(+), 33 deletions(-)
diff --git a/clang/lib/Driver/ToolChains/SYCL.cpp b/clang/lib/Driver/ToolChains/SYCL.cpp
index a82cc8f775707e..25f02198b9c28c 100644
--- a/clang/lib/Driver/ToolChains/SYCL.cpp
+++ b/clang/lib/Driver/ToolChains/SYCL.cpp
@@ -7,18 +7,7 @@
//===----------------------------------------------------------------------===//
#include "SYCL.h"
#include "CommonArgs.h"
-#include "clang/Driver/Action.h"
-#include "clang/Driver/Compilation.h"
-#include "clang/Driver/Driver.h"
-#include "clang/Driver/DriverDiagnostic.h"
-#include "clang/Driver/InputInfo.h"
-#include "clang/Driver/Options.h"
-#include "llvm/Option/Option.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
-#include <algorithm>
-#include <sstream>
using namespace clang::driver;
using namespace clang::driver::toolchains;
@@ -64,32 +53,29 @@ void SYCLInstallationDetector::print(llvm::raw_ostream &OS) const {
}
}
-// Unsupported options for SYCL device compilation
-// -fcf-protection, -fsanitize, -fprofile-generate, -fprofile-instr-generate
-// -ftest-coverage, -fcoverage-mapping, -fcreate-profile, -fprofile-arcs
-// -fcs-profile-generate -forder-file-instrumentation, --coverage
-static std::vector<OptSpecifier> getUnsupportedOpts(void) {
+// Unsupported options for SYCL device compilation.
+static std::vector<OptSpecifier> getUnsupportedOpts() {
std::vector<OptSpecifier> UnsupportedOpts = {
- options::OPT_fsanitize_EQ,
- options::OPT_fcf_protection_EQ,
+ options::OPT_fsanitize_EQ, // -fsanitize
+ options::OPT_fcf_protection_EQ, // -fcf-protection
options::OPT_fprofile_generate,
options::OPT_fprofile_generate_EQ,
- options::OPT_fno_profile_generate,
+ options::OPT_fno_profile_generate, // -f[no-]profile-generate
options::OPT_ftest_coverage,
- options::OPT_fno_test_coverage,
+ options::OPT_fno_test_coverage, // -f[no-]test-coverage
options::OPT_fcoverage_mapping,
- options::OPT_fno_coverage_mapping,
- options::OPT_coverage,
+ options::OPT_fno_coverage_mapping, // -f[no-]coverage-mapping
+ options::OPT_coverage, // --coverage
options::OPT_fprofile_instr_generate,
options::OPT_fprofile_instr_generate_EQ,
+ options::OPT_fno_profile_instr_generate, // -f[no-]profile-instr-generate
options::OPT_fprofile_arcs,
- options::OPT_fno_profile_arcs,
- options::OPT_fno_profile_instr_generate,
- options::OPT_fcreate_profile,
+ options::OPT_fno_profile_arcs, // -f[no-]profile-arcs
+ options::OPT_fcreate_profile, // -fcreate-profile
options::OPT_fprofile_instr_use,
- options::OPT_fprofile_instr_use_EQ,
- options::OPT_forder_file_instrumentation,
- options::OPT_fcs_profile_generate,
+ options::OPT_fprofile_instr_use_EQ, // -fprofile-instr-use
+ options::OPT_forder_file_instrumentation, // -forder-file-instrumentation
+ options::OPT_fcs_profile_generate, // -fcs-profile-generate
options::OPT_fcs_profile_generate_EQ};
return UnsupportedOpts;
}
@@ -105,7 +91,7 @@ SYCLToolChain::SYCLToolChain(const Driver &D, const llvm::Triple &Triple,
for (OptSpecifier Opt : getUnsupportedOpts()) {
if (const Arg *A = Args.getLastArg(Opt)) {
// All sanitizer options are not currently supported, except
- // AddressSanitizer
+ // AddressSanitizer.
if (A->getOption().getID() == options::OPT_fsanitize_EQ &&
A->getValues().size() == 1) {
std::string SanitizeVal = A->getValue();
diff --git a/clang/lib/Driver/ToolChains/SYCL.h b/clang/lib/Driver/ToolChains/SYCL.h
index 80dd5b204d53f3..8ac1b7a9cea141 100644
--- a/clang/lib/Driver/ToolChains/SYCL.h
+++ b/clang/lib/Driver/ToolChains/SYCL.h
@@ -48,9 +48,7 @@ class LLVM_LIBRARY_VISIBILITY SYCLToolChain : public ToolChain {
bool useIntegratedAs() const override { return true; }
bool isPICDefault() const override { return false; }
llvm::codegenoptions::DebugInfoFormat getDefaultDebugFormat() const override {
- if (this->HostTC.getTriple().isWindowsMSVCEnvironment())
- return this->HostTC.getDefaultDebugFormat();
- return ToolChain::getDefaultDebugFormat();
+ return this->HostTC.getDefaultDebugFormat();
}
bool isPIEDefault(const llvm::opt::ArgList &Args) const override {
return false;
@@ -69,8 +67,8 @@ class LLVM_LIBRARY_VISIBILITY SYCLToolChain : public ToolChain {
SanitizerMask getSupportedSanitizers() const override;
+private:
const ToolChain &HostTC;
-
SYCLInstallationDetector SYCLInstallation;
};
>From 8c29ad5e70ec106b22f8a61936d15ee4cdf2ddac Mon Sep 17 00:00:00 2001
From: Michael D Toguchi <michael.d.toguchi at intel.com>
Date: Mon, 23 Sep 2024 15:52:41 -0700
Subject: [PATCH 3/9] Address a few review comments
- Use spirv32/spirv64 as default triple arch
- clean up a number of comments
- Fix file ordering inclusion to be alphabetical
---
clang/lib/Driver/CMakeLists.txt | 2 +-
clang/lib/Driver/Driver.cpp | 8 +++-----
clang/test/Driver/sycl-offload-jit.cpp | 9 +++------
llvm/include/llvm/TargetParser/Triple.h | 6 +-----
4 files changed, 8 insertions(+), 17 deletions(-)
diff --git a/clang/lib/Driver/CMakeLists.txt b/clang/lib/Driver/CMakeLists.txt
index 4cc5f730424cd5..e0527c9d91c9a5 100644
--- a/clang/lib/Driver/CMakeLists.txt
+++ b/clang/lib/Driver/CMakeLists.txt
@@ -77,6 +77,7 @@ add_clang_library(clangDriver
ToolChains/RISCVToolchain.cpp
ToolChains/Solaris.cpp
ToolChains/SPIRV.cpp
+ ToolChains/SYCL.cpp
ToolChains/TCE.cpp
ToolChains/VEToolchain.cpp
ToolChains/WebAssembly.cpp
@@ -85,7 +86,6 @@ add_clang_library(clangDriver
ToolChains/PPCFreeBSD.cpp
ToolChains/InterfaceStubs.cpp
ToolChains/ZOS.cpp
- ToolChains/SYCL.cpp
Types.cpp
XRayArgs.cpp
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index b8d7401f6e01cc..1975f54c291f4d 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -769,9 +769,10 @@ Driver::OpenMPRuntimeKind Driver::getOpenMPRuntime(const ArgList &Args) const {
}
static const char *getDefaultSYCLArch(Compilation &C) {
+ // If -fsycl is supplied we will assume SPIR-V
if (C.getDefaultToolChain().getTriple().getArch() == llvm::Triple::x86)
- return "spir";
- return "spir64";
+ return "spirv32";
+ return "spirv64";
}
static bool addSYCLDefaultTriple(Compilation &C,
@@ -1004,7 +1005,6 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
// SYCL
//
// We need to generate a SYCL toolchain if the user specified -fsycl.
- // If -fsycl is supplied we will assume SPIR-V.
bool IsSYCL =
C.getInputArgs().hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
false);
@@ -1023,7 +1023,6 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
llvm::SmallVector<llvm::Triple, 4> UniqueSYCLTriplesVec;
- // If -fsycl is supplied we will assume SPIR-V.
if (IsSYCL) {
addSYCLDefaultTriple(C, UniqueSYCLTriplesVec);
@@ -6635,7 +6634,6 @@ const ToolChain &Driver::getOffloadingDeviceToolChain(
break;
}
case Action::OFK_SYCL:
- // TODO: Add additional Arch values for Ahead of Time support for SYCL.
switch (Target.getArch()) {
case llvm::Triple::spir:
case llvm::Triple::spir64:
diff --git a/clang/test/Driver/sycl-offload-jit.cpp b/clang/test/Driver/sycl-offload-jit.cpp
index 7f2fd76b673132..070bf967483975 100644
--- a/clang/test/Driver/sycl-offload-jit.cpp
+++ b/clang/test/Driver/sycl-offload-jit.cpp
@@ -6,9 +6,6 @@
// RUN: %clang -ccc-print-phases --target=x86_64-unknown-linux-gnu \
// RUN: -fsycl %s 2>&1 \
// RUN: | FileCheck -check-prefixes=CHK-PHASES %s
-// RUN: %clang -ccc-print-phases --target=x86_64-unknown-linux-gnu -fsycl \
-// RUN: %s 2>&1 \
-// RUN: | FileCheck -check-prefixes=CHK-PHASES %s
// RUN: %clang_cl -ccc-print-phases --target=x86_64-pc-windows-msvc -fsycl \
// RUN: %s 2>&1 \
// RUN: | FileCheck -check-prefixes=CHK-PHASES %s
@@ -19,7 +16,7 @@
// CHK-PHASES: 4: preprocessor, {3}, c++-cpp-output, (device-sycl)
// CHK-PHASES: 5: compiler, {4}, ir, (device-sycl)
// CHK-PHASES: 6: backend, {5}, ir, (device-sycl)
-// CHK-PHASES: 7: offload, "device-sycl (spir64-unknown-unknown)" {6}, ir
+// CHK-PHASES: 7: offload, "device-sycl (spirv64-unknown-unknown)" {6}, ir
// CHK-PHASES: 8: clang-offload-packager, {7}, image, (device-sycl)
// CHK-PHASES: 9: offload, "host-sycl (x86_64{{.*}})" {2}, "device-sycl (x86_64{{.*}})" {8}, ir
// CHK-PHASES: 10: backend, {9}, assembler, (host-sycl)
@@ -30,11 +27,11 @@
/// well as clang-offload-packager inputs.
// RUN: %clang -### -fsycl -c --target=x86_64-unknown-linux-gnu %s 2>&1 \
// RUN: | FileCheck -check-prefix=CHK-DEVICE-TRIPLE %s
-// CHK-DEVICE-TRIPLE: clang{{.*}} "-triple" "spir64-unknown-unknown"
+// CHK-DEVICE-TRIPLE: clang{{.*}} "-triple" "spirv64-unknown-unknown"
// CHK-DEVICE-TRIPLE-SAME: "-aux-triple" "x86_64-unknown-linux-gnu"
// CHK-DEVICE-TRIPLE-SAME: "-fsycl-is-device"
// CHK-DEVICE-TRIPLE-SAME: "-O2"
-// CHK-DEVICE-TRIPLE: clang-offload-packager{{.*}} "--image=file={{.*}}.bc,triple=spir64-unknown-unknown,arch=,kind=sycl"
+// CHK-DEVICE-TRIPLE: clang-offload-packager{{.*}} "--image=file={{.*}}.bc,triple=spirv64-unknown-unknown,arch=,kind=sycl"
/// Check -fsycl-is-device is passed when compiling for the device.
/// Check -fsycl-is-host is passed when compiling for host.
diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
index 5564a041d2b59e..533a5d59984bbf 100644
--- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -831,11 +831,7 @@ class Triple {
getArch() == Triple::spirv;
}
- // Tests whether the target is SPIR-V or SPIR. Currently, we use spir-based
- // target triples to represent JIT compilation targets for SYCL. We will
- // transition to using spir-v based target triples to represent JIT
- // compilation targets for SYCL very soon. This helper function is used
- // (instead of isSPIR) to ease that transition.
+ // Tests whether the target is SPIR-V or SPIR.
bool isSPIROrSPIRV() const { return isSPIR() || isSPIRV(); }
/// Tests whether the target is SPIR-V Logical
>From 7884962bfb9e286c31479181bd3a9ec4f87ec254 Mon Sep 17 00:00:00 2001
From: Michael D Toguchi <michael.d.toguchi at intel.com>
Date: Mon, 23 Sep 2024 16:17:40 -0700
Subject: [PATCH 4/9] Adjust logic for adding options to the -cc1 step
---
clang/lib/Driver/ToolChains/Clang.cpp | 45 +++++++++++++--------------
1 file changed, 22 insertions(+), 23 deletions(-)
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index c8398113313bc4..e7bed0ad853adf 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -5125,37 +5125,36 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Arg *SYCLStdArg = Args.getLastArg(options::OPT_sycl_std_EQ);
- if (IsSYCLDevice) {
- // Host triple is needed when doing SYCL device compilations.
- llvm::Triple AuxT = C.getDefaultToolChain().getTriple();
- std::string NormalizedTriple = AuxT.normalize();
- CmdArgs.push_back("-aux-triple");
- CmdArgs.push_back(Args.MakeArgString(NormalizedTriple));
-
- // We want to compile sycl kernels.
- CmdArgs.push_back("-fsycl-is-device");
+ if (IsSYCL) {
+ if (IsSYCLDevice) {
+ // Host triple is needed when doing SYCL device compilations.
+ llvm::Triple AuxT = C.getDefaultToolChain().getTriple();
+ std::string NormalizedTriple = AuxT.normalize();
+ CmdArgs.push_back("-aux-triple");
+ CmdArgs.push_back(Args.MakeArgString(NormalizedTriple));
+
+ // We want to compile sycl kernels.
+ CmdArgs.push_back("-fsycl-is-device");
+
+ // Set O2 optimization level by default
+ if (!Args.getLastArg(options::OPT_O_Group))
+ CmdArgs.push_back("-O2");
+ } else {
+ // Add any options that are needed specific to SYCL offload while
+ // performing the host side compilation.
- // Set O2 optimization level by default
- if (!Args.getLastArg(options::OPT_O_Group))
- CmdArgs.push_back("-O2");
- }
+ // Let the front-end host compilation flow know about SYCL offload
+ // compilation.
+ CmdArgs.push_back("-fsycl-is-host");
+ }
- if (IsSYCL) {
- // Set options for both host and device
+ // Set options for both host and device.
if (SYCLStdArg) {
SYCLStdArg->render(Args, CmdArgs);
} else {
// Ensure the default version in SYCL mode is 2020.
CmdArgs.push_back("-sycl-std=2020");
}
-
- // Add any options that are needed specific to SYCL offload while
- // performing the host side compilation.
- if (!IsSYCLDevice) {
- // Let the front-end host compilation flow know about SYCL offload
- // compilation.
- CmdArgs.push_back("-fsycl-is-host");
- }
}
if (IsOpenMPDevice) {
>From 5e204cd3c1c65e2e3e21fca6f8394be8db11bb51 Mon Sep 17 00:00:00 2001
From: Michael D Toguchi <michael.d.toguchi at intel.com>
Date: Fri, 25 Oct 2024 08:28:01 -0700
Subject: [PATCH 5/9] Address a few review items
- update a number of comments to include SYCL
- update function names to better fit standards
- use generic check for 32-bit
---
clang/include/clang/Driver/Driver.h | 4 ++--
clang/include/clang/Driver/ToolChain.h | 2 +-
clang/lib/Driver/Compilation.cpp | 2 +-
clang/lib/Driver/Driver.cpp | 6 +++---
clang/lib/Driver/ToolChains/Clang.cpp | 6 +++---
5 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h
index ddadefaa079dd5..3fee9dd4318a92 100644
--- a/clang/include/clang/Driver/Driver.h
+++ b/clang/include/clang/Driver/Driver.h
@@ -582,9 +582,9 @@ class Driver {
/// @name Helper Methods
/// @{
- /// MakeSYCLDeviceTriple - Returns the SYCL device triple for the
+ /// getSYCLDeviceTriple - Returns the SYCL device triple for the
/// specified ArchType.
- llvm::Triple MakeSYCLDeviceTriple(StringRef TargetArch = "spir64") const;
+ llvm::Triple getSYCLDeviceTriple(StringRef TargetArch = "spir64") const;
/// PrintActions - Print the list of actions.
void PrintActions(const Compilation &C) const;
diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h
index 0bc2a28bceb923..4efef49346fa4d 100644
--- a/clang/include/clang/Driver/ToolChain.h
+++ b/clang/include/clang/Driver/ToolChain.h
@@ -762,7 +762,7 @@ class ToolChain {
virtual void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const;
- /// Add arguments to use SYCL specific includes.
+ /// Add arguments to use system-specific SYCL includes.
virtual void AddSYCLIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const;
diff --git a/clang/lib/Driver/Compilation.cpp b/clang/lib/Driver/Compilation.cpp
index 283487548f4cf2..57315493f16e13 100644
--- a/clang/lib/Driver/Compilation.cpp
+++ b/clang/lib/Driver/Compilation.cpp
@@ -219,7 +219,7 @@ static bool ActionFailed(const Action *A,
// CUDA/HIP/SYCL can have the same input source code compiled multiple times
// so do not compile again if there are already failures. It is OK to abort
- // the CUDA pipeline on errors.
+ // the CUDA/HIP/SYCL pipeline on errors.
if (A->isOffloading(Action::OFK_Cuda) || A->isOffloading(Action::OFK_HIP) ||
A->isOffloading(Action::OFK_SYCL))
return true;
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 1975f54c291f4d..d3eefae4353b06 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -770,7 +770,7 @@ Driver::OpenMPRuntimeKind Driver::getOpenMPRuntime(const ArgList &Args) const {
static const char *getDefaultSYCLArch(Compilation &C) {
// If -fsycl is supplied we will assume SPIR-V
- if (C.getDefaultToolChain().getTriple().getArch() == llvm::Triple::x86)
+ if (C.getDefaultToolChain().getTriple().isArch32Bit())
return "spirv32";
return "spirv64";
}
@@ -784,7 +784,7 @@ static bool addSYCLDefaultTriple(Compilation &C,
}
// Add the default triple as it was not found.
llvm::Triple DefaultTriple =
- C.getDriver().MakeSYCLDeviceTriple(getDefaultSYCLArch(C));
+ C.getDriver().getSYCLDeviceTriple(getDefaultSYCLArch(C));
SYCLTriples.insert(SYCLTriples.begin(), DefaultTriple);
return true;
}
@@ -2059,7 +2059,7 @@ void Driver::PrintHelp(bool ShowHidden) const {
VisibilityMask);
}
-llvm::Triple Driver::MakeSYCLDeviceTriple(StringRef TargetArch) const {
+llvm::Triple Driver::getSYCLDeviceTriple(StringRef TargetArch) const {
SmallVector<StringRef, 5> SYCLAlias = { "spir", "spir64", "spirv32", "spirv64"};
if (std::find(SYCLAlias.begin(), SYCLAlias.end(), TargetArch) !=
SYCLAlias.end()) {
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index e7bed0ad853adf..8886939538853e 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -1066,10 +1066,10 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_MP);
Args.AddLastArg(CmdArgs, options::OPT_MV);
- // Add offload include arguments specific for CUDA/HIP. This must happen
+ // Add offload include arguments specific for CUDA/HIP/SYCL. This must happen
// before we -I or -include anything else, because we must pick up the
- // CUDA/HIP headers from the particular CUDA/ROCm installation, rather than
- // from e.g. /usr/local/include.
+ // CUDA/HIP/SYCL headers from the particular CUDA/ROCm/SYCL installation,
+ // rather than from e.g. /usr/local/include.
if (JA.isOffloading(Action::OFK_Cuda))
getToolChain().AddCudaIncludeArgs(Args, CmdArgs);
if (JA.isOffloading(Action::OFK_HIP))
>From db45e5c36a9d4ff997f551325fd52eb4070a6b56 Mon Sep 17 00:00:00 2001
From: Michael D Toguchi <michael.d.toguchi at intel.com>
Date: Fri, 25 Oct 2024 15:17:17 -0700
Subject: [PATCH 6/9] Update header inclusion and related test
---
clang/lib/Driver/ToolChains/SYCL.cpp | 8 ++------
clang/test/Driver/sycl-offload-jit.cpp | 6 +-----
2 files changed, 3 insertions(+), 11 deletions(-)
diff --git a/clang/lib/Driver/ToolChains/SYCL.cpp b/clang/lib/Driver/ToolChains/SYCL.cpp
index 25f02198b9c28c..af795197f26dc8 100644
--- a/clang/lib/Driver/ToolChains/SYCL.cpp
+++ b/clang/lib/Driver/ToolChains/SYCL.cpp
@@ -23,22 +23,18 @@ SYCLInstallationDetector::SYCLInstallationDetector(const Driver &D)
void SYCLInstallationDetector::AddSYCLIncludeArgs(
const ArgList &DriverArgs, ArgStringList &CC1Args) const {
// Add the SYCL header search locations in the specified order.
- // ../include/sycl
// ../include/sycl/stl_wrappers
// ../include
SmallString<128> IncludePath(D.Dir);
llvm::sys::path::append(IncludePath, "..");
llvm::sys::path::append(IncludePath, "include");
- SmallString<128> SYCLPath(IncludePath);
- llvm::sys::path::append(SYCLPath, "sycl");
// This is used to provide our wrappers around STL headers that provide
// additional functions/template specializations when the user includes those
// STL headers in their programs (e.g., <complex>).
- SmallString<128> STLWrappersPath(SYCLPath);
+ SmallString<128> STLWrappersPath(IncludePath);
+ llvm::sys::path::append(STLWrappersPath, "sycl");
llvm::sys::path::append(STLWrappersPath, "stl_wrappers");
CC1Args.push_back("-internal-isystem");
- CC1Args.push_back(DriverArgs.MakeArgString(SYCLPath));
- CC1Args.push_back("-internal-isystem");
CC1Args.push_back(DriverArgs.MakeArgString(STLWrappersPath));
CC1Args.push_back("-internal-isystem");
CC1Args.push_back(DriverArgs.MakeArgString(IncludePath));
diff --git a/clang/test/Driver/sycl-offload-jit.cpp b/clang/test/Driver/sycl-offload-jit.cpp
index 070bf967483975..08cac727d8a197 100644
--- a/clang/test/Driver/sycl-offload-jit.cpp
+++ b/clang/test/Driver/sycl-offload-jit.cpp
@@ -52,14 +52,10 @@
// RUN: %clang_cl -### -fsycl %s 2>&1 \
// RUN: | FileCheck %s -check-prefixes=CHECK-HEADER-DIR
// CHECK-HEADER-DIR: clang{{.*}} "-fsycl-is-device"
-// CHECK-HEADER-DIR-SAME: "-internal-isystem" "[[ROOT:[^"]*]]bin{{[/\\]+}}..{{[/\\]+}}include{{[/\\]+}}sycl"
-// CHECK-HEADER-DIR-NOT: -internal-isystem
-// CHECK-HEADER-DIR-SAME: "-internal-isystem" "[[ROOT]]bin{{[/\\]+}}..{{[/\\]+}}include{{[/\\]+}}sycl{{[/\\]+}}stl_wrappers"
+// CHECK-HEADER-DIR-SAME: "-internal-isystem" "[[ROOT:[^"]*]]bin{{[/\\]+}}..{{[/\\]+}}include{{[/\\]+}}sycl{{[/\\]+}}stl_wrappers"
// CHECK-HEADER-DIR-NOT: -internal-isystem
// CHECK-HEADER-DIR-SAME: "-internal-isystem" "[[ROOT]]bin{{[/\\]+}}..{{[/\\]+}}include"
// CHECK-HEADER-DIR: clang{{.*}} "-fsycl-is-host"
-// CHECK-HEADER-DIR-SAME: "-internal-isystem" "[[ROOT]]bin{{[/\\]+}}..{{[/\\]+}}include{{[/\\]+}}sycl"
-// CHECK-HEADER-DIR-NOT: -internal-isystem
// CHECK-HEADER-DIR-SAME: "-internal-isystem" "[[ROOT]]bin{{[/\\]+}}..{{[/\\]+}}include{{[/\\]+}}sycl{{[/\\]+}}stl_wrappers"
// CHECK-HEADER-DIR-NOT: -internal-isystem
// CHECK-HEADER-DIR-SAME: "-internal-isystem" "[[ROOT]]bin{{[/\\]+}}..{{[/\\]+}}include"
>From f57670e76b5d740787574f8767b5973ac2693e09 Mon Sep 17 00:00:00 2001
From: Michael D Toguchi <michael.d.toguchi at intel.com>
Date: Fri, 25 Oct 2024 15:24:13 -0700
Subject: [PATCH 7/9] Clean up superfluous parens
---
clang/lib/Driver/Driver.cpp | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index d3eefae4353b06..fcc86637c9e69f 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -4946,13 +4946,13 @@ Action *Driver::ConstructPhaseAction(
return C.MakeAction<BackendJobAction>(Input, Output);
}
if (Args.hasArg(options::OPT_emit_llvm) ||
- (TargetDeviceOffloadKind == Action::OFK_SYCL ||
- (((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 ||
+ (((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 ||
>From 05c7584ad0bebb1286c4c364c804e1743b899461 Mon Sep 17 00:00:00 2001
From: Michael D Toguchi <michael.d.toguchi at intel.com>
Date: Fri, 1 Nov 2024 08:20:08 -0700
Subject: [PATCH 8/9] remove unneeded init code
---
clang/lib/Driver/ToolChains/SYCL.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/Driver/ToolChains/SYCL.cpp b/clang/lib/Driver/ToolChains/SYCL.cpp
index af795197f26dc8..0c4dab7c818eba 100644
--- a/clang/lib/Driver/ToolChains/SYCL.cpp
+++ b/clang/lib/Driver/ToolChains/SYCL.cpp
@@ -16,7 +16,7 @@ using namespace clang;
using namespace llvm::opt;
SYCLInstallationDetector::SYCLInstallationDetector(const Driver &D)
- : D(D), InstallationCandidates() {
+ : D(D) {
InstallationCandidates.emplace_back(D.Dir + "/..");
}
>From 8a0826adbc8b2c6a39961432c09a2d7ef465df67 Mon Sep 17 00:00:00 2001
From: Michael D Toguchi <michael.d.toguchi at intel.com>
Date: Mon, 4 Nov 2024 08:48:41 -0800
Subject: [PATCH 9/9] address clang-format findings
---
clang/lib/Driver/Driver.cpp | 8 ++++----
clang/lib/Driver/ToolChains/SYCL.cpp | 13 ++++++-------
clang/lib/Driver/ToolChains/SYCL.h | 10 ++++++----
3 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 938bf64fb19147..91971511714117 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -1023,9 +1023,8 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
// SYCL
//
// We need to generate a SYCL toolchain if the user specified -fsycl.
- bool IsSYCL =
- C.getInputArgs().hasFlag(options::OPT_fsycl, options::OPT_fno_sycl,
- false);
+ bool IsSYCL = C.getInputArgs().hasFlag(options::OPT_fsycl,
+ options::OPT_fno_sycl, false);
auto argSYCLIncompatible = [&](OptSpecifier OptId) {
if (!IsSYCL)
@@ -2089,7 +2088,8 @@ void Driver::PrintHelp(bool ShowHidden) const {
}
llvm::Triple Driver::getSYCLDeviceTriple(StringRef TargetArch) const {
- SmallVector<StringRef, 5> SYCLAlias = { "spir", "spir64", "spirv32", "spirv64"};
+ SmallVector<StringRef, 5> SYCLAlias = {"spir", "spir64", "spirv32",
+ "spirv64"};
if (std::find(SYCLAlias.begin(), SYCLAlias.end(), TargetArch) !=
SYCLAlias.end()) {
llvm::Triple TT;
diff --git a/clang/lib/Driver/ToolChains/SYCL.cpp b/clang/lib/Driver/ToolChains/SYCL.cpp
index 0c4dab7c818eba..241444b71384b5 100644
--- a/clang/lib/Driver/ToolChains/SYCL.cpp
+++ b/clang/lib/Driver/ToolChains/SYCL.cpp
@@ -15,8 +15,7 @@ using namespace clang::driver::tools;
using namespace clang;
using namespace llvm::opt;
-SYCLInstallationDetector::SYCLInstallationDetector(const Driver &D)
- : D(D) {
+SYCLInstallationDetector::SYCLInstallationDetector(const Driver &D) : D(D) {
InstallationCandidates.emplace_back(D.Dir + "/..");
}
@@ -52,7 +51,7 @@ void SYCLInstallationDetector::print(llvm::raw_ostream &OS) const {
// Unsupported options for SYCL device compilation.
static std::vector<OptSpecifier> getUnsupportedOpts() {
std::vector<OptSpecifier> UnsupportedOpts = {
- options::OPT_fsanitize_EQ, // -fsanitize
+ options::OPT_fsanitize_EQ, // -fsanitize
options::OPT_fcf_protection_EQ, // -fcf-protection
options::OPT_fprofile_generate,
options::OPT_fprofile_generate_EQ,
@@ -61,17 +60,17 @@ static std::vector<OptSpecifier> getUnsupportedOpts() {
options::OPT_fno_test_coverage, // -f[no-]test-coverage
options::OPT_fcoverage_mapping,
options::OPT_fno_coverage_mapping, // -f[no-]coverage-mapping
- options::OPT_coverage, // --coverage
+ options::OPT_coverage, // --coverage
options::OPT_fprofile_instr_generate,
options::OPT_fprofile_instr_generate_EQ,
options::OPT_fno_profile_instr_generate, // -f[no-]profile-instr-generate
options::OPT_fprofile_arcs,
options::OPT_fno_profile_arcs, // -f[no-]profile-arcs
- options::OPT_fcreate_profile, // -fcreate-profile
+ options::OPT_fcreate_profile, // -fcreate-profile
options::OPT_fprofile_instr_use,
- options::OPT_fprofile_instr_use_EQ, // -fprofile-instr-use
+ options::OPT_fprofile_instr_use_EQ, // -fprofile-instr-use
options::OPT_forder_file_instrumentation, // -forder-file-instrumentation
- options::OPT_fcs_profile_generate, // -fcs-profile-generate
+ options::OPT_fcs_profile_generate, // -fcs-profile-generate
options::OPT_fcs_profile_generate_EQ};
return UnsupportedOpts;
}
diff --git a/clang/lib/Driver/ToolChains/SYCL.h b/clang/lib/Driver/ToolChains/SYCL.h
index 8ac1b7a9cea141..9395478cb044d2 100644
--- a/clang/lib/Driver/ToolChains/SYCL.h
+++ b/clang/lib/Driver/ToolChains/SYCL.h
@@ -41,9 +41,10 @@ class LLVM_LIBRARY_VISIBILITY SYCLToolChain : public ToolChain {
llvm::opt::DerivedArgList *
TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
Action::OffloadKind DeviceOffloadKind) const override;
- void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
- llvm::opt::ArgStringList &CC1Args,
- Action::OffloadKind DeviceOffloadKind) const override;
+ void
+ addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
+ llvm::opt::ArgStringList &CC1Args,
+ Action::OffloadKind DeviceOffloadKind) const override;
bool useIntegratedAs() const override { return true; }
bool isPICDefault() const override { return false; }
@@ -59,7 +60,8 @@ class LLVM_LIBRARY_VISIBILITY SYCLToolChain : public ToolChain {
CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override;
void AddSYCLIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const override;
- void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
+ void
+ AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const override;
void AddClangCXXStdlibIncludeArgs(
const llvm::opt::ArgList &Args,
More information about the cfe-commits
mailing list