1 //===--- Cuda.h - Cuda ToolChain Implementations ----------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_CUDA_H 10 #define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_CUDA_H 11 12 #include "clang/Basic/Cuda.h" 13 #include "clang/Driver/Action.h" 14 #include "clang/Driver/Multilib.h" 15 #include "clang/Driver/Tool.h" 16 #include "clang/Driver/ToolChain.h" 17 #include "llvm/ADT/Optional.h" 18 #include "llvm/ADT/SmallSet.h" 19 #include "llvm/Support/Compiler.h" 20 #include "llvm/Support/VersionTuple.h" 21 #include <set> 22 #include <vector> 23 24 namespace clang { 25 namespace driver { 26 27 /// A class to find a viable CUDA installation 28 class CudaInstallationDetector { 29 private: 30 const Driver &D; 31 bool IsValid = false; 32 CudaVersion Version = CudaVersion::UNKNOWN; 33 std::string DetectedVersion; 34 bool DetectedVersionIsNotSupported = false; 35 std::string InstallPath; 36 std::string BinPath; 37 std::string LibPath; 38 std::string LibDevicePath; 39 std::string IncludePath; 40 llvm::StringMap<std::string> LibDeviceMap; 41 42 // CUDA architectures for which we have raised an error in 43 // CheckCudaVersionSupportsArch. 44 mutable llvm::SmallSet<CudaArch, 4> ArchsWithBadVersion; 45 46 public: 47 CudaInstallationDetector(const Driver &D, const llvm::Triple &HostTriple, 48 const llvm::opt::ArgList &Args); 49 50 void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, 51 llvm::opt::ArgStringList &CC1Args) const; 52 53 /// Emit an error if Version does not support the given Arch. 54 /// 55 /// If either Version or Arch is unknown, does not emit an error. Emits at 56 /// most one error per Arch. 57 void CheckCudaVersionSupportsArch(CudaArch Arch) const; 58 59 /// Check whether we detected a valid Cuda install. 60 bool isValid() const { return IsValid; } 61 /// Print information about the detected CUDA installation. 62 void print(raw_ostream &OS) const; 63 64 /// Get the detected Cuda install's version. 65 CudaVersion version() const { return Version; } 66 /// Get the detected Cuda installation path. 67 StringRef getInstallPath() const { return InstallPath; } 68 /// Get the detected path to Cuda's bin directory. 69 StringRef getBinPath() const { return BinPath; } 70 /// Get the detected Cuda Include path. 71 StringRef getIncludePath() const { return IncludePath; } 72 /// Get the detected Cuda library path. 73 StringRef getLibPath() const { return LibPath; } 74 /// Get the detected Cuda device library path. 75 StringRef getLibDevicePath() const { return LibDevicePath; } 76 /// Get libdevice file for given architecture 77 std::string getLibDeviceFile(StringRef Gpu) const { 78 return LibDeviceMap.lookup(Gpu); 79 } 80 void WarnIfUnsupportedVersion(); 81 }; 82 83 namespace tools { 84 namespace NVPTX { 85 86 // Run ptxas, the NVPTX assembler. 87 class LLVM_LIBRARY_VISIBILITY Assembler : public Tool { 88 public: 89 Assembler(const ToolChain &TC) : Tool("NVPTX::Assembler", "ptxas", TC) {} 90 91 bool hasIntegratedCPP() const override { return false; } 92 93 void ConstructJob(Compilation &C, const JobAction &JA, 94 const InputInfo &Output, const InputInfoList &Inputs, 95 const llvm::opt::ArgList &TCArgs, 96 const char *LinkingOutput) const override; 97 }; 98 99 // Runs fatbinary, which combines GPU object files ("cubin" files) and/or PTX 100 // assembly into a single output file. 101 class LLVM_LIBRARY_VISIBILITY Linker : public Tool { 102 public: 103 Linker(const ToolChain &TC) : Tool("NVPTX::Linker", "fatbinary", TC) {} 104 105 bool hasIntegratedCPP() const override { return false; } 106 107 void ConstructJob(Compilation &C, const JobAction &JA, 108 const InputInfo &Output, const InputInfoList &Inputs, 109 const llvm::opt::ArgList &TCArgs, 110 const char *LinkingOutput) const override; 111 }; 112 113 class LLVM_LIBRARY_VISIBILITY OpenMPLinker : public Tool { 114 public: 115 OpenMPLinker(const ToolChain &TC) 116 : Tool("NVPTX::OpenMPLinker", "nvlink", TC) {} 117 118 bool hasIntegratedCPP() const override { return false; } 119 120 void ConstructJob(Compilation &C, const JobAction &JA, 121 const InputInfo &Output, const InputInfoList &Inputs, 122 const llvm::opt::ArgList &TCArgs, 123 const char *LinkingOutput) const override; 124 }; 125 126 } // end namespace NVPTX 127 } // end namespace tools 128 129 namespace toolchains { 130 131 class LLVM_LIBRARY_VISIBILITY CudaToolChain : public ToolChain { 132 public: 133 CudaToolChain(const Driver &D, const llvm::Triple &Triple, 134 const ToolChain &HostTC, const llvm::opt::ArgList &Args, 135 const Action::OffloadKind OK); 136 137 const llvm::Triple *getAuxTriple() const override { 138 return &HostTC.getTriple(); 139 } 140 141 std::string getInputFilename(const InputInfo &Input) const override; 142 143 llvm::opt::DerivedArgList * 144 TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, 145 Action::OffloadKind DeviceOffloadKind) const override; 146 void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 147 llvm::opt::ArgStringList &CC1Args, 148 Action::OffloadKind DeviceOffloadKind) const override; 149 150 llvm::DenormalMode getDefaultDenormalModeForType( 151 const llvm::opt::ArgList &DriverArgs, const JobAction &JA, 152 const llvm::fltSemantics *FPType = nullptr) const override; 153 154 // Never try to use the integrated assembler with CUDA; always fork out to 155 // ptxas. 156 bool useIntegratedAs() const override { return false; } 157 bool isCrossCompiling() const override { return true; } 158 bool isPICDefault() const override { return false; } 159 bool isPIEDefault() const override { return false; } 160 bool isPICDefaultForced() const override { return false; } 161 bool SupportsProfiling() const override { return false; } 162 bool supportsDebugInfoOption(const llvm::opt::Arg *A) const override; 163 void adjustDebugInfoKind(codegenoptions::DebugInfoKind &DebugInfoKind, 164 const llvm::opt::ArgList &Args) const override; 165 bool IsMathErrnoDefault() const override { return false; } 166 167 void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, 168 llvm::opt::ArgStringList &CC1Args) const override; 169 170 void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override; 171 CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; 172 void 173 AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, 174 llvm::opt::ArgStringList &CC1Args) const override; 175 void AddClangCXXStdlibIncludeArgs( 176 const llvm::opt::ArgList &Args, 177 llvm::opt::ArgStringList &CC1Args) const override; 178 void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs, 179 llvm::opt::ArgStringList &CC1Args) const override; 180 181 SanitizerMask getSupportedSanitizers() const override; 182 183 VersionTuple 184 computeMSVCVersion(const Driver *D, 185 const llvm::opt::ArgList &Args) const override; 186 187 unsigned GetDefaultDwarfVersion() const override { return 2; } 188 189 const ToolChain &HostTC; 190 CudaInstallationDetector CudaInstallation; 191 192 protected: 193 Tool *buildAssembler() const override; // ptxas 194 Tool *buildLinker() const override; // fatbinary (ok, not really a linker) 195 196 private: 197 const Action::OffloadKind OK; 198 }; 199 200 } // end namespace toolchains 201 } // end namespace driver 202 } // end namespace clang 203 204 #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_CUDA_H 205