4444#include " ToolChains/RISCVToolchain.h"
4545#include " ToolChains/SPIRV.h"
4646#include " ToolChains/SPIRVOpenMP.h"
47+ #include " ToolChains/SYCL.h"
4748#include " ToolChains/Solaris.h"
4849#include " ToolChains/TCE.h"
4950#include " ToolChains/UEFI.h"
@@ -781,6 +782,35 @@ Driver::OpenMPRuntimeKind Driver::getOpenMPRuntime(const ArgList &Args) const {
781782 return RT;
782783}
783784
785+ static llvm::Triple getSYCLDeviceTriple (StringRef TargetArch) {
786+ SmallVector<StringRef, 5 > SYCLAlias = {" spir" , " spir64" , " spirv" , " spirv32" ,
787+ " spirv64" };
788+ if (llvm::is_contained (SYCLAlias, TargetArch)) {
789+ llvm::Triple TargetTriple;
790+ TargetTriple.setArchName (TargetArch);
791+ TargetTriple.setVendor (llvm::Triple::UnknownVendor);
792+ TargetTriple.setOS (llvm::Triple::UnknownOS);
793+ return TargetTriple;
794+ }
795+ return llvm::Triple (TargetArch);
796+ }
797+
798+ static bool addSYCLDefaultTriple (Compilation &C,
799+ SmallVectorImpl<llvm::Triple> &SYCLTriples) {
800+ // Check current set of triples to see if the default has already been set.
801+ for (const auto &SYCLTriple : SYCLTriples) {
802+ if (SYCLTriple.getSubArch () == llvm::Triple::NoSubArch &&
803+ SYCLTriple.isSPIROrSPIRV ())
804+ return false ;
805+ }
806+ // Add the default triple as it was not found.
807+ llvm::Triple DefaultTriple = getSYCLDeviceTriple (
808+ C.getDefaultToolChain ().getTriple ().isArch32Bit () ? " spirv32"
809+ : " spirv64" );
810+ SYCLTriples.insert (SYCLTriples.begin (), DefaultTriple);
811+ return true ;
812+ }
813+
784814void Driver::CreateOffloadingDeviceToolChains (Compilation &C,
785815 InputList &Inputs) {
786816
@@ -842,7 +872,6 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
842872 return ;
843873 auto *HIPTC = &getOffloadingDeviceToolChain (C.getInputArgs (), *HIPTriple,
844874 *HostTC, OFK);
845- assert (HIPTC && " Could not create offloading device tool chain." );
846875 C.addOffloadDeviceToolChain (HIPTC, OFK);
847876 }
848877
@@ -997,6 +1026,38 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
9971026 return ;
9981027 }
9991028
1029+ // We need to generate a SYCL toolchain if the user specified -fsycl.
1030+ bool IsSYCL = C.getInputArgs ().hasFlag (options::OPT_fsycl,
1031+ options::OPT_fno_sycl, false );
1032+
1033+ auto argSYCLIncompatible = [&](OptSpecifier OptId) {
1034+ if (!IsSYCL)
1035+ return ;
1036+ if (Arg *IncompatArg = C.getInputArgs ().getLastArg (OptId))
1037+ Diag (clang::diag::err_drv_argument_not_allowed_with)
1038+ << IncompatArg->getSpelling () << " -fsycl" ;
1039+ };
1040+ // -static-libstdc++ is not compatible with -fsycl.
1041+ argSYCLIncompatible (options::OPT_static_libstdcxx);
1042+ // -ffreestanding cannot be used with -fsycl
1043+ argSYCLIncompatible (options::OPT_ffreestanding);
1044+
1045+ llvm::SmallVector<llvm::Triple, 4 > UniqueSYCLTriplesVec;
1046+
1047+ if (IsSYCL) {
1048+ addSYCLDefaultTriple (C, UniqueSYCLTriplesVec);
1049+
1050+ // We'll need to use the SYCL and host triples as the key into
1051+ // getOffloadingDeviceToolChain, because the device toolchains we're
1052+ // going to create will depend on both.
1053+ const ToolChain *HostTC = C.getSingleOffloadToolChain <Action::OFK_Host>();
1054+ for (const auto &TargetTriple : UniqueSYCLTriplesVec) {
1055+ auto SYCLTC = &getOffloadingDeviceToolChain (
1056+ C.getInputArgs (), TargetTriple, *HostTC, Action::OFK_SYCL);
1057+ C.addOffloadDeviceToolChain (SYCLTC, Action::OFK_SYCL);
1058+ }
1059+ }
1060+
10001061 //
10011062 // TODO: Add support for other offloading programming models here.
10021063 //
@@ -4236,6 +4297,7 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
42364297
42374298 bool UseNewOffloadingDriver =
42384299 C.isOffloadingHostKind (Action::OFK_OpenMP) ||
4300+ C.isOffloadingHostKind (Action::OFK_SYCL) ||
42394301 Args.hasFlag (options::OPT_foffload_via_llvm,
42404302 options::OPT_fno_offload_via_llvm, false ) ||
42414303 Args.hasFlag (options::OPT_offload_new_driver,
@@ -4661,6 +4723,8 @@ Driver::getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args,
46614723 Archs.insert (OffloadArchToString (OffloadArch::HIPDefault));
46624724 else if (Kind == Action::OFK_OpenMP)
46634725 Archs.insert (StringRef ());
4726+ else if (Kind == Action::OFK_SYCL)
4727+ Archs.insert (StringRef ());
46644728 } else {
46654729 Args.ClaimAllArgs (options::OPT_offload_arch_EQ);
46664730 Args.ClaimAllArgs (options::OPT_no_offload_arch_EQ);
@@ -4685,7 +4749,7 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
46854749 OffloadAction::DeviceDependences DDeps;
46864750
46874751 const Action::OffloadKind OffloadKinds[] = {
4688- Action::OFK_OpenMP, Action::OFK_Cuda, Action::OFK_HIP};
4752+ Action::OFK_OpenMP, Action::OFK_Cuda, Action::OFK_HIP, Action::OFK_SYCL };
46894753
46904754 for (Action::OffloadKind Kind : OffloadKinds) {
46914755 SmallVector<const ToolChain *, 2 > ToolChains;
@@ -4722,6 +4786,15 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
47224786 if (DeviceActions.empty ())
47234787 return HostAction;
47244788
4789+ // FIXME: Do not collapse the host side for Darwin targets with SYCL offload
4790+ // compilations. The toolchain is not properly initialized for the target.
4791+ if (isa<CompileJobAction>(HostAction) && Kind == Action::OFK_SYCL &&
4792+ HostAction->getType () != types::TY_Nothing &&
4793+ C.getSingleOffloadToolChain <Action::OFK_Host>()
4794+ ->getTriple ()
4795+ .isOSDarwin ())
4796+ HostAction->setCannotBeCollapsedWithNextDependentAction ();
4797+
47254798 auto PL = types::getCompilationPhases (*this , Args, InputType);
47264799
47274800 for (phases::ID Phase : PL) {
@@ -4730,6 +4803,11 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
47304803 break ;
47314804 }
47324805
4806+ // Assemble actions are not used for the SYCL device side. Both compile
4807+ // and backend actions are used to generate IR and textual IR if needed.
4808+ if (Kind == Action::OFK_SYCL && Phase == phases::Assemble)
4809+ continue ;
4810+
47334811 auto TCAndArch = TCAndArchs.begin ();
47344812 for (Action *&A : DeviceActions) {
47354813 if (A->getType () == types::TY_Nothing)
@@ -4975,6 +5053,7 @@ Action *Driver::ConstructPhaseAction(
49755053 return C.MakeAction <BackendJobAction>(Input, Output);
49765054 }
49775055 if (Args.hasArg (options::OPT_emit_llvm) ||
5056+ TargetDeviceOffloadKind == Action::OFK_SYCL ||
49785057 (((Input->getOffloadingToolChain () &&
49795058 Input->getOffloadingToolChain ()->getTriple ().isAMDGPU ()) ||
49805059 TargetDeviceOffloadKind == Action::OFK_HIP) &&
@@ -6680,11 +6759,16 @@ const ToolChain &Driver::getOffloadingDeviceToolChain(
66806759 HostTC, Args);
66816760 break ;
66826761 }
6762+ case Action::OFK_SYCL:
6763+ if (Target.isSPIROrSPIRV ())
6764+ TC = std::make_unique<toolchains::SYCLToolChain>(*this , Target, HostTC,
6765+ Args);
6766+ break ;
66836767 default :
66846768 break ;
66856769 }
66866770 }
6687-
6771+ assert (TC && " Could not create offloading device tool chain. " );
66886772 return *TC;
66896773}
66906774
0 commit comments