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 } // end namespace NVPTX 128 } // end namespace tools 129 130 namespace toolchains { 131 132 class LLVM_LIBRARY_VISIBILITY CudaToolChain : public ToolChain { 133 public: 134 CudaToolChain(const Driver &D, const llvm::Triple &Triple, 135 const ToolChain &HostTC, const llvm::opt::ArgList &Args, 136 const Action::OffloadKind OK); 137 138 const llvm::Triple *getAuxTriple() const override { 139 return &HostTC.getTriple(); 140 } 141 142 std::string getInputFilename(const InputInfo &Input) const override; 143 144 llvm::opt::DerivedArgList * 145 TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, 146 Action::OffloadKind DeviceOffloadKind) const override; 147 void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 148 llvm::opt::ArgStringList &CC1Args, 149 Action::OffloadKind DeviceOffloadKind) const override; 150 151 llvm::DenormalMode getDefaultDenormalModeForType( 152 const llvm::opt::ArgList &DriverArgs, const JobAction &JA, 153 const llvm::fltSemantics *FPType = nullptr) const override; 154 155 // Never try to use the integrated assembler with CUDA; always fork out to 156 // ptxas. 157 bool useIntegratedAs() const override { return false; } 158 bool isCrossCompiling() const override { return true; } 159 bool isPICDefault() const override { return false; } 160 bool isPIEDefault(const llvm::opt::ArgList &Args) const override { 161 return false; 162 } 163 bool isPICDefaultForced() const override { return false; } 164 bool SupportsProfiling() const override { return false; } 165 bool supportsDebugInfoOption(const llvm::opt::Arg *A) const override; 166 void adjustDebugInfoKind(codegenoptions::DebugInfoKind &DebugInfoKind, 167 const llvm::opt::ArgList &Args) const override; 168 bool IsMathErrnoDefault() const override { return false; } 169 170 void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, 171 llvm::opt::ArgStringList &CC1Args) const override; 172 173 void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override; 174 CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; 175 void 176 AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, 177 llvm::opt::ArgStringList &CC1Args) const override; 178 void AddClangCXXStdlibIncludeArgs( 179 const llvm::opt::ArgList &Args, 180 llvm::opt::ArgStringList &CC1Args) const override; 181 void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs, 182 llvm::opt::ArgStringList &CC1Args) const override; 183 184 SanitizerMask getSupportedSanitizers() const override; 185 186 VersionTuple 187 computeMSVCVersion(const Driver *D, 188 const llvm::opt::ArgList &Args) const override; 189 190 unsigned GetDefaultDwarfVersion() const override { return 2; } 191 // NVPTX supports only DWARF2. 192 unsigned getMaxDwarfVersion() const override { return 2; } 193 194 const ToolChain &HostTC; 195 CudaInstallationDetector CudaInstallation; 196 197 protected: 198 Tool *buildAssembler() const override; // ptxas 199 Tool *buildLinker() const override; // fatbinary (ok, not really a linker) 200 201 private: 202 const Action::OffloadKind OK; 203 }; 204 205 } // end namespace toolchains 206 } // end namespace driver 207 } // end namespace clang 208 209 #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_CUDA_H 210