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 //
@@ -4234,6 +4295,7 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
42344295
42354296 bool UseNewOffloadingDriver =
42364297 C.isOffloadingHostKind (Action::OFK_OpenMP) ||
4298+ C.isOffloadingHostKind (Action::OFK_SYCL) ||
42374299 Args.hasFlag (options::OPT_foffload_via_llvm,
42384300 options::OPT_fno_offload_via_llvm, false ) ||
42394301 Args.hasFlag (options::OPT_offload_new_driver,
@@ -4651,6 +4713,8 @@ Driver::getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args,
46514713 Archs.insert (OffloadArchToString (OffloadArch::HIPDefault));
46524714 else if (Kind == Action::OFK_OpenMP)
46534715 Archs.insert (StringRef ());
4716+ else if (Kind == Action::OFK_SYCL)
4717+ Archs.insert (StringRef ());
46544718 } else {
46554719 Args.ClaimAllArgs (options::OPT_offload_arch_EQ);
46564720 Args.ClaimAllArgs (options::OPT_no_offload_arch_EQ);
@@ -4675,7 +4739,7 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
46754739 OffloadAction::DeviceDependences DDeps;
46764740
46774741 const Action::OffloadKind OffloadKinds[] = {
4678- Action::OFK_OpenMP, Action::OFK_Cuda, Action::OFK_HIP};
4742+ Action::OFK_OpenMP, Action::OFK_Cuda, Action::OFK_HIP, Action::OFK_SYCL };
46794743
46804744 for (Action::OffloadKind Kind : OffloadKinds) {
46814745 SmallVector<const ToolChain *, 2 > ToolChains;
@@ -4712,6 +4776,15 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
47124776 if (DeviceActions.empty ())
47134777 return HostAction;
47144778
4779+ // FIXME: Do not collapse the host side for Darwin targets with SYCL offload
4780+ // compilations. The toolchain is not properly initialized for the target.
4781+ if (isa<CompileJobAction>(HostAction) && Kind == Action::OFK_SYCL &&
4782+ HostAction->getType () != types::TY_Nothing &&
4783+ C.getSingleOffloadToolChain <Action::OFK_Host>()
4784+ ->getTriple ()
4785+ .isOSDarwin ())
4786+ HostAction->setCannotBeCollapsedWithNextDependentAction ();
4787+
47154788 auto PL = types::getCompilationPhases (*this , Args, InputType);
47164789
47174790 for (phases::ID Phase : PL) {
@@ -4720,6 +4793,11 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
47204793 break ;
47214794 }
47224795
4796+ // Assemble actions are not used for the SYCL device side. Both compile
4797+ // and backend actions are used to generate IR and textual IR if needed.
4798+ if (Kind == Action::OFK_SYCL && Phase == phases::Assemble)
4799+ continue ;
4800+
47234801 auto TCAndArch = TCAndArchs.begin ();
47244802 for (Action *&A : DeviceActions) {
47254803 if (A->getType () == types::TY_Nothing)
@@ -4958,6 +5036,7 @@ Action *Driver::ConstructPhaseAction(
49585036 return C.MakeAction <BackendJobAction>(Input, Output);
49595037 }
49605038 if (Args.hasArg (options::OPT_emit_llvm) ||
5039+ TargetDeviceOffloadKind == Action::OFK_SYCL ||
49615040 (((Input->getOffloadingToolChain () &&
49625041 Input->getOffloadingToolChain ()->getTriple ().isAMDGPU ()) ||
49635042 TargetDeviceOffloadKind == Action::OFK_HIP) &&
@@ -6644,11 +6723,16 @@ const ToolChain &Driver::getOffloadingDeviceToolChain(
66446723 HostTC, Args);
66456724 break ;
66466725 }
6726+ case Action::OFK_SYCL:
6727+ if (Target.isSPIROrSPIRV ())
6728+ TC = std::make_unique<toolchains::SYCLToolChain>(*this , Target, HostTC,
6729+ Args);
6730+ break ;
66476731 default :
66486732 break ;
66496733 }
66506734 }
6651-
6735+ assert (TC && " Could not create offloading device tool chain. " );
66526736 return *TC;
66536737}
66546738
0 commit comments