12 #include "clang/Config/config.h"
19 #include "llvm/ADT/StringExtras.h"
20 #include "llvm/Option/ArgList.h"
21 #include "llvm/Support/FileSystem.h"
22 #include "llvm/Support/FormatAdapters.h"
23 #include "llvm/Support/FormatVariadic.h"
24 #include "llvm/Support/Path.h"
25 #include "llvm/Support/Process.h"
26 #include "llvm/Support/Program.h"
27 #include "llvm/Support/VirtualFileSystem.h"
28 #include "llvm/TargetParser/Host.h"
29 #include "llvm/TargetParser/TargetParser.h"
30 #include <system_error>
35 using namespace clang;
41 if (raw_version < 7050)
43 if (raw_version < 8000)
45 if (raw_version < 9000)
47 if (raw_version < 9010)
49 if (raw_version < 9020)
51 if (raw_version < 10000)
53 if (raw_version < 10010)
55 if (raw_version < 10020)
57 if (raw_version < 11000)
59 if (raw_version < 11010)
61 if (raw_version < 11020)
63 if (raw_version < 11030)
65 if (raw_version < 11040)
67 if (raw_version < 11050)
69 if (raw_version < 11060)
71 if (raw_version < 11070)
73 if (raw_version < 11080)
75 if (raw_version < 11090)
77 if (raw_version < 12010)
79 if (raw_version < 12020)
81 if (raw_version < 12030)
83 if (raw_version < 12040)
85 if (raw_version < 12050)
93 auto StartsWithWords =
94 [](llvm::StringRef Line,
96 for (StringRef word : words) {
97 if (!Line.consume_front(word))
104 Input = Input.ltrim();
105 while (!Input.empty()) {
107 StartsWithWords(Input.ltrim(), {
"#",
"define",
"CUDA_VERSION"})) {
109 Line->consumeInteger(10, RawVersion);
110 return getCudaVersion(RawVersion);
113 Input = Input.drop_front(Input.find_first_of(
"\n\r")).ltrim();
122 if (!VersionString.empty())
123 VersionString.insert(0,
" ");
124 D.Diag(diag::warn_drv_new_cuda_version)
129 D.Diag(diag::warn_drv_partially_supported_cuda_version)
134 const Driver &D,
const llvm::Triple &HostTriple,
135 const llvm::opt::ArgList &Args)
141 Candidate(std::string Path,
bool StrictChecking =
false)
142 : Path(Path), StrictChecking(StrictChecking) {}
147 std::initializer_list<const char *> Versions = {
148 "11.4",
"11.3",
"11.2",
"11.1",
"10.2",
"10.1",
"10.0",
149 "9.2",
"9.1",
"9.0",
"8.0",
"7.5",
"7.0"};
152 if (Args.hasArg(clang::driver::options::OPT_cuda_path_EQ)) {
153 Candidates.emplace_back(
154 Args.getLastArgValue(clang::driver::options::OPT_cuda_path_EQ).str());
155 }
else if (HostTriple.isOSWindows()) {
158 if (
const char *CudaPathEnvVar = ::getenv(
"CUDA_PATH"))
159 Candidates.emplace_back(CudaPathEnvVar);
161 for (
const char *Ver : Versions)
162 Candidates.emplace_back(
163 D.
SysRoot +
"/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v" +
166 if (!Args.hasArg(clang::driver::options::OPT_cuda_path_ignore_env)) {
175 if (llvm::ErrorOr<std::string> ptxas =
176 llvm::sys::findProgramByName(
"ptxas")) {
178 llvm::sys::fs::real_path(*ptxas, ptxasAbsolutePath);
180 StringRef ptxasDir = llvm::sys::path::parent_path(ptxasAbsolutePath);
181 if (llvm::sys::path::filename(ptxasDir) ==
"bin")
182 Candidates.emplace_back(
183 std::string(llvm::sys::path::parent_path(ptxasDir)),
188 Candidates.emplace_back(D.
SysRoot +
"/usr/local/cuda");
189 for (
const char *Ver : Versions)
190 Candidates.emplace_back(D.
SysRoot +
"/usr/local/cuda-" + Ver);
192 Distro Dist(FS, llvm::Triple(llvm::sys::getProcessTriple()));
196 Candidates.emplace_back(D.
SysRoot +
"/usr/lib/cuda");
199 bool NoCudaLib = Args.hasArg(options::OPT_nogpulib);
201 for (
const auto &Candidate : Candidates) {
202 InstallPath = Candidate.Path;
203 if (InstallPath.empty() || !FS.exists(InstallPath))
206 BinPath = InstallPath +
"/bin";
207 IncludePath = InstallPath +
"/include";
208 LibDevicePath = InstallPath +
"/nvvm/libdevice";
210 if (!(FS.exists(IncludePath) && FS.exists(BinPath)))
212 bool CheckLibDevice = (!NoCudaLib || Candidate.StrictChecking);
213 if (CheckLibDevice && !FS.exists(LibDevicePath))
217 if (
auto CudaHFile = FS.getBufferForFile(InstallPath +
"/include/cuda.h"))
218 Version = parseCudaHFile((*CudaHFile)->getBuffer());
222 Version = FS.exists(LibDevicePath +
"/libdevice.10.bc")
229 std::string FilePath = LibDevicePath +
"/libdevice.10.bc";
230 if (FS.exists(FilePath)) {
237 LibDeviceMap[GpuArchName] = FilePath;
242 for (llvm::vfs::directory_iterator LI = FS.dir_begin(LibDevicePath, EC),
244 !EC && LI !=
LE; LI = LI.increment(EC)) {
245 StringRef FilePath = LI->path();
246 StringRef
FileName = llvm::sys::path::filename(FilePath);
249 const StringRef LibDeviceName =
"libdevice.";
253 LibDeviceName.size(),
FileName.find(
'.', LibDeviceName.size()));
254 LibDeviceMap[GpuArch] = FilePath.str();
258 if (GpuArch ==
"compute_20") {
259 LibDeviceMap[
"sm_20"] = std::string(FilePath);
260 LibDeviceMap[
"sm_21"] = std::string(FilePath);
261 LibDeviceMap[
"sm_32"] = std::string(FilePath);
262 }
else if (GpuArch ==
"compute_30") {
263 LibDeviceMap[
"sm_30"] = std::string(FilePath);
265 LibDeviceMap[
"sm_50"] = std::string(FilePath);
266 LibDeviceMap[
"sm_52"] = std::string(FilePath);
267 LibDeviceMap[
"sm_53"] = std::string(FilePath);
269 LibDeviceMap[
"sm_60"] = std::string(FilePath);
270 LibDeviceMap[
"sm_61"] = std::string(FilePath);
271 LibDeviceMap[
"sm_62"] = std::string(FilePath);
272 }
else if (GpuArch ==
"compute_35") {
273 LibDeviceMap[
"sm_35"] = std::string(FilePath);
274 LibDeviceMap[
"sm_37"] = std::string(FilePath);
275 }
else if (GpuArch ==
"compute_50") {
277 LibDeviceMap[
"sm_50"] = std::string(FilePath);
278 LibDeviceMap[
"sm_52"] = std::string(FilePath);
279 LibDeviceMap[
"sm_53"] = std::string(FilePath);
287 if (LibDeviceMap.empty() && !NoCudaLib)
296 const ArgList &DriverArgs, ArgStringList &CC1Args)
const {
297 if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
301 llvm::sys::path::append(
P,
"include");
302 llvm::sys::path::append(
P,
"cuda_wrappers");
303 CC1Args.push_back(
"-internal-isystem");
304 CC1Args.push_back(DriverArgs.MakeArgString(
P));
307 if (DriverArgs.hasArg(options::OPT_nogpuinc))
311 D.
Diag(diag::err_drv_no_cuda_installation);
315 CC1Args.push_back(
"-include");
316 CC1Args.push_back(
"__clang_cuda_runtime_wrapper.h");
322 ArchsWithBadVersion[(
int)Arch])
327 if (Version < MinVersion || Version > MaxVersion) {
328 ArchsWithBadVersion[(
int)Arch] =
true;
329 D.
Diag(diag::err_drv_cuda_version_unsupported)
338 OS <<
"Found CUDA installation: " << InstallPath <<
", version "
348 enum DeviceDebugInfoLevel {
351 EmitSameDebugInfoAsHost,
365 const Arg *A = Args.getLastArg(options::OPT_O_Group);
366 bool IsDebugEnabled = !A || A->getOption().matches(options::OPT_O0) ||
367 Args.hasFlag(options::OPT_cuda_noopt_device_debug,
368 options::OPT_no_cuda_noopt_device_debug,
370 if (
const Arg *A = Args.getLastArg(options::OPT_g_Group)) {
371 const Option &Opt = A->getOption();
372 if (Opt.matches(options::OPT_gN_Group)) {
373 if (Opt.matches(options::OPT_g0) || Opt.matches(options::OPT_ggdb0))
374 return DisableDebugInfo;
375 if (Opt.matches(options::OPT_gline_directives_only))
376 return DebugDirectivesOnly;
378 return IsDebugEnabled ? EmitSameDebugInfoAsHost : DebugDirectivesOnly;
387 const char *LinkingOutput)
const {
390 assert(TC.getTriple().isNVPTX() &&
"Wrong platform");
392 StringRef GPUArchName;
400 GPUArchName = Args.getLastArgValue(options::OPT_march_EQ);
401 if (GPUArchName.empty()) {
402 C.getDriver().Diag(diag::err_drv_offload_missing_gpu_arch)
403 << getToolChain().getArchName() << getShortName();
411 "Device action expected to have an architecture.");
414 if (!Args.hasArg(options::OPT_no_cuda_version_check)) {
415 TC.CudaInstallation.CheckCudaVersionSupportsArch(gpu_arch);
418 ArgStringList CmdArgs;
419 CmdArgs.push_back(TC.getTriple().isArch64Bit() ?
"-m64" :
"-m32");
421 if (DIKind == EmitSameDebugInfoAsHost) {
424 CmdArgs.push_back(
"-g");
425 CmdArgs.push_back(
"--dont-merge-basicblocks");
426 CmdArgs.push_back(
"--return-at-end");
427 }
else if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
432 StringRef OOpt =
"3";
433 if (A->getOption().matches(options::OPT_O4) ||
434 A->getOption().matches(options::OPT_Ofast))
436 else if (A->getOption().matches(options::OPT_O0))
438 else if (A->getOption().matches(options::OPT_O)) {
440 OOpt = llvm::StringSwitch<const char *>(A->getValue())
448 CmdArgs.push_back(Args.MakeArgString(llvm::Twine(
"-O") + OOpt));
452 CmdArgs.push_back(
"-O3");
454 if (DIKind == DebugDirectivesOnly)
455 CmdArgs.push_back(
"-lineinfo");
458 if (Args.hasArg(options::OPT_v))
459 CmdArgs.push_back(
"-v");
461 CmdArgs.push_back(
"--gpu-name");
463 CmdArgs.push_back(
"--output-file");
464 std::string OutputFileName = TC.getInputFilename(Output);
468 if (!C.getInputArgs().getLastArg(options::OPT_c)) {
470 llvm::sys::path::replace_extension(
Filename,
"cubin");
474 C.addTempFile(Args.MakeArgString(OutputFileName));
476 CmdArgs.push_back(Args.MakeArgString(OutputFileName));
477 for (
const auto &II : Inputs)
478 CmdArgs.push_back(Args.MakeArgString(II.getFilename()));
480 for (
const auto &A : Args.getAllArgValues(options::OPT_Xcuda_ptxas))
481 CmdArgs.push_back(Args.MakeArgString(A));
486 Relocatable = Args.hasFlag(options::OPT_fopenmp_relocatable_target,
487 options::OPT_fnoopenmp_relocatable_target,
491 Relocatable = Args.hasFlag(options::OPT_fgpu_rdc, options::OPT_fno_gpu_rdc,
503 CmdArgs.push_back(
"-c");
506 if (Arg *A = Args.getLastArg(options::OPT_ptxas_path_EQ))
507 Exec = A->getValue();
509 Exec = Args.MakeArgString(TC.GetProgramPath(
"ptxas"));
510 C.addCommand(std::make_unique<Command>(
514 Exec, CmdArgs, Inputs, Output));
519 bool includePTX = !Args.hasFlag(options::OPT_offload_new_driver,
520 options::OPT_no_offload_new_driver,
false);
521 for (Arg *A : Args.filtered(options::OPT_cuda_include_ptx_EQ,
522 options::OPT_no_cuda_include_ptx_EQ)) {
524 const StringRef ArchStr = A->getValue();
525 if (A->getOption().matches(options::OPT_cuda_include_ptx_EQ) &&
526 (ArchStr ==
"all" || ArchStr == InputArch))
528 else if (A->getOption().matches(options::OPT_no_cuda_include_ptx_EQ) &&
529 (ArchStr ==
"all" || ArchStr == InputArch))
542 const char *LinkingOutput)
const {
545 assert(TC.getTriple().isNVPTX() &&
"Wrong platform");
547 ArgStringList CmdArgs;
549 CmdArgs.push_back(
"--cuda");
550 CmdArgs.push_back(TC.getTriple().isArch64Bit() ?
"-64" :
"-32");
551 CmdArgs.push_back(Args.MakeArgString(
"--create"));
552 CmdArgs.push_back(Args.MakeArgString(Output.
getFilename()));
554 CmdArgs.push_back(
"-g");
556 for (
const auto &II : Inputs) {
557 auto *A = II.getAction();
558 assert(A->getInputs().size() == 1 &&
559 "Device offload action is expected to have a single input");
560 const char *gpu_arch_str = A->getOffloadingArch();
561 assert(gpu_arch_str &&
562 "Device action expected to have associated a GPU architecture!");
565 if (II.getType() == types::TY_PP_Asm &&
570 const char *Arch = (II.getType() == types::TY_PP_Asm)
574 Args.MakeArgString(llvm::Twine(
"--image=profile=") + Arch +
575 ",file=" + getToolChain().getInputFilename(II)));
578 for (
const auto &A : Args.getAllArgValues(options::OPT_Xcuda_fatbinary))
579 CmdArgs.push_back(Args.MakeArgString(A));
581 const char *Exec = Args.MakeArgString(TC.GetProgramPath(
"fatbinary"));
582 C.addCommand(std::make_unique<Command>(
586 Exec, CmdArgs, Inputs, Output));
593 const char *LinkingOutput)
const {
596 assert(TC.getTriple().isNVPTX() &&
"Wrong platform");
598 ArgStringList CmdArgs;
603 "CUDA toolchain not expected for an OpenMP host device.");
606 CmdArgs.push_back(
"-o");
609 assert(Output.
isNothing() &&
"Invalid output.");
611 CmdArgs.push_back(
"-g");
613 if (Args.hasArg(options::OPT_v))
614 CmdArgs.push_back(
"-v");
617 Args.getLastArgValue(options::OPT_march_EQ);
618 assert(!GPUArch.empty() &&
"At least one GPU Arch required for ptxas.");
620 CmdArgs.push_back(
"-arch");
621 CmdArgs.push_back(Args.MakeArgString(GPUArch));
628 llvm::sys::path::parent_path(TC.getDriver().Dir);
629 llvm::sys::path::append(DefaultLibPath, CLANG_INSTALL_LIBDIR_BASENAME);
630 CmdArgs.push_back(Args.MakeArgString(Twine(
"-L") + DefaultLibPath));
632 for (
const auto &II : Inputs) {
633 if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR ||
634 II.getType() == types::TY_LTO_BC || II.getType() == types::TY_LLVM_BC) {
635 C.getDriver().Diag(diag::err_drv_no_linker_llvm_support)
636 << getToolChain().getTripleString();
642 if (!II.isFilename())
646 C.getArgs().MakeArgString(getToolChain().getInputFilename(II));
648 CmdArgs.push_back(CubinF);
656 CmdArgs.push_back(Args.MakeArgString(
657 Twine(
"--nvlink-path=" + getToolChain().GetProgramPath(
"nvlink"))));
660 Args.MakeArgString(getToolChain().GetProgramPath(
"clang-nvlink-wrapper"));
661 C.addCommand(std::make_unique<Command>(
665 Exec, CmdArgs, Inputs, Output));
672 const char *LinkingOutput)
const {
675 ArgStringList CmdArgs;
677 assert(TC.getTriple().isNVPTX() &&
"Wrong platform");
681 CmdArgs.push_back(
"-o");
686 CmdArgs.push_back(
"-g");
688 if (Args.hasArg(options::OPT_v))
689 CmdArgs.push_back(
"-v");
691 StringRef GPUArch = Args.getLastArgValue(options::OPT_march_EQ);
692 if (GPUArch.empty()) {
693 C.getDriver().Diag(diag::err_drv_offload_missing_gpu_arch)
694 << getToolChain().getArchName() << getShortName();
698 CmdArgs.push_back(
"-arch");
699 CmdArgs.push_back(Args.MakeArgString(GPUArch));
705 Args.AddAllArgs(CmdArgs, options::OPT_L);
706 getToolChain().AddFilePathLibArgs(Args, CmdArgs);
710 llvm::sys::path::parent_path(TC.getDriver().Dir);
711 llvm::sys::path::append(DefaultLibPath, CLANG_INSTALL_LIBDIR_BASENAME);
712 CmdArgs.push_back(Args.MakeArgString(Twine(
"-L") + DefaultLibPath));
714 for (
const auto &II : Inputs) {
715 if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR ||
716 II.getType() == types::TY_LTO_BC || II.getType() == types::TY_LLVM_BC) {
717 C.getDriver().Diag(diag::err_drv_no_linker_llvm_support)
718 << getToolChain().getTripleString();
726 if (II.isFilename()) {
727 auto InputFile = getToolChain().getInputFilename(II);
728 if (llvm::sys::path::extension(InputFile) !=
".cubin") {
732 if (II.getAction() && II.getAction()->getInputs().size() == 0) {
734 Args.MakeArgString(getToolChain().getDriver().GetTemporaryPath(
735 llvm::sys::path::stem(InputFile),
"cubin"));
736 if (llvm::sys::fs::copy_file(InputFile, C.addTempFile(CubinF)))
739 CmdArgs.push_back(CubinF);
742 llvm::sys::path::replace_extension(
Filename,
"cubin");
743 CmdArgs.push_back(Args.MakeArgString(
Filename));
746 CmdArgs.push_back(Args.MakeArgString(InputFile));
748 }
else if (!II.isNothing()) {
749 II.getInputArg().renderAsInput(Args, CmdArgs);
753 C.addCommand(std::make_unique<Command>(
757 Args.MakeArgString(getToolChain().GetProgramPath(
"nvlink")), CmdArgs,
762 const llvm::opt::ArgList &Args,
763 std::vector<StringRef> &Features) {
764 if (Args.hasArg(options::OPT_cuda_feature_EQ)) {
765 StringRef PtxFeature =
766 Args.getLastArgValue(options::OPT_cuda_feature_EQ,
"+ptx42");
767 Features.push_back(Args.MakeArgString(PtxFeature));
775 const char *PtxFeature =
nullptr;
776 switch (CudaInstallation.
version()) {
777 #define CASE_CUDA_VERSION(CUDA_VER, PTX_VER) \
778 case CudaVersion::CUDA_##CUDA_VER: \
779 PtxFeature = "+ptx" #PTX_VER; \
801 #undef CASE_CUDA_VERSION
803 PtxFeature =
"+ptx42";
805 Features.push_back(PtxFeature);
811 NVPTXToolChain::NVPTXToolChain(
const Driver &D,
const llvm::Triple &Triple,
812 const llvm::Triple &HostTriple,
813 const ArgList &Args,
bool Freestanding =
false)
814 :
ToolChain(D, Triple, Args), CudaInstallation(D, HostTriple, Args),
815 Freestanding(Freestanding) {
816 if (CudaInstallation.isValid())
817 getProgramPaths().push_back(std::string(CudaInstallation.getBinPath()));
820 getProgramPaths().push_back(getDriver().Dir);
825 NVPTXToolChain::NVPTXToolChain(
const Driver &D,
const llvm::Triple &Triple,
830 llvm::opt::DerivedArgList *
831 NVPTXToolChain::TranslateArgs(
const llvm::opt::DerivedArgList &Args,
836 DAL =
new DerivedArgList(Args.getBaseArgs());
838 const OptTable &Opts = getDriver().getOpts();
841 if (!llvm::is_contained(*DAL, A))
844 if (!DAL->hasArg(options::OPT_march_EQ) && OffloadKind !=
Action::OFK_None) {
845 DAL->AddJoinedArg(
nullptr, Opts.getOption(options::OPT_march_EQ),
847 }
else if (DAL->getLastArgValue(options::OPT_march_EQ) ==
"generic" &&
849 DAL->eraseArg(options::OPT_march_EQ);
850 }
else if (DAL->getLastArgValue(options::OPT_march_EQ) ==
"native") {
851 auto GPUsOrErr = getSystemGPUArchs(Args);
853 getDriver().Diag(diag::err_drv_undetermined_gpu_arch)
854 << getArchName() <<
llvm::toString(GPUsOrErr.takeError()) <<
"-march";
856 if (GPUsOrErr->size() > 1)
857 getDriver().Diag(diag::warn_drv_multi_gpu_arch)
858 << getArchName() << llvm::join(*GPUsOrErr,
", ") <<
"-march";
859 DAL->AddJoinedArg(
nullptr, Opts.getOption(options::OPT_march_EQ),
860 Args.MakeArgString(GPUsOrErr->front()));
871 return "remangled-l32-signed_char.libspirv-nvptx64-nvidia-cuda.bc";
872 return "remangled-l64-signed_char.libspirv-nvptx64-nvidia-cuda.bc";
875 void NVPTXToolChain::addClangTargetOptions(
876 const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
882 CC1Args.append({
"-mllvm",
"--nvptx-lower-global-ctor-dtor"});
885 bool NVPTXToolChain::supportsDebugInfoOption(
const llvm::opt::Arg *A)
const {
886 const Option &O = A->getOption();
887 return (O.matches(options::OPT_gN_Group) &&
888 !O.matches(options::OPT_gmodules)) ||
889 O.matches(options::OPT_g_Flag) ||
890 O.matches(options::OPT_ggdbN_Group) || O.matches(options::OPT_ggdb) ||
891 O.matches(options::OPT_gdwarf) || O.matches(options::OPT_gdwarf_2) ||
892 O.matches(options::OPT_gdwarf_3) || O.matches(options::OPT_gdwarf_4) ||
893 O.matches(options::OPT_gdwarf_5) ||
894 O.matches(options::OPT_gcolumn_info);
897 void NVPTXToolChain::adjustDebugInfoKind(
898 llvm::codegenoptions::DebugInfoKind &DebugInfoKind,
899 const ArgList &Args)
const {
901 case DisableDebugInfo:
902 DebugInfoKind = llvm::codegenoptions::NoDebugInfo;
904 case DebugDirectivesOnly:
905 DebugInfoKind = llvm::codegenoptions::DebugDirectivesOnly;
907 case EmitSameDebugInfoAsHost:
914 NVPTXToolChain::getSystemGPUArchs(
const ArgList &Args)
const {
917 if (Arg *A = Args.getLastArg(options::OPT_nvptx_arch_tool_EQ))
918 Program = A->getValue();
920 Program = GetProgramPath(
"nvptx-arch");
922 auto StdoutOrErr = executeToolChainProgram(Program);
924 return StdoutOrErr.takeError();
927 for (StringRef Arch : llvm::split((*StdoutOrErr)->getBuffer(),
"\n"))
929 GPUArchs.push_back(Arch.str());
931 if (GPUArchs.empty())
932 return llvm::createStringError(std::error_code(),
933 "No NVIDIA GPU detected in the system");
935 return std::move(GPUArchs);
942 CudaToolChain::CudaToolChain(
const Driver &D,
const llvm::Triple &Triple,
943 const ToolChain &HostTC,
const ArgList &Args,
945 :
NVPTXToolChain(D, Triple, HostTC.getTriple(), Args), HostTC(HostTC),
949 const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args,
953 StringRef GpuArch = DriverArgs.getLastArgValue(options::OPT_march_EQ);
954 assert(!GpuArch.empty() &&
"Must have an explicit GPU arch.");
958 "Only OpenMP, SYCL or CUDA offloading kinds are supported for NVIDIA GPUs.");
962 {
"-fcuda-is-device",
"-mllvm",
"-enable-memcpyopt-without-libcalls"});
969 CC1Args.push_back(
"-fcuda-allow-variadic-functions");
971 if (DriverArgs.hasArg(options::OPT_fsycl)) {
973 CC1Args.append({
"-std=c++17",
"-fsycl-is-host"});
981 if (DriverArgs.hasArg(options::OPT_fsycl_fp32_prec_sqrt)) {
982 CC1Args.push_back(
"-fcuda-prec-sqrt");
986 auto NoLibSpirv = DriverArgs.hasArg(options::OPT_fno_sycl_libspirv) ||
989 std::string LibSpirvFile;
991 if (DriverArgs.hasArg(clang::driver::options::OPT_fsycl_libspirv_path_EQ)) {
993 DriverArgs.getLastArgValue(clang::driver::options::OPT_fsycl_libspirv_path_EQ).str();
994 if (llvm::sys::fs::exists(ProvidedPath))
995 LibSpirvFile = ProvidedPath;
1001 llvm::sys::path::append(WithoutInstallPath, Twine(
"../../clc"));
1002 LibraryPaths.emplace_back(WithoutInstallPath.c_str());
1006 llvm::sys::path::append(WithInstallPath, Twine(
"../../../share/clc"));
1007 LibraryPaths.emplace_back(WithInstallPath.c_str());
1012 for (StringRef LibraryPath : LibraryPaths) {
1014 llvm::sys::path::append(LibSpirvTargetFile, LibSpirvTargetName);
1015 if (llvm::sys::fs::exists(LibSpirvTargetFile) ||
1016 DriverArgs.hasArg(options::OPT__HASH_HASH_HASH)) {
1017 LibSpirvFile = std::string(LibSpirvTargetFile.str());
1023 if (LibSpirvFile.empty()) {
1029 CC1Args.push_back(
"-mlink-builtin-bitcode");
1030 CC1Args.push_back(DriverArgs.MakeArgString(LibSpirvFile));
1033 if (DriverArgs.hasArg(options::OPT_nogpulib))
1037 DriverArgs.hasArg(options::OPT_S))
1041 if (LibDeviceFile.empty()) {
1042 getDriver().
Diag(diag::err_drv_no_cuda_libdevice) << GpuArch;
1046 CC1Args.push_back(
"-mlink-builtin-bitcode");
1047 CC1Args.push_back(DriverArgs.MakeArgString(LibDeviceFile));
1051 if (DriverArgs.hasFlag(options::OPT_fcuda_short_ptr,
1052 options::OPT_fno_cuda_short_ptr,
false))
1053 CC1Args.append({
"-mllvm",
"--nvptx-short-ptr"});
1057 DriverArgs.MakeArgString(Twine(
"-target-sdk-version=") +
1063 diag::err_drv_omp_offload_target_cuda_version_not_support)
1081 const llvm::opt::ArgList &DriverArgs,
const JobAction &JA,
1082 const llvm::fltSemantics *FPType)
const {
1084 if (FPType && FPType == &llvm::APFloat::IEEEsingle() &&
1085 DriverArgs.hasFlag(options::OPT_fgpu_flush_denormals_to_zero,
1086 options::OPT_fno_gpu_flush_denormals_to_zero,
false))
1087 return llvm::DenormalMode::getPreserveSign();
1091 return llvm::DenormalMode::getIEEE();
1095 ArgStringList &CC1Args)
const {
1097 if (!DriverArgs.hasArg(options::OPT_nogpuinc) &&
1098 !DriverArgs.hasArg(options::OPT_no_cuda_version_check)) {
1099 StringRef Arch = DriverArgs.getLastArgValue(options::OPT_march_EQ);
1100 assert(!Arch.empty() &&
"Must have an explicit GPU arch.");
1109 if (Input.
getType() != types::TY_Object ||
getDriver().offloadDeviceOnly())
1115 llvm::sys::path::replace_extension(
Filename,
"cubin");
1119 llvm::opt::DerivedArgList *
1121 StringRef BoundArch,
1123 DerivedArgList *DAL =
1126 DAL =
new DerivedArgList(Args.getBaseArgs());
1135 if (!llvm::is_contained(*DAL, A))
1138 if (!DAL->hasArg(options::OPT_march_EQ)) {
1139 StringRef Arch = BoundArch;
1143 std::string ErrMsg =
1144 llvm::formatv(
"{0}", llvm::fmt_consume(ArchsOrErr.takeError()));
1146 << llvm::Triple::getArchTypeName(
getArch()) << ErrMsg <<
"-march";
1149 Arch = Args.MakeArgString(ArchsOrErr->front());
1152 DAL->AddJoinedArg(
nullptr, Opts.getOption(options::OPT_march_EQ), Arch);
1158 for (Arg *A : Args) {
1160 if (!llvm::is_contained(*DAL, A)) {
1165 if (!BoundArch.empty()) {
1166 DAL->eraseArg(options::OPT_march_EQ);
1167 DAL->AddJoinedArg(
nullptr, Opts.getOption(options::OPT_march_EQ),
1196 JA.
getType() == types::TY_LLVM_BC) {
1198 ->GetSYCLToolChainLinker();
1214 ArgStringList &CC1Args)
const {
1215 if (DriverArgs.hasArg(options::OPT_fsycl)) {
1223 {
"-internal-isystem",
1228 ArgStringList &CC1Args)
const {
1233 ArgStringList &CC1Args)
const {
1251 const ArgList &Args)
const {
types::ID getType() const
ActionClass getKind() const
OffloadKind getOffloadingDeviceKind() const
bool isHostOffloading(unsigned int OKind) const
Check if this action have any offload kinds.
bool isDeviceOffloading(OffloadKind OKind) const
const char * getOffloadingArch() 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)
void WarnIfUnsupportedVersion()
CudaVersion version() const
Get the detected Cuda install's version.
std::string getLibDeviceFile(StringRef Gpu) const
Get libdevice file for given architecture.
void CheckCudaVersionSupportsArch(CudaArch 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...
std::string SysRoot
sysroot, if present
bool offloadDeviceOnly() const
llvm::vfs::FileSystem & getVFS() const
DiagnosticBuilder Diag(unsigned DiagID) const
const llvm::opt::OptTable & getOpts() const
std::string ResourceDir
The path to the compiler resource directory.
bool willEmitRemarks(const llvm::opt::ArgList &Args)
bool LE(InterpState &S, CodePtr OpPC)
std::string toString(const til::SExpr *E)
The JSON file list parser is used to communicate input to InstallAPI.
const char * CudaArchToVirtualArchString(CudaArch A)
CudaVersion MaxVersionForCudaArch(CudaArch A)
Get the latest CudaVersion that supports the given CudaArch.
CudaArch StringToCudaArch(llvm::StringRef S)
CudaVersion MinVersionForCudaArch(CudaArch A)
Get the earliest CudaVersion that supports the given CudaArch.
static bool IsNVIDIAGpuArch(CudaArch A)
const char * CudaVersionToString(CudaVersion V)
const char * CudaArchToString(CudaArch A)
Diagnostic wrappers for TextAPI types for error reporting.