@@ -886,42 +886,37 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
886
886
return ;
887
887
}
888
888
if (IsCuda && !UseLLVMOffload) {
889
- const ToolChain *HostTC = C.getSingleOffloadToolChain <Action::OFK_Host>();
890
- const llvm::Triple &HostTriple = HostTC->getTriple ();
891
- auto OFK = Action::OFK_Cuda;
892
- auto CudaTriple =
893
- getNVIDIAOffloadTargetTriple (*this , C.getInputArgs (), HostTriple);
889
+ auto CudaTriple = getNVIDIAOffloadTargetTriple (
890
+ *this , C.getInputArgs (), C.getDefaultToolChain ().getTriple ());
894
891
if (!CudaTriple)
895
892
return ;
896
- // Use the CUDA and host triples as the key into the ToolChains map,
897
- // because the device toolchain we create depends on both.
898
- auto &CudaTC = ToolChains[CudaTriple->str () + " /" + HostTriple.str ()];
899
- if (!CudaTC) {
900
- CudaTC = std::make_unique<toolchains::CudaToolChain>(
901
- *this , *CudaTriple, *HostTC, C.getInputArgs ());
902
-
903
- // Emit a warning if the detected CUDA version is too new.
904
- CudaInstallationDetector &CudaInstallation =
905
- static_cast <toolchains::CudaToolChain &>(*CudaTC).CudaInstallation ;
906
- if (CudaInstallation.isValid ())
907
- CudaInstallation.WarnIfUnsupportedVersion ();
908
- }
909
- C.addOffloadDeviceToolChain (CudaTC.get (), OFK);
893
+
894
+ auto &TC =
895
+ getOffloadToolChain (C.getInputArgs (), Action::OFK_Cuda, *CudaTriple,
896
+ C.getDefaultToolChain ().getTriple ());
897
+
898
+ // Emit a warning if the detected CUDA version is too new.
899
+ const CudaInstallationDetector &CudaInstallation =
900
+ static_cast <const toolchains::CudaToolChain &>(TC).CudaInstallation ;
901
+ if (CudaInstallation.isValid ())
902
+ CudaInstallation.WarnIfUnsupportedVersion ();
903
+ C.addOffloadDeviceToolChain (&TC, Action::OFK_Cuda);
910
904
} else if (IsHIP && !UseLLVMOffload) {
911
905
if (auto *OMPTargetArg =
912
906
C.getInputArgs ().getLastArg (options::OPT_fopenmp_targets_EQ)) {
913
907
Diag (clang::diag::err_drv_unsupported_opt_for_language_mode)
914
908
<< OMPTargetArg->getSpelling () << " HIP" ;
915
909
return ;
916
910
}
917
- const ToolChain *HostTC = C.getSingleOffloadToolChain <Action::OFK_Host>();
918
- auto OFK = Action::OFK_HIP;
911
+
919
912
auto HIPTriple = getHIPOffloadTargetTriple (*this , C.getInputArgs ());
920
913
if (!HIPTriple)
921
914
return ;
922
- auto *HIPTC = &getOffloadingDeviceToolChain (C.getInputArgs (), *HIPTriple,
923
- *HostTC, OFK);
924
- C.addOffloadDeviceToolChain (HIPTC, OFK);
915
+
916
+ auto &TC =
917
+ getOffloadToolChain (C.getInputArgs (), Action::OFK_HIP, *HIPTriple,
918
+ C.getDefaultToolChain ().getTriple ());
919
+ C.addOffloadDeviceToolChain (&TC, Action::OFK_HIP);
925
920
}
926
921
927
922
if (IsCuda || IsHIP)
@@ -1038,40 +1033,17 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
1038
1033
FoundNormalizedTriples[NormalizedName] = Val;
1039
1034
1040
1035
// If the specified target is invalid, emit a diagnostic.
1041
- if (TT.getArch () == llvm::Triple::UnknownArch)
1036
+ if (TT.getArch () == llvm::Triple::UnknownArch) {
1042
1037
Diag (clang::diag::err_drv_invalid_omp_target) << Val;
1043
- else {
1044
- const ToolChain *TC;
1045
- // Device toolchains have to be selected differently. They pair host
1046
- // and device in their implementation.
1047
- if (TT.isNVPTX () || TT.isAMDGCN () || TT.isSPIRV ()) {
1048
- const ToolChain *HostTC =
1049
- C.getSingleOffloadToolChain <Action::OFK_Host>();
1050
- assert (HostTC && " Host toolchain should be always defined." );
1051
- auto &DeviceTC =
1052
- ToolChains[TT.str () + " /" + HostTC->getTriple ().normalize ()];
1053
- if (!DeviceTC) {
1054
- if (TT.isNVPTX ())
1055
- DeviceTC = std::make_unique<toolchains::CudaToolChain>(
1056
- *this , TT, *HostTC, C.getInputArgs ());
1057
- else if (TT.isAMDGCN ())
1058
- DeviceTC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(
1059
- *this , TT, *HostTC, C.getInputArgs ());
1060
- else if (TT.isSPIRV ())
1061
- DeviceTC = std::make_unique<toolchains::SPIRVOpenMPToolChain>(
1062
- *this , TT, *HostTC, C.getInputArgs ());
1063
- else
1064
- assert (DeviceTC && " Device toolchain not defined." );
1065
- }
1066
-
1067
- TC = DeviceTC.get ();
1068
- } else
1069
- TC = &getToolChain (C.getInputArgs (), TT);
1070
- C.addOffloadDeviceToolChain (TC, Action::OFK_OpenMP);
1071
- auto It = DerivedArchs.find (TT.getTriple ());
1072
- if (It != DerivedArchs.end ())
1073
- KnownArchs[TC] = It->second ;
1038
+ continue ;
1074
1039
}
1040
+
1041
+ auto &TC = getOffloadToolChain (C.getInputArgs (), Action::OFK_OpenMP, TT,
1042
+ C.getDefaultToolChain ().getTriple ());
1043
+ C.addOffloadDeviceToolChain (&TC, Action::OFK_OpenMP);
1044
+ auto It = DerivedArchs.find (TT.getTriple ());
1045
+ if (It != DerivedArchs.end ())
1046
+ KnownArchs[&TC] = It->second ;
1075
1047
}
1076
1048
} else if (C.getInputArgs ().hasArg (options::OPT_fopenmp_targets_EQ)) {
1077
1049
Diag (clang::diag::err_drv_expecting_fopenmp_with_fopenmp_targets);
@@ -1103,9 +1075,9 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
1103
1075
// getOffloadingDeviceToolChain, because the device toolchains we're
1104
1076
// going to create will depend on both.
1105
1077
const ToolChain *HostTC = C.getSingleOffloadToolChain <Action::OFK_Host>();
1106
- for (const auto &TargetTriple : UniqueSYCLTriplesVec) {
1107
- auto SYCLTC = &getOffloadingDeviceToolChain (
1108
- C. getInputArgs (), TargetTriple, *HostTC, Action::OFK_SYCL );
1078
+ for (const auto &TT : UniqueSYCLTriplesVec) {
1079
+ auto SYCLTC = &getOffloadToolChain (C. getInputArgs (), Action::OFK_SYCL, TT,
1080
+ HostTC-> getTriple () );
1109
1081
C.addOffloadDeviceToolChain (SYCLTC, Action::OFK_SYCL);
1110
1082
}
1111
1083
}
@@ -6605,6 +6577,73 @@ std::string Driver::GetClPchPath(Compilation &C, StringRef BaseName) const {
6605
6577
return std::string (Output);
6606
6578
}
6607
6579
6580
+ const ToolChain &Driver::getOffloadToolChain (
6581
+ const llvm::opt::ArgList &Args, const Action::OffloadKind Kind,
6582
+ const llvm::Triple &Target, const llvm::Triple &AuxTarget) const {
6583
+ std::unique_ptr<ToolChain> &TC =
6584
+ ToolChains[Target.str () + " /" + AuxTarget.str ()];
6585
+ std::unique_ptr<ToolChain> &HostTC = ToolChains[AuxTarget.str ()];
6586
+
6587
+ assert (HostTC && " Host toolchain for offloading doesn't exit?" );
6588
+ if (!TC) {
6589
+ // Detect the toolchain based off of the target operating system.
6590
+ switch (Target.getOS ()) {
6591
+ case llvm::Triple::CUDA:
6592
+ TC = std::make_unique<toolchains::CudaToolChain>(*this , Target, *HostTC,
6593
+ Args);
6594
+ break ;
6595
+ case llvm::Triple::AMDHSA:
6596
+ if (Kind == Action::OFK_HIP)
6597
+ TC = std::make_unique<toolchains::HIPAMDToolChain>(*this , Target,
6598
+ *HostTC, Args);
6599
+ else if (Kind == Action::OFK_OpenMP)
6600
+ TC = std::make_unique<toolchains::AMDGPUOpenMPToolChain>(*this , Target,
6601
+ *HostTC, Args);
6602
+ break ;
6603
+ default :
6604
+ break ;
6605
+ }
6606
+ }
6607
+ if (!TC) {
6608
+ // Detect the toolchain based off of the target architecture if that failed.
6609
+ switch (Target.getArch ()) {
6610
+ case llvm::Triple::spir:
6611
+ case llvm::Triple::spir64:
6612
+ case llvm::Triple::spirv:
6613
+ case llvm::Triple::spirv32:
6614
+ case llvm::Triple::spirv64:
6615
+ switch (Kind) {
6616
+ case Action::OFK_SYCL:
6617
+ TC = std::make_unique<toolchains::SYCLToolChain>(*this , Target, *HostTC,
6618
+ Args);
6619
+ break ;
6620
+ case Action::OFK_HIP:
6621
+ TC = std::make_unique<toolchains::HIPSPVToolChain>(*this , Target,
6622
+ *HostTC, Args);
6623
+ break ;
6624
+ case Action::OFK_OpenMP:
6625
+ TC = std::make_unique<toolchains::SPIRVOpenMPToolChain>(*this , Target,
6626
+ *HostTC, Args);
6627
+ break ;
6628
+ case Action::OFK_Cuda:
6629
+ TC = std::make_unique<toolchains::CudaToolChain>(*this , Target, *HostTC,
6630
+ Args);
6631
+ break ;
6632
+ default :
6633
+ break ;
6634
+ }
6635
+ break ;
6636
+ default :
6637
+ break ;
6638
+ }
6639
+ }
6640
+
6641
+ // If all else fails, just look up the normal toolchain for the target.
6642
+ if (!TC)
6643
+ return getToolChain (Args, Target);
6644
+ return *TC;
6645
+ }
6646
+
6608
6647
const ToolChain &Driver::getToolChain (const ArgList &Args,
6609
6648
const llvm::Triple &Target) const {
6610
6649
@@ -6798,45 +6837,6 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
6798
6837
return *TC;
6799
6838
}
6800
6839
6801
- const ToolChain &Driver::getOffloadingDeviceToolChain (
6802
- const ArgList &Args, const llvm::Triple &Target, const ToolChain &HostTC,
6803
- const Action::OffloadKind &TargetDeviceOffloadKind) const {
6804
- // Use device / host triples as the key into the ToolChains map because the
6805
- // device ToolChain we create depends on both.
6806
- auto &TC = ToolChains[Target.str () + " /" + HostTC.getTriple ().str ()];
6807
- if (!TC) {
6808
- // Categorized by offload kind > arch rather than OS > arch like
6809
- // the normal getToolChain call, as it seems a reasonable way to categorize
6810
- // things.
6811
- switch (TargetDeviceOffloadKind) {
6812
- case Action::OFK_HIP: {
6813
- if (((Target.getArch () == llvm::Triple::amdgcn ||
6814
- Target.getArch () == llvm::Triple::spirv64) &&
6815
- Target.getVendor () == llvm::Triple::AMD &&
6816
- Target.getOS () == llvm::Triple::AMDHSA) ||
6817
- !Args.hasArgNoClaim (options::OPT_offload_EQ))
6818
- TC = std::make_unique<toolchains::HIPAMDToolChain>(*this , Target,
6819
- HostTC, Args);
6820
- else if (Target.getArch () == llvm::Triple::spirv64 &&
6821
- Target.getVendor () == llvm::Triple::UnknownVendor &&
6822
- Target.getOS () == llvm::Triple::UnknownOS)
6823
- TC = std::make_unique<toolchains::HIPSPVToolChain>(*this , Target,
6824
- HostTC, Args);
6825
- break ;
6826
- }
6827
- case Action::OFK_SYCL:
6828
- if (Target.isSPIROrSPIRV ())
6829
- TC = std::make_unique<toolchains::SYCLToolChain>(*this , Target, HostTC,
6830
- Args);
6831
- break ;
6832
- default :
6833
- break ;
6834
- }
6835
- }
6836
- assert (TC && " Could not create offloading device tool chain." );
6837
- return *TC;
6838
- }
6839
-
6840
6840
bool Driver::ShouldUseClangCompiler (const JobAction &JA) const {
6841
6841
// Say "no" if there is not exactly one input of a type clang understands.
6842
6842
if (JA.size () != 1 ||
0 commit comments