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/Support/Compiler.h" 18 #include "llvm/Support/VersionTuple.h" 19 #include <bitset> 20 #include <set> 21 #include <vector> 22 23 namespace clang { 24 namespace driver { 25 26 /// A class to find a viable CUDA installation 27 class CudaInstallationDetector { 28 private: 29 const Driver &D; 30 bool IsValid = false; 31 CudaVersion Version = CudaVersion::UNKNOWN; 32 std::string InstallPath; 33 std::string BinPath; 34 std::string LibDevicePath; 35 std::string IncludePath; 36 llvm::StringMap<std::string> LibDeviceMap; 37 38 // CUDA architectures for which we have raised an error in 39 // CheckCudaVersionSupportsArch. 40 mutable std::bitset<(int)CudaArch::LAST> ArchsWithBadVersion; 41 42 public: 43 CudaInstallationDetector(const Driver &D, const llvm::Triple &HostTriple, 44 const llvm::opt::ArgList &Args); 45 46 void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, 47 llvm::opt::ArgStringList &CC1Args) const; 48 49 /// Emit an error if Version does not support the given Arch. 50 /// 51 /// If either Version or Arch is unknown, does not emit an error. Emits at 52 /// most one error per Arch. 53 void CheckCudaVersionSupportsArch(CudaArch Arch) const; 54 55 /// Check whether we detected a valid Cuda install. 56 bool isValid() const { return IsValid; } 57 /// Print information about the detected CUDA installation. 58 void print(raw_ostream &OS) const; 59 60 /// Get the detected Cuda install's version. 61 CudaVersion version() const { 62 return Version == CudaVersion::NEW ? CudaVersion::PARTIALLY_SUPPORTED 63 : Version; 64 } 65 /// Get the detected Cuda installation path. 66 StringRef getInstallPath() const { return InstallPath; } 67 /// Get the detected path to Cuda's bin directory. 68 StringRef getBinPath() const { return BinPath; } 69 /// Get the detected Cuda Include path. 70 StringRef getIncludePath() const { return IncludePath; } 71 /// Get the detected Cuda device library path. 72 StringRef getLibDevicePath() const { return LibDevicePath; } 73 /// Get libdevice file for given architecture 74 std::string getLibDeviceFile(StringRef Gpu) const { 75 return LibDeviceMap.lookup(Gpu); 76 } 77 void WarnIfUnsupportedVersion(); 78 }; 79 80 namespace tools { 81 namespace NVPTX { 82 83 // Run ptxas, the NVPTX assembler. 84 class LLVM_LIBRARY_VISIBILITY Assembler : public Tool { 85 public: 86 Assembler(const ToolChain &TC) : Tool("NVPTX::Assembler", "ptxas", TC) {} 87 88 bool hasIntegratedCPP() const override { return false; } 89 90 void ConstructJob(Compilation &C, const JobAction &JA, 91 const InputInfo &Output, const InputInfoList &Inputs, 92 const llvm::opt::ArgList &TCArgs, 93 const char *LinkingOutput) const override; 94 }; 95 96 // Runs fatbinary, which combines GPU object files ("cubin" files) and/or PTX 97 // assembly into a single output file. 98 class LLVM_LIBRARY_VISIBILITY FatBinary : public Tool { 99 public: 100 FatBinary(const ToolChain &TC) : Tool("NVPTX::Linker", "fatbinary", TC) {} 101 102 bool hasIntegratedCPP() const override { return false; } 103 104 void ConstructJob(Compilation &C, const JobAction &JA, 105 const InputInfo &Output, const InputInfoList &Inputs, 106 const llvm::opt::ArgList &TCArgs, 107 const char *LinkingOutput) const override; 108 }; 109 110 // Runs nvlink, which links GPU object files ("cubin" files) into a single file. 111 class LLVM_LIBRARY_VISIBILITY Linker : public Tool { 112 public: 113 Linker(const ToolChain &TC) : Tool("NVPTX::Linker", "fatbinary", TC) {} 114 115 bool hasIntegratedCPP() const override { return false; } 116 117 void ConstructJob(Compilation &C, const JobAction &JA, 118 const InputInfo &Output, const InputInfoList &Inputs, 119 const llvm::opt::ArgList &TCArgs, 120 const char *LinkingOutput) const override; 121 }; 122 123 void getNVPTXTargetFeatures(const Driver &D, const llvm::Triple &Triple, 124 const llvm::opt::ArgList &Args, 125 std::vector<StringRef> &Features); 126 127 } // end namespace NVPTX 128 } // end namespace tools 129 130 namespace toolchains { 131 132 class LLVM_LIBRARY_VISIBILITY NVPTXToolChain : public ToolChain { 133 public: 134 NVPTXToolChain(const Driver &D, const llvm::Triple &Triple, 135 const llvm::Triple &HostTriple, const llvm::opt::ArgList &Args, 136 bool Freestanding); 137 138 NVPTXToolChain(const Driver &D, const llvm::Triple &Triple, 139 const llvm::opt::ArgList &Args); 140 141 llvm::opt::DerivedArgList * 142 TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, 143 Action::OffloadKind DeviceOffloadKind) const override; 144 145 void 146 addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 147 llvm::opt::ArgStringList &CC1Args, 148 Action::OffloadKind DeviceOffloadKind) const override; 149 150 // Never try to use the integrated assembler with CUDA; always fork out to 151 // ptxas. 152 bool useIntegratedAs() const override { return false; } 153 bool isCrossCompiling() const override { return true; } 154 bool isPICDefault() const override { return false; } 155 bool isPIEDefault(const llvm::opt::ArgList &Args) const override { 156 return false; 157 } 158 bool isPICDefaultForced() const override { return false; } 159 bool SupportsProfiling() const override { return false; } 160 161 bool IsMathErrnoDefault() const override { return false; } 162 163 bool supportsDebugInfoOption(const llvm::opt::Arg *A) const override; 164 void adjustDebugInfoKind(llvm::codegenoptions::DebugInfoKind &DebugInfoKind, 165 const llvm::opt::ArgList &Args) const override; 166 167 // NVPTX supports only DWARF2. 168 unsigned GetDefaultDwarfVersion() const override { return 2; } 169 unsigned getMaxDwarfVersion() const override { return 2; } 170 171 CudaInstallationDetector CudaInstallation; 172 173 protected: 174 Tool *buildAssembler() const override; // ptxas. 175 Tool *buildLinker() const override; // nvlink. 176 177 private: 178 bool Freestanding = false; 179 }; 180 181 class LLVM_LIBRARY_VISIBILITY CudaToolChain : public NVPTXToolChain { 182 public: 183 CudaToolChain(const Driver &D, const llvm::Triple &Triple, 184 const ToolChain &HostTC, const llvm::opt::ArgList &Args); 185 186 const llvm::Triple *getAuxTriple() const override { 187 return &HostTC.getTriple(); 188 } 189 190 std::string getInputFilename(const InputInfo &Input) const override; 191 192 llvm::opt::DerivedArgList * 193 TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, 194 Action::OffloadKind DeviceOffloadKind) const override; 195 void 196 addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 197 llvm::opt::ArgStringList &CC1Args, 198 Action::OffloadKind DeviceOffloadKind) const override; 199 200 llvm::DenormalMode getDefaultDenormalModeForType( 201 const llvm::opt::ArgList &DriverArgs, const JobAction &JA, 202 const llvm::fltSemantics *FPType = nullptr) const override; 203 204 void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, 205 llvm::opt::ArgStringList &CC1Args) const override; 206 207 void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override; 208 CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; 209 void 210 AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, 211 llvm::opt::ArgStringList &CC1Args) const override; 212 void AddClangCXXStdlibIncludeArgs( 213 const llvm::opt::ArgList &Args, 214 llvm::opt::ArgStringList &CC1Args) const override; 215 void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs, 216 llvm::opt::ArgStringList &CC1Args) const override; 217 218 SanitizerMask getSupportedSanitizers() const override; 219 220 VersionTuple 221 computeMSVCVersion(const Driver *D, 222 const llvm::opt::ArgList &Args) const override; 223 224 const ToolChain &HostTC; 225 226 /// Uses nvptx-arch tool to get arch of the system GPU. Will return error 227 /// if unable to find one. 228 virtual Expected<SmallVector<std::string>> 229 getSystemGPUArchs(const llvm::opt::ArgList &Args) const override; 230 231 protected: 232 Tool *buildAssembler() const override; // ptxas 233 Tool *buildLinker() const override; // fatbinary (ok, not really a linker) 234 }; 235 236 } // end namespace toolchains 237 } // end namespace driver 238 } // end namespace clang 239 240 #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_CUDA_H 241