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