Skip to content
Merged
1 change: 1 addition & 0 deletions clang/include/clang/Driver/Action.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ class Action {
OFK_Cuda = 0x02,
OFK_OpenMP = 0x04,
OFK_HIP = 0x08,
OFK_SYCL = 0x10,
};

static const char *getClassName(ActionClass AC);
Expand Down
20 changes: 13 additions & 7 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -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">,
Expand Down Expand Up @@ -6782,16 +6783,21 @@ 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<"Enable SYCL C++ extensions">;
def fno_sycl : Flag<["-"], "fno-sycl">,
Visibility<[ClangOption, CLOption]>,
Group<sycl_Group>, HelpText<"Disables SYCL kernels compilation for device">;
HelpText<"Disable SYCL C++ extensions">;
def fsycl_device_only : Flag<["-"], "fsycl-device-only">,
Alias<offload_device_only>, HelpText<"Compile SYCL code for device only">;
def fsycl_host_only : Flag<["-"], "fsycl-host-only">,
Alias<offload_host_only>, HelpText<"Compile SYCL code for host only. Has no "
"effect on non-SYCL compilations">;
def sycl_link : Flag<["--"], "sycl-link">, Flags<[HelpHidden]>,
Visibility<[ClangOption, CLOption]>,
Group<sycl_Group>, HelpText<"Perform link through clang-sycl-linker via the target "
HelpText<"Perform link through clang-sycl-linker via the target "
"offloading toolchain.">;
} // let Group = sycl_Group

// OS-specific options
let Flags = [TargetSpecific] in {
defm android_pad_segment : BooleanFFlag<"android-pad-segment">, Group<f_Group>;
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Driver/ToolChain.h
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,10 @@ class ToolChain {
virtual void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs,
llvm::opt::ArgStringList &CC1Args) const;

/// Add arguments to use system-specific SYCL 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;
Expand Down
8 changes: 7 additions & 1 deletion clang/lib/Driver/Action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
}
Expand All @@ -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.

Expand Down Expand Up @@ -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.
}
Expand Down Expand Up @@ -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);
}
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Driver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ add_clang_library(clangDriver
ToolChains/RISCVToolchain.cpp
ToolChains/Solaris.cpp
ToolChains/SPIRV.cpp
ToolChains/SYCL.cpp
ToolChains/TCE.cpp
ToolChains/UEFI.cpp
ToolChains/VEToolchain.cpp
Expand Down
9 changes: 5 additions & 4 deletions clang/lib/Driver/Compilation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,10 +214,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/HIP/SYCL 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)
Expand Down
106 changes: 103 additions & 3 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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/UEFI.h"
Expand Down Expand Up @@ -780,6 +781,41 @@ Driver::OpenMPRuntimeKind Driver::getOpenMPRuntime(const ArgList &Args) const {
return RT;
}

static const char *getDefaultSYCLArch(Compilation &C) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this trivial function and inline its use

// If -fsycl is supplied we will assume SPIR-V
if (C.getDefaultToolChain().getTriple().isArch32Bit())
return "spirv32";
return "spirv64";
}

static llvm::Triple getSYCLDeviceTriple(StringRef TargetArch) {
SmallVector<StringRef, 5> SYCLAlias = {"spir", "spir64", "spirv", "spirv32",
"spirv64"};
if (std::find(SYCLAlias.begin(), SYCLAlias.end(), TargetArch) !=
Copy link
Member

@MaskRay MaskRay Dec 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

llvm::is_contained({..., ..., ...}, TargetArch)

SYCLAlias.end()) {
llvm::Triple TargetTriple;
TargetTriple.setArchName(TargetArch);
TargetTriple.setVendor(llvm::Triple::UnknownVendor);
TargetTriple.setOS(llvm::Triple::UnknownOS);
return TargetTriple;
}
return llvm::Triple(TargetArch);
}

static bool addSYCLDefaultTriple(Compilation &C,
SmallVectorImpl<llvm::Triple> &SYCLTriples) {
// Check current set of triples to see if the default has already been set.
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 = getSYCLDeviceTriple(getDefaultSYCLArch(C));
SYCLTriples.insert(SYCLTriples.begin(), DefaultTriple);
return true;
}

void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
InputList &Inputs) {

Expand Down Expand Up @@ -841,7 +877,6 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
return;
auto *HIPTC = &getOffloadingDeviceToolChain(C.getInputArgs(), *HIPTriple,
*HostTC, OFK);
assert(HIPTC && "Could not create offloading device tool chain.");
C.addOffloadDeviceToolChain(HIPTC, OFK);
}

Expand Down Expand Up @@ -993,6 +1028,41 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
return;
}

//
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't use start a comment block with //\n. Just delete the part before We need to generate a SYCL toolchain if the user specified -fsycl.

// 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);

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 (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 &TargetTriple : UniqueSYCLTriplesVec) {
auto SYCLTC = &getOffloadingDeviceToolChain(
C.getInputArgs(), TargetTriple, *HostTC, Action::OFK_SYCL);
C.addOffloadDeviceToolChain(SYCLTC, Action::OFK_SYCL);
}
}

//
// TODO: Add support for other offloading programming models here.
//
Expand Down Expand Up @@ -4183,6 +4253,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,
Expand Down Expand Up @@ -4593,6 +4664,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);
Expand All @@ -4617,7 +4690,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;
Expand Down Expand Up @@ -4654,6 +4727,15 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
if (DeviceActions.empty())
return HostAction;

// FIXME: Do not collapse the host side for Darwin targets with SYCL offload
// compilations. The toolchain is not properly initialized for the target.
if (isa<CompileJobAction>(HostAction) && Kind == Action::OFK_SYCL &&
HostAction->getType() != types::TY_Nothing &&
C.getSingleOffloadToolChain<Action::OFK_Host>()
->getTriple()
.isOSDarwin())
HostAction->setCannotBeCollapsedWithNextDependentAction();

auto PL = types::getCompilationPhases(*this, Args, InputType);

for (phases::ID Phase : PL) {
Expand All @@ -4662,6 +4744,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)
Expand Down Expand Up @@ -4900,6 +4987,7 @@ 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) &&
Expand Down Expand Up @@ -6591,11 +6679,23 @@ const ToolChain &Driver::getOffloadingDeviceToolChain(
HostTC, Args);
break;
}
case Action::OFK_SYCL:
switch (Target.getArch()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use isSPIR and isSPIRV

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;
}
default:
break;
}
}

assert(TC && "Could not create offloading device tool chain.");
return *TC;
}

Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Driver/ToolChain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1485,6 +1485,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 {};
Expand Down
Loading
Loading