4343#include " ToolChains/PS4CPU.h"
4444#include " ToolChains/RISCVToolchain.h"
4545#include " ToolChains/SPIRV.h"
46+ #include " ToolChains/SYCL.h"
4647#include " ToolChains/Solaris.h"
4748#include " ToolChains/TCE.h"
4849#include " ToolChains/UEFI.h"
@@ -780,6 +781,41 @@ Driver::OpenMPRuntimeKind Driver::getOpenMPRuntime(const ArgList &Args) const {
780781 return RT;
781782}
782783
784+ static const char *getDefaultSYCLArch (Compilation &C) {
785+ // If -fsycl is supplied we will assume SPIR-V
786+ if (C.getDefaultToolChain ().getTriple ().isArch32Bit ())
787+ return " spirv32" ;
788+ return " spirv64" ;
789+ }
790+
791+ static llvm::Triple getSYCLDeviceTriple (StringRef TargetArch) {
792+ SmallVector<StringRef, 5 > SYCLAlias = {" spir" , " spir64" , " spirv" , " spirv32" ,
793+ " spirv64" };
794+ if (std::find (SYCLAlias.begin (), SYCLAlias.end (), TargetArch) !=
795+ SYCLAlias.end ()) {
796+ llvm::Triple TargetTriple;
797+ TargetTriple.setArchName (TargetArch);
798+ TargetTriple.setVendor (llvm::Triple::UnknownVendor);
799+ TargetTriple.setOS (llvm::Triple::UnknownOS);
800+ return TargetTriple;
801+ }
802+ return llvm::Triple (TargetArch);
803+ }
804+
805+ static bool addSYCLDefaultTriple (Compilation &C,
806+ SmallVectorImpl<llvm::Triple> &SYCLTriples) {
807+ // Check current set of triples to see if the default has already been set.
808+ for (const auto &SYCLTriple : SYCLTriples) {
809+ if (SYCLTriple.getSubArch () == llvm::Triple::NoSubArch &&
810+ SYCLTriple.isSPIROrSPIRV ())
811+ return false ;
812+ }
813+ // Add the default triple as it was not found.
814+ llvm::Triple DefaultTriple = getSYCLDeviceTriple (getDefaultSYCLArch (C));
815+ SYCLTriples.insert (SYCLTriples.begin (), DefaultTriple);
816+ return true ;
817+ }
818+
783819void Driver::CreateOffloadingDeviceToolChains (Compilation &C,
784820 InputList &Inputs) {
785821
@@ -993,6 +1029,42 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
9931029 return ;
9941030 }
9951031
1032+ //
1033+ // SYCL
1034+ //
1035+ // We need to generate a SYCL toolchain if the user specified -fsycl.
1036+ bool IsSYCL = C.getInputArgs ().hasFlag (options::OPT_fsycl,
1037+ options::OPT_fno_sycl, false );
1038+
1039+ auto argSYCLIncompatible = [&](OptSpecifier OptId) {
1040+ if (!IsSYCL)
1041+ return ;
1042+ if (Arg *IncompatArg = C.getInputArgs ().getLastArg (OptId))
1043+ Diag (clang::diag::err_drv_argument_not_allowed_with)
1044+ << IncompatArg->getSpelling () << " -fsycl" ;
1045+ };
1046+ // -static-libstdc++ is not compatible with -fsycl.
1047+ argSYCLIncompatible (options::OPT_static_libstdcxx);
1048+ // -ffreestanding cannot be used with -fsycl
1049+ argSYCLIncompatible (options::OPT_ffreestanding);
1050+
1051+ llvm::SmallVector<llvm::Triple, 4 > UniqueSYCLTriplesVec;
1052+
1053+ if (IsSYCL) {
1054+ addSYCLDefaultTriple (C, UniqueSYCLTriplesVec);
1055+
1056+ // We'll need to use the SYCL and host triples as the key into
1057+ // getOffloadingDeviceToolChain, because the device toolchains we're
1058+ // going to create will depend on both.
1059+ const ToolChain *HostTC = C.getSingleOffloadToolChain <Action::OFK_Host>();
1060+ for (const auto &TargetTriple : UniqueSYCLTriplesVec) {
1061+ auto SYCLTC = &getOffloadingDeviceToolChain (
1062+ C.getInputArgs (), TargetTriple, *HostTC, Action::OFK_SYCL);
1063+ assert (SYCLTC && " Could not create offloading device tool chain." );
1064+ C.addOffloadDeviceToolChain (SYCLTC, Action::OFK_SYCL);
1065+ }
1066+ }
1067+
9961068 //
9971069 // TODO: Add support for other offloading programming models here.
9981070 //
@@ -4183,6 +4255,7 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
41834255
41844256 bool UseNewOffloadingDriver =
41854257 C.isOffloadingHostKind (Action::OFK_OpenMP) ||
4258+ C.isOffloadingHostKind (Action::OFK_SYCL) ||
41864259 Args.hasFlag (options::OPT_foffload_via_llvm,
41874260 options::OPT_fno_offload_via_llvm, false ) ||
41884261 Args.hasFlag (options::OPT_offload_new_driver,
@@ -4593,6 +4666,8 @@ Driver::getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args,
45934666 Archs.insert (OffloadArchToString (OffloadArch::HIPDefault));
45944667 else if (Kind == Action::OFK_OpenMP)
45954668 Archs.insert (StringRef ());
4669+ else if (Kind == Action::OFK_SYCL)
4670+ Archs.insert (StringRef ());
45964671 } else {
45974672 Args.ClaimAllArgs (options::OPT_offload_arch_EQ);
45984673 Args.ClaimAllArgs (options::OPT_no_offload_arch_EQ);
@@ -4617,7 +4692,7 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
46174692 OffloadAction::DeviceDependences DDeps;
46184693
46194694 const Action::OffloadKind OffloadKinds[] = {
4620- Action::OFK_OpenMP, Action::OFK_Cuda, Action::OFK_HIP};
4695+ Action::OFK_OpenMP, Action::OFK_Cuda, Action::OFK_HIP, Action::OFK_SYCL };
46214696
46224697 for (Action::OffloadKind Kind : OffloadKinds) {
46234698 SmallVector<const ToolChain *, 2 > ToolChains;
@@ -4654,6 +4729,15 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
46544729 if (DeviceActions.empty ())
46554730 return HostAction;
46564731
4732+ // FIXME: Do not collapse the host side for Darwin targets with SYCL offload
4733+ // compilations. The toolchain is not properly initialized for the target.
4734+ if (isa<CompileJobAction>(HostAction) && Kind == Action::OFK_SYCL &&
4735+ HostAction->getType () != types::TY_Nothing &&
4736+ C.getSingleOffloadToolChain <Action::OFK_Host>()
4737+ ->getTriple ()
4738+ .isOSDarwin ())
4739+ HostAction->setCannotBeCollapsedWithNextDependentAction ();
4740+
46574741 auto PL = types::getCompilationPhases (*this , Args, InputType);
46584742
46594743 for (phases::ID Phase : PL) {
@@ -4662,6 +4746,11 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
46624746 break ;
46634747 }
46644748
4749+ // Assemble actions are not used for the SYCL device side. Both compile
4750+ // and backend actions are used to generate IR and textual IR if needed.
4751+ if (Kind == Action::OFK_SYCL && Phase == phases::Assemble)
4752+ continue ;
4753+
46654754 auto TCAndArch = TCAndArchs.begin ();
46664755 for (Action *&A : DeviceActions) {
46674756 if (A->getType () == types::TY_Nothing)
@@ -4900,6 +4989,7 @@ Action *Driver::ConstructPhaseAction(
49004989 return C.MakeAction <BackendJobAction>(Input, Output);
49014990 }
49024991 if (Args.hasArg (options::OPT_emit_llvm) ||
4992+ TargetDeviceOffloadKind == Action::OFK_SYCL ||
49034993 (((Input->getOffloadingToolChain () &&
49044994 Input->getOffloadingToolChain ()->getTriple ().isAMDGPU ()) ||
49054995 TargetDeviceOffloadKind == Action::OFK_HIP) &&
@@ -6591,6 +6681,18 @@ const ToolChain &Driver::getOffloadingDeviceToolChain(
65916681 HostTC, Args);
65926682 break ;
65936683 }
6684+ case Action::OFK_SYCL:
6685+ switch (Target.getArch ()) {
6686+ case llvm::Triple::spir:
6687+ case llvm::Triple::spir64:
6688+ case llvm::Triple::spirv32:
6689+ case llvm::Triple::spirv64:
6690+ TC = std::make_unique<toolchains::SYCLToolChain>(*this , Target, HostTC,
6691+ Args);
6692+ break ;
6693+ default :
6694+ break ;
6695+ }
65946696 default :
65956697 break ;
65966698 }
0 commit comments