11#include "clang/Config/config.h"
18#include "llvm/ADT/SmallSet.h"
19#include "llvm/ADT/StringExtras.h"
20#include "llvm/Config/llvm-config.h"
21#include "llvm/Option/ArgList.h"
22#include "llvm/Support/FileSystem.h"
23#include "llvm/Support/Path.h"
24#include "llvm/Support/Process.h"
25#include "llvm/Support/Program.h"
26#include "llvm/Support/VirtualFileSystem.h"
27#include "llvm/TargetParser/Host.h"
28#include "llvm/TargetParser/TargetParser.h"
29#include <system_error>
40 if (raw_version < 7050)
42 if (raw_version < 8000)
44 if (raw_version < 9000)
46 if (raw_version < 9010)
48 if (raw_version < 9020)
50 if (raw_version < 10000)
52 if (raw_version < 10010)
54 if (raw_version < 10020)
56 if (raw_version < 11000)
58 if (raw_version < 11010)
60 if (raw_version < 11020)
62 if (raw_version < 11030)
64 if (raw_version < 11040)
66 if (raw_version < 11050)
68 if (raw_version < 11060)
70 if (raw_version < 11070)
72 if (raw_version < 11080)
74 if (raw_version < 11090)
76 if (raw_version < 12010)
78 if (raw_version < 12020)
80 if (raw_version < 12030)
82 if (raw_version < 12040)
84 if (raw_version < 12050)
86 if (raw_version < 12060)
88 if (raw_version < 12070)
90 if (raw_version < 12090)
92 if (raw_version < 13000)
94 if (raw_version < 13010)
96 if (raw_version < 13020)
98 if (raw_version < 13030)
100 if (raw_version < 13040)
102 if (raw_version < 13050)
110 auto StartsWithWords =
111 [](llvm::StringRef
Line,
113 for (StringRef word : words) {
114 if (!
Line.consume_front(word))
121 Input = Input.ltrim();
122 while (!Input.empty()) {
124 StartsWithWords(Input.ltrim(), {
"#",
"define",
"CUDA_VERSION"})) {
126 Line->consumeInteger(10, RawVersion);
127 return getCudaVersion(RawVersion);
130 Input = Input.drop_front(Input.find_first_of(
"\n\r")).ltrim();
139 if (!VersionString.empty())
140 VersionString.insert(0,
" ");
141 D.Diag(diag::warn_drv_new_cuda_version)
146 D.Diag(diag::warn_drv_partially_supported_cuda_version)
151 const Driver &D,
const llvm::Triple &HostTriple,
152 const llvm::opt::ArgList &Args)
158 Candidate(std::string Path,
bool StrictChecking =
false)
159 : Path(Path), StrictChecking(StrictChecking) {}
164 std::initializer_list<const char *> Versions = {
"8.0",
"7.5",
"7.0"};
165 auto &FS = D.getVFS();
167 if (Args.hasArg(options::OPT_cuda_path_EQ)) {
168 Candidates.emplace_back(
169 Args.getLastArgValue(options::OPT_cuda_path_EQ).str());
170 }
else if (HostTriple.isOSWindows()) {
171 for (
const char *Ver : Versions)
172 Candidates.emplace_back(
173 D.SysRoot +
"/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v" +
176 if (!Args.hasArg(options::OPT_cuda_path_ignore_env)) {
185 if (llvm::ErrorOr<std::string> ptxas =
186 llvm::sys::findProgramByName(
"ptxas")) {
188 llvm::sys::fs::real_path(*ptxas, ptxasAbsolutePath);
190 StringRef ptxasDir = llvm::sys::path::parent_path(ptxasAbsolutePath);
191 if (llvm::sys::path::filename(ptxasDir) ==
"bin")
192 Candidates.emplace_back(
193 std::string(llvm::sys::path::parent_path(ptxasDir)),
198 Candidates.emplace_back(D.SysRoot +
"/usr/local/cuda");
199 for (
const char *Ver : Versions)
200 Candidates.emplace_back(D.SysRoot +
"/usr/local/cuda-" + Ver);
202 Distro Dist(FS, llvm::Triple(llvm::sys::getProcessTriple()));
206 Candidates.emplace_back(D.SysRoot +
"/usr/lib/cuda");
210 !Args.hasFlag(options::OPT_offloadlib, options::OPT_no_offloadlib,
true);
212 for (
const auto &Candidate : Candidates) {
213 InstallPath = Candidate.Path;
214 if (InstallPath.empty() || !FS.exists(InstallPath))
217 BinPath = InstallPath +
"/bin";
218 IncludePath = InstallPath +
"/include";
219 LibDevicePath = InstallPath +
"/nvvm/libdevice";
221 if (!(FS.exists(IncludePath) && FS.exists(BinPath)))
223 bool CheckLibDevice = (!NoCudaLib || Candidate.StrictChecking);
224 if (CheckLibDevice && !FS.exists(LibDevicePath))
228 if (
auto CudaHFile = FS.getBufferForFile(InstallPath +
"/include/cuda.h"))
229 Version = parseCudaHFile((*CudaHFile)->getBuffer());
233 Version = FS.exists(LibDevicePath +
"/libdevice.10.bc")
240 std::string FilePath = LibDevicePath +
"/libdevice.10.bc";
241 if (FS.exists(FilePath)) {
244#define NVPTX_GPU(NAME, KIND, VIRTUAL, SM_ID, MIN_VER, MAX_VER, SUFFIX) \
245 if ((SM_ID) >= 300) \
246 LibDeviceMap[NAME] = FilePath;
247#include "llvm/TargetParser/NVPTXTargetParser.def"
251 for (llvm::vfs::directory_iterator LI = FS.dir_begin(LibDevicePath, EC),
253 !EC && LI != LE; LI = LI.increment(EC)) {
254 StringRef FilePath = LI->path();
255 StringRef
FileName = llvm::sys::path::filename(FilePath);
258 const StringRef LibDeviceName =
"libdevice.";
262 LibDeviceName.size(),
FileName.find(
'.', LibDeviceName.size()));
263 LibDeviceMap[GpuArch] = FilePath.str();
267 if (GpuArch ==
"compute_20") {
268 LibDeviceMap[
"sm_20"] = std::string(FilePath);
269 LibDeviceMap[
"sm_21"] = std::string(FilePath);
270 LibDeviceMap[
"sm_32"] = std::string(FilePath);
271 }
else if (GpuArch ==
"compute_30") {
272 LibDeviceMap[
"sm_30"] = std::string(FilePath);
274 LibDeviceMap[
"sm_50"] = std::string(FilePath);
275 LibDeviceMap[
"sm_52"] = std::string(FilePath);
276 LibDeviceMap[
"sm_53"] = std::string(FilePath);
278 LibDeviceMap[
"sm_60"] = std::string(FilePath);
279 LibDeviceMap[
"sm_61"] = std::string(FilePath);
280 LibDeviceMap[
"sm_62"] = std::string(FilePath);
281 }
else if (GpuArch ==
"compute_35") {
282 LibDeviceMap[
"sm_35"] = std::string(FilePath);
283 LibDeviceMap[
"sm_37"] = std::string(FilePath);
284 }
else if (GpuArch ==
"compute_50") {
286 LibDeviceMap[
"sm_50"] = std::string(FilePath);
287 LibDeviceMap[
"sm_52"] = std::string(FilePath);
288 LibDeviceMap[
"sm_53"] = std::string(FilePath);
296 if (LibDeviceMap.empty() && !NoCudaLib)
305 const ArgList &DriverArgs, ArgStringList &CC1Args)
const {
306 if (DriverArgs.hasFlag(options::OPT_foffload_via_llvm,
307 options::OPT_fno_offload_via_llvm,
false))
310 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
314 llvm::sys::path::append(P,
"include");
315 llvm::sys::path::append(P,
"cuda_wrappers");
316 CC1Args.push_back(
"-internal-isystem");
317 CC1Args.push_back(DriverArgs.MakeArgString(P));
320 if (!DriverArgs.hasFlag(options::OPT_offload_inc, options::OPT_no_offload_inc,
325 D.Diag(diag::err_drv_no_cuda_installation);
329 CC1Args.push_back(
"-include");
330 CC1Args.push_back(
"__clang_cuda_runtime_wrapper.h");
335 llvm::sys::path::append(CCCLPath,
"cccl");
336 if (D.getVFS().exists(CCCLPath)) {
337 CC1Args.push_back(
"-internal-isystem");
338 CC1Args.push_back(DriverArgs.MakeArgString(CCCLPath));
346 ArchsWithBadVersion[
Arch.nvptxKind()])
351 if (Version < MinVersion || Version > MaxVersion) {
352 ArchsWithBadVersion[
Arch.nvptxKind()] =
true;
353 D.Diag(diag::err_drv_cuda_version_unsupported)
362 OS <<
"Found CUDA installation: " << InstallPath <<
", version "
372enum DeviceDebugInfoLevel {
375 EmitSameDebugInfoAsHost,
389 const Arg *A = Args.getLastArg(options::OPT_O_Group);
390 bool IsDebugEnabled = !A || A->getOption().matches(options::OPT_O0) ||
391 Args.hasFlag(options::OPT_cuda_noopt_device_debug,
392 options::OPT_no_cuda_noopt_device_debug,
394 if (
const Arg *A = Args.getLastArg(options::OPT_g_Group)) {
395 const Option &Opt = A->getOption();
396 if (Opt.matches(options::OPT_gN_Group)) {
397 if (Opt.matches(options::OPT_g0) || Opt.matches(options::OPT_ggdb0))
398 return DisableDebugInfo;
399 if (Opt.matches(options::OPT_gline_directives_only))
400 return DebugDirectivesOnly;
402 return IsDebugEnabled ? EmitSameDebugInfoAsHost : DebugDirectivesOnly;
411 const char *LinkingOutput)
const {
415 bool UsesLLVMOffloading = Args.hasFlag(
416 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
417 assert((TC.getTriple().isNVPTX() || UsesLLVMOffloading) &&
"Wrong platform");
427 GPUArch =
BoundArch(Args.getLastArgValue(options::OPT_march_EQ));
428 if (GPUArch.
empty()) {
429 C.getDriver().Diag(diag::err_drv_offload_missing_gpu_arch)
437 "Device action expected to have an architecture.");
440 if (!UsesLLVMOffloading && !Args.hasArg(options::OPT_no_cuda_version_check)) {
441 TC.CudaInstallation.CheckCudaVersionSupportsArch(GPUArch.
Arch);
444 ArgStringList CmdArgs;
445 CmdArgs.push_back(TC.getTriple().isArch64Bit() ?
"-m64" :
"-m32");
447 if (DIKind == EmitSameDebugInfoAsHost) {
450 CmdArgs.push_back(
"-g");
451 CmdArgs.push_back(
"--dont-merge-basicblocks");
452 CmdArgs.push_back(
"--return-at-end");
453 }
else if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
461 StringRef OOpt =
"3";
462 if (A->getOption().matches(options::OPT_O4) ||
463 A->getOption().matches(options::OPT_Ofast))
465 else if (A->getOption().matches(options::OPT_O0))
467 else if (A->getOption().matches(options::OPT_O)) {
469 OOpt = llvm::StringSwitch<const char *>(A->getValue())
477 CmdArgs.push_back(Args.MakeArgString(llvm::Twine(
"-O") + OOpt));
481 CmdArgs.push_back(
"-O0");
483 if (DIKind == DebugDirectivesOnly)
484 CmdArgs.push_back(
"-lineinfo");
487 if (Args.hasArg(options::OPT_v))
488 CmdArgs.push_back(
"-v");
490 CmdArgs.push_back(
"--gpu-name");
491 CmdArgs.push_back(Args.MakeArgString(GPUArch.
ArchName));
492 CmdArgs.push_back(
"--output-file");
493 std::string OutputFileName = TC.getInputFilename(Output);
496 C.addTempFile(Args.MakeArgString(OutputFileName));
498 CmdArgs.push_back(Args.MakeArgString(OutputFileName));
499 for (
const auto &II : Inputs)
500 CmdArgs.push_back(Args.MakeArgString(II.getFilename()));
502 for (
const auto &A : Args.getAllArgValues(options::OPT_Xcuda_ptxas))
503 CmdArgs.push_back(Args.MakeArgString(A));
508 Relocatable = Args.hasFlag(options::OPT_fopenmp_relocatable_target,
509 options::OPT_fnoopenmp_relocatable_target,
513 Relocatable = UsesLLVMOffloading ||
514 Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
521 CmdArgs.push_back(
"-c");
524 if (Arg *A = Args.getLastArg(options::OPT_ptxas_path_EQ))
525 Exec = A->getValue();
527 Exec = Args.MakeArgString(TC.GetProgramPath(
"ptxas"));
528 C.addCommand(std::make_unique<Command>(
532 Exec, CmdArgs, Inputs, Output));
536 bool includePTX =
false;
537 for (Arg *A : Args.filtered(options::OPT_cuda_include_ptx_EQ,
538 options::OPT_no_cuda_include_ptx_EQ)) {
540 const StringRef ArchStr = A->getValue();
541 if (A->getOption().matches(options::OPT_cuda_include_ptx_EQ) &&
542 (ArchStr ==
"all" || ArchStr == InputArch))
544 else if (A->getOption().matches(options::OPT_no_cuda_include_ptx_EQ) &&
545 (ArchStr ==
"all" || ArchStr == InputArch))
558 const char *LinkingOutput)
const {
561 [[maybe_unused]]
bool UsesLLVMOffloading = Args.hasFlag(
562 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
563 assert((UsesLLVMOffloading || TC.getTriple().isNVPTX()) &&
"Wrong platform");
565 ArgStringList CmdArgs;
567 CmdArgs.push_back(
"--cuda");
568 CmdArgs.push_back(TC.getTriple().isArch64Bit() ?
"-64" :
"-32");
569 CmdArgs.push_back(Args.MakeArgString(
"--create"));
570 CmdArgs.push_back(Args.MakeArgString(Output.
getFilename()));
572 CmdArgs.push_back(
"-g");
574 for (
const auto &II : Inputs) {
575 auto *A = II.getAction();
576 assert(A->getInputs().size() == 1 &&
577 "Device offload action is expected to have a single input");
578 BoundArch GpuArch = A->getOffloadingArch();
579 assert(!GpuArch.
empty() &&
580 "Device action expected to have associated a GPU architecture!");
582 if (II.getType() == types::TY_PP_Asm &&
585 StringRef Kind = (II.getType() == types::TY_PP_Asm) ?
"ptx" :
"elf";
586 CmdArgs.push_back(Args.MakeArgString(
587 "--image3=kind=" + Kind +
",sm=" + GpuArch.
ArchName.drop_front(3) +
591 for (
const auto &A : Args.getAllArgValues(options::OPT_Xcuda_fatbinary))
592 CmdArgs.push_back(Args.MakeArgString(A));
594 const char *Exec = Args.MakeArgString(TC.GetProgramPath(
"fatbinary"));
595 C.addCommand(std::make_unique<Command>(
599 Exec, CmdArgs, Inputs, Output));
606 const char *LinkingOutput)
const {
609 ArgStringList CmdArgs;
611 [[maybe_unused]]
bool UsesLLVMOffloading = Args.hasFlag(
612 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
613 assert((UsesLLVMOffloading || TC.getTriple().isNVPTX()) &&
"Wrong platform");
617 CmdArgs.push_back(
"-o");
622 CmdArgs.push_back(
"-g");
624 if (Args.hasArg(options::OPT_v))
625 CmdArgs.push_back(
"-v");
627 StringRef GPUArch = Args.getLastArgValue(options::OPT_march_EQ);
628 if (GPUArch.empty() && !
getToolChain().isUsingLTO(Args)) {
629 C.getDriver().Diag(diag::err_drv_offload_missing_gpu_arch)
634 if (!GPUArch.empty()) {
635 CmdArgs.push_back(
"-arch");
636 CmdArgs.push_back(Args.MakeArgString(GPUArch));
639 if (Args.hasArg(options::OPT_ptxas_path_EQ))
640 CmdArgs.push_back(Args.MakeArgString(
641 "--ptxas-path=" + Args.getLastArgValue(options::OPT_ptxas_path_EQ)));
644 for (
const Arg *A : Args.filtered(options::OPT_Xcuda_ptxas)) {
646 CmdArgs.append({
"-Xptxas", A->getValue()});
649 if (Args.hasArg(options::OPT_cuda_path_EQ) || TC.CudaInstallation.isValid()) {
650 StringRef CudaPath = Args.getLastArgValue(
651 options::OPT_cuda_path_EQ,
652 llvm::sys::path::parent_path(TC.CudaInstallation.getBinPath()));
653 CmdArgs.push_back(Args.MakeArgString(
"--cuda-path=" + CudaPath));
660 Args.AddAllArgs(CmdArgs, options::OPT_L);
669 std::vector<StringRef> Features;
673 Args.MakeArgString(
"--plugin-opt=-mattr=" + llvm::join(Features,
",")));
677 llvm::sys::path::parent_path(TC.getDriver().Dir);
678 llvm::sys::path::append(DefaultLibPath, CLANG_INSTALL_LIBDIR_BASENAME);
679 CmdArgs.push_back(Args.MakeArgString(Twine(
"-L") + DefaultLibPath));
684 if (Args.hasArg(options::OPT_stdlib))
685 CmdArgs.append({
"-lc",
"-lm"});
686 if (Args.hasArg(options::OPT_startfiles)) {
687 std::optional<std::string> IncludePath =
getToolChain().getStdlibPath();
689 IncludePath =
"/lib";
691 llvm::sys::path::append(P,
"crt1.o");
692 CmdArgs.push_back(Args.MakeArgString(P));
695 C.addCommand(std::make_unique<Command>(
697 Args.MakeArgString(
getToolChain().GetProgramPath(
"clang-nvlink-wrapper")),
698 CmdArgs, Inputs, Output));
702 const llvm::opt::ArgList &Args,
703 std::vector<StringRef> &Features) {
704 if (Args.hasArg(options::OPT_cuda_feature_EQ)) {
705 StringRef PtxFeature = Args.getLastArgValue(options::OPT_cuda_feature_EQ);
706 Features.push_back(Args.MakeArgString(PtxFeature));
714 const char *PtxFeature =
nullptr;
715 switch (CudaInstallation.
version()) {
716#define CASE_CUDA_VERSION(CUDA_VER, PTX_VER) \
717 case CudaVersion::CUDA_##CUDA_VER: \
718 PtxFeature = "+ptx" #PTX_VER; \
752#undef CASE_CUDA_VERSION
755 PtxFeature =
"+ptx86";
762 Features.push_back(PtxFeature);
769 const llvm::Triple &HostTriple,
771 :
ToolChain(D, Triple, Args), CudaInstallation(D, HostTriple, Args) {
772 if (CudaInstallation.isValid())
773 getProgramPaths().push_back(std::string(CudaInstallation.getBinPath()));
776 getProgramPaths().push_back(getDriver().Dir);
784 loadMultilibsFromYAML(Args, D);
787llvm::opt::DerivedArgList *
793 DAL =
new DerivedArgList(Args.getBaseArgs());
795 const OptTable &Opts =
getDriver().getOpts();
798 if (!llvm::is_contained(*DAL, A))
801 if (!DAL->hasArg(options::OPT_march_EQ) && OffloadKind !=
Action::OFK_None) {
802 DAL->AddJoinedArg(
nullptr, Opts.getOption(options::OPT_march_EQ),
804 }
else if (DAL->getLastArgValue(options::OPT_march_EQ) ==
"generic" &&
806 DAL->eraseArg(options::OPT_march_EQ);
807 }
else if (DAL->getLastArgValue(options::OPT_march_EQ) ==
"native") {
810 getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
811 <<
getArchName() << llvm::toString(GPUsOrErr.takeError()) <<
"-march";
813 auto &GPUs = *GPUsOrErr;
814 if (llvm::SmallSet<std::string, 1>(GPUs.begin(), GPUs.end()).size() > 1)
815 getDriver().Diag(diag::warn_drv_multi_gpu_arch)
816 <<
getArchName() << llvm::join(GPUs,
", ") <<
"-march";
817 DAL->AddJoinedArg(
nullptr, Opts.getOption(options::OPT_march_EQ),
818 Args.MakeArgString(GPUs.front()));
826 const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
830 ArgStringList &CC1Args)
const {
831 if (DriverArgs.hasArg(options::OPT_nostdinc) ||
832 DriverArgs.hasArg(options::OPT_nostdlibinc))
841 llvm::sys::path::append(Dir, M.includeSuffix());
852 const Option &O = A->getOption();
853 return (O.matches(options::OPT_gN_Group) &&
854 !O.matches(options::OPT_gmodules)) ||
855 O.matches(options::OPT_g_Flag) ||
856 O.matches(options::OPT_ggdbN_Group) || O.matches(options::OPT_ggdb) ||
857 O.matches(options::OPT_gdwarf) || O.matches(options::OPT_gdwarf_2) ||
858 O.matches(options::OPT_gdwarf_3) || O.matches(options::OPT_gdwarf_4) ||
859 O.matches(options::OPT_gdwarf_5) ||
860 O.matches(options::OPT_gcolumn_info);
864 llvm::codegenoptions::DebugInfoKind &DebugInfoKind,
865 const ArgList &Args)
const {
867 case DisableDebugInfo:
868 DebugInfoKind = llvm::codegenoptions::NoDebugInfo;
870 case DebugDirectivesOnly:
871 DebugInfoKind = llvm::codegenoptions::DebugDirectivesOnly;
873 case EmitSameDebugInfoAsHost:
883 if (Arg *A = Args.getLastArg(options::OPT_offload_arch_tool_EQ))
884 Program = A->getValue();
888 auto StdoutOrErr =
getDriver().executeProgram({Program});
890 return StdoutOrErr.takeError();
893 for (StringRef
Arch : llvm::split((*StdoutOrErr)->getBuffer(),
"\n"))
895 GPUArchs.push_back(
Arch.str());
897 if (GPUArchs.empty())
898 return llvm::createStringError(std::error_code(),
899 "No NVIDIA GPU detected in the system");
901 return std::move(GPUArchs);
913 const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
915 HostTC.addClangTargetOptions(DriverArgs, CC1Args, BA, DeviceOffloadingKind);
917 bool UsesLLVMOffloading = DriverArgs.hasFlag(
918 options::OPT_foffload_via_llvm, options::OPT_fno_offload_via_llvm,
false);
920 StringRef GpuArch = DriverArgs.getLastArgValue(options::OPT_march_EQ);
923 "Only OpenMP or CUDA offloading kinds are supported for NVIDIA GPUs.");
925 CC1Args.append({
"-fcuda-is-device",
"-fno-threadsafe-statics"});
927 if (DriverArgs.hasFlag(options::OPT_fcuda_short_ptr,
928 options::OPT_fno_cuda_short_ptr,
false))
929 CC1Args.append({
"-target-abi",
"shortptr"});
931 if (!DriverArgs.hasFlag(options::OPT_offloadlib, options::OPT_no_offloadlib,
936 DriverArgs.hasArg(options::OPT_S))
939 if (UsesLLVMOffloading)
943 if (LibDeviceFile.empty()) {
944 getDriver().
Diag(diag::err_drv_no_cuda_libdevice) << GpuArch;
948 CC1Args.push_back(
"-mlink-builtin-bitcode");
949 CC1Args.push_back(DriverArgs.MakeArgString(LibDeviceFile));
955 DriverArgs.MakeArgString(Twine(
"-target-sdk-version=") +
961 diag::err_drv_omp_offload_target_cuda_version_not_support)
967 if (
isUsingLTO(DriverArgs, DeviceOffloadingKind))
976 const llvm::opt::ArgList &DriverArgs,
const JobAction &JA,
977 const llvm::fltSemantics *FPType)
const {
979 if (FPType && FPType == &llvm::APFloat::IEEEsingle() &&
980 DriverArgs.hasFlag(options::OPT_fgpu_flush_denormals_to_zero,
981 options::OPT_fno_gpu_flush_denormals_to_zero,
false))
982 return llvm::DenormalMode::getPreserveSign();
986 return llvm::DenormalMode::getIEEE();
990 ArgStringList &CC1Args)
const {
991 if (DriverArgs.hasFlag(options::OPT_foffload_via_llvm,
992 options::OPT_fno_offload_via_llvm,
false))
996 if (DriverArgs.hasFlag(options::OPT_offload_inc, options::OPT_no_offload_inc,
998 !DriverArgs.hasArg(options::OPT_no_cuda_version_check)) {
999 StringRef
Arch = DriverArgs.getLastArgValue(options::OPT_march_EQ);
1000 assert(!
Arch.empty() &&
"Must have an explicit GPU arch.");
1009 if (Input.
getType() != types::TY_Object ||
getDriver().offloadDeviceOnly())
1015llvm::opt::DerivedArgList *
1019 DerivedArgList *DAL =
HostTC.TranslateArgs(Args, BA, DeviceOffloadKind);
1021 DAL =
new DerivedArgList(Args.getBaseArgs());
1025 for (Arg *A : Args) {
1027 if (!llvm::is_contained(*DAL, A)) {
1033 DAL->eraseArg(options::OPT_march_EQ);
1034 DAL->AddJoinedArg(
nullptr, Opts.getOption(options::OPT_march_EQ),
1057 HostTC.addClangWarningOptions(CC1Args);
1062 return HostTC.GetCXXStdlibType(Args);
1066 ArgStringList &CC1Args)
const {
1067 if (DriverArgs.hasFlag(options::OPT_foffload_via_llvm,
1068 options::OPT_fno_offload_via_llvm,
false))
1071 HostTC.AddClangSystemIncludeArgs(DriverArgs, CC1Args);
1073 if (DriverArgs.hasFlag(options::OPT_offload_inc, options::OPT_no_offload_inc,
1077 {
"-internal-isystem",
1082 ArgStringList &CC1Args)
const {
1083 HostTC.AddClangCXXStdlibIncludeArgs(Args, CC1Args);
1087 ArgStringList &CC1Args)
const {
1088 HostTC.AddIAMCUIncludeArgs(Args, CC1Args);
1104 return HostTC.getSupportedSanitizers(BA, DeviceOffloadKind);
1108 const ArgList &Args)
const {
1109 return HostTC.computeMSVCVersion(D, Args);
static StringRef getTriple(const Command &Job)
A processor an offloading action can target.
static OffloadArch CudaDefault()
Default architectures used when the user does not specify one.
BoundArch getOffloadingArch() const
OffloadKind getOffloadingDeviceKind() const
bool isDeviceOffloading(OffloadKind OKind) const
bool isOffloading(OffloadKind OKind) const
Compilation - A set of tasks to perform for a single driver invocation.
A class to find a viable CUDA installation.
void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const
CudaInstallationDetector(const Driver &D, const llvm::Triple &HostTriple, const llvm::opt::ArgList &Args)
CudaVersion version() const
Get the detected Cuda install's version.
void WarnIfUnsupportedVersion() const
void CheckCudaVersionSupportsArch(OffloadArch Arch) const
Emit an error if Version does not support the given Arch.
void print(raw_ostream &OS) const
Print information about the detected CUDA installation.
StringRef getIncludePath() const
Get the detected Cuda Include path.
bool isValid() const
Check whether we detected a valid Cuda install.
Distro - Helper class for detecting and classifying Linux distributions.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
DiagnosticBuilder Diag(unsigned DiagID) const
const llvm::opt::OptTable & getOpts() const
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
SmallVector< InputInfo, 4 > InputInfoList
bool willEmitRemarks(const llvm::opt::ArgList &Args)
Top level wrappers for InstallAPI frontend operations.
CudaVersion MaxVersionForOffloadArch(OffloadArch A)
Get the latest CudaVersion that supports the given OffloadArch.
const char * CudaVersionToString(CudaVersion V)
OffloadArch StringToOffloadArch(llvm::StringRef S)
const char * OffloadArchToString(OffloadArch A)
CudaVersion MinVersionForOffloadArch(OffloadArch A)
Get the earliest CudaVersion that supports the given OffloadArch.
Diagnostic wrappers for TextAPI types for error reporting.
Represents a bound architecture for offload / multiple architecture compilation.
OffloadArch Arch
The parsed offload architecture.
static constexpr ResponseFileSupport AtFileUTF8()