44
44
#include " ToolChains/RISCVToolchain.h"
45
45
#include " ToolChains/SPIRV.h"
46
46
#include " ToolChains/SPIRVOpenMP.h"
47
+ #include " ToolChains/SYCL.h"
47
48
#include " ToolChains/Solaris.h"
48
49
#include " ToolChains/TCE.h"
49
50
#include " ToolChains/UEFI.h"
@@ -781,6 +782,35 @@ Driver::OpenMPRuntimeKind Driver::getOpenMPRuntime(const ArgList &Args) const {
781
782
return RT;
782
783
}
783
784
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
+
784
814
void Driver::CreateOffloadingDeviceToolChains (Compilation &C,
785
815
InputList &Inputs) {
786
816
@@ -842,7 +872,6 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
842
872
return ;
843
873
auto *HIPTC = &getOffloadingDeviceToolChain (C.getInputArgs (), *HIPTriple,
844
874
*HostTC, OFK);
845
- assert (HIPTC && " Could not create offloading device tool chain." );
846
875
C.addOffloadDeviceToolChain (HIPTC, OFK);
847
876
}
848
877
@@ -997,6 +1026,38 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
997
1026
return ;
998
1027
}
999
1028
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
+
1000
1061
//
1001
1062
// TODO: Add support for other offloading programming models here.
1002
1063
//
@@ -4234,6 +4295,7 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
4234
4295
4235
4296
bool UseNewOffloadingDriver =
4236
4297
C.isOffloadingHostKind (Action::OFK_OpenMP) ||
4298
+ C.isOffloadingHostKind (Action::OFK_SYCL) ||
4237
4299
Args.hasFlag (options::OPT_foffload_via_llvm,
4238
4300
options::OPT_fno_offload_via_llvm, false ) ||
4239
4301
Args.hasFlag (options::OPT_offload_new_driver,
@@ -4651,6 +4713,8 @@ Driver::getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args,
4651
4713
Archs.insert (OffloadArchToString (OffloadArch::HIPDefault));
4652
4714
else if (Kind == Action::OFK_OpenMP)
4653
4715
Archs.insert (StringRef ());
4716
+ else if (Kind == Action::OFK_SYCL)
4717
+ Archs.insert (StringRef ());
4654
4718
} else {
4655
4719
Args.ClaimAllArgs (options::OPT_offload_arch_EQ);
4656
4720
Args.ClaimAllArgs (options::OPT_no_offload_arch_EQ);
@@ -4675,7 +4739,7 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
4675
4739
OffloadAction::DeviceDependences DDeps;
4676
4740
4677
4741
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 };
4679
4743
4680
4744
for (Action::OffloadKind Kind : OffloadKinds) {
4681
4745
SmallVector<const ToolChain *, 2 > ToolChains;
@@ -4712,6 +4776,15 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
4712
4776
if (DeviceActions.empty ())
4713
4777
return HostAction;
4714
4778
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
+
4715
4788
auto PL = types::getCompilationPhases (*this , Args, InputType);
4716
4789
4717
4790
for (phases::ID Phase : PL) {
@@ -4720,6 +4793,11 @@ Action *Driver::BuildOffloadingActions(Compilation &C,
4720
4793
break ;
4721
4794
}
4722
4795
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
+
4723
4801
auto TCAndArch = TCAndArchs.begin ();
4724
4802
for (Action *&A : DeviceActions) {
4725
4803
if (A->getType () == types::TY_Nothing)
@@ -4958,6 +5036,7 @@ Action *Driver::ConstructPhaseAction(
4958
5036
return C.MakeAction <BackendJobAction>(Input, Output);
4959
5037
}
4960
5038
if (Args.hasArg (options::OPT_emit_llvm) ||
5039
+ TargetDeviceOffloadKind == Action::OFK_SYCL ||
4961
5040
(((Input->getOffloadingToolChain () &&
4962
5041
Input->getOffloadingToolChain ()->getTriple ().isAMDGPU ()) ||
4963
5042
TargetDeviceOffloadKind == Action::OFK_HIP) &&
@@ -6644,11 +6723,16 @@ const ToolChain &Driver::getOffloadingDeviceToolChain(
6644
6723
HostTC, Args);
6645
6724
break ;
6646
6725
}
6726
+ case Action::OFK_SYCL:
6727
+ if (Target.isSPIROrSPIRV ())
6728
+ TC = std::make_unique<toolchains::SYCLToolChain>(*this , Target, HostTC,
6729
+ Args);
6730
+ break ;
6647
6731
default :
6648
6732
break ;
6649
6733
}
6650
6734
}
6651
-
6735
+ assert (TC && " Could not create offloading device tool chain. " );
6652
6736
return *TC;
6653
6737
}
6654
6738
0 commit comments