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 private: 83 void ParseCudaVersionFile(llvm::StringRef V); 84 }; 85 86 namespace tools { 87 namespace NVPTX { 88 89 // Run ptxas, the NVPTX assembler. 90 class LLVM_LIBRARY_VISIBILITY Assembler : public Tool { 91 public: 92 Assembler(const ToolChain &TC) 93 : Tool("NVPTX::Assembler", "ptxas", TC, RF_Full, llvm::sys::WEM_UTF8, 94 "--options-file") {} 95 96 bool hasIntegratedCPP() const override { return false; } 97 98 void ConstructJob(Compilation &C, const JobAction &JA, 99 const InputInfo &Output, const InputInfoList &Inputs, 100 const llvm::opt::ArgList &TCArgs, 101 const char *LinkingOutput) const override; 102 }; 103 104 // Runs fatbinary, which combines GPU object files ("cubin" files) and/or PTX 105 // assembly into a single output file. 106 class LLVM_LIBRARY_VISIBILITY Linker : public Tool { 107 public: 108 Linker(const ToolChain &TC) 109 : Tool("NVPTX::Linker", "fatbinary", TC, RF_Full, llvm::sys::WEM_UTF8, 110 "--options-file") {} 111 112 bool hasIntegratedCPP() const override { return false; } 113 114 void ConstructJob(Compilation &C, const JobAction &JA, 115 const InputInfo &Output, const InputInfoList &Inputs, 116 const llvm::opt::ArgList &TCArgs, 117 const char *LinkingOutput) const override; 118 }; 119 120 class LLVM_LIBRARY_VISIBILITY OpenMPLinker : public Tool { 121 public: 122 OpenMPLinker(const ToolChain &TC) 123 : Tool("NVPTX::OpenMPLinker", "nvlink", TC, RF_Full, llvm::sys::WEM_UTF8, 124 "--options-file") {} 125 126 bool hasIntegratedCPP() const override { return false; } 127 128 void ConstructJob(Compilation &C, const JobAction &JA, 129 const InputInfo &Output, const InputInfoList &Inputs, 130 const llvm::opt::ArgList &TCArgs, 131 const char *LinkingOutput) const override; 132 }; 133 134 } // end namespace NVPTX 135 } // end namespace tools 136 137 namespace toolchains { 138 139 class LLVM_LIBRARY_VISIBILITY CudaToolChain : public ToolChain { 140 public: 141 CudaToolChain(const Driver &D, const llvm::Triple &Triple, 142 const ToolChain &HostTC, const llvm::opt::ArgList &Args, 143 const Action::OffloadKind OK); 144 145 const llvm::Triple *getAuxTriple() const override { 146 return &HostTC.getTriple(); 147 } 148 149 std::string getInputFilename(const InputInfo &Input) const override; 150 151 llvm::opt::DerivedArgList * 152 TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, 153 Action::OffloadKind DeviceOffloadKind) const override; 154 void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 155 llvm::opt::ArgStringList &CC1Args, 156 Action::OffloadKind DeviceOffloadKind) const override; 157 158 // Never try to use the integrated assembler with CUDA; always fork out to 159 // ptxas. 160 bool useIntegratedAs() const override { return false; } 161 bool isCrossCompiling() const override { return true; } 162 bool isPICDefault() const override { return false; } 163 bool isPIEDefault() const override { return false; } 164 bool isPICDefaultForced() const override { return false; } 165 bool SupportsProfiling() const override { return false; } 166 bool supportsDebugInfoOption(const llvm::opt::Arg *A) const override; 167 void adjustDebugInfoKind(codegenoptions::DebugInfoKind &DebugInfoKind, 168 const llvm::opt::ArgList &Args) const override; 169 bool IsMathErrnoDefault() const override { return false; } 170 171 void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, 172 llvm::opt::ArgStringList &CC1Args) const override; 173 174 void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override; 175 CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; 176 void 177 AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, 178 llvm::opt::ArgStringList &CC1Args) const override; 179 void AddClangCXXStdlibIncludeArgs( 180 const llvm::opt::ArgList &Args, 181 llvm::opt::ArgStringList &CC1Args) const override; 182 void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs, 183 llvm::opt::ArgStringList &CC1Args) const override; 184 185 SanitizerMask getSupportedSanitizers() const override; 186 187 VersionTuple 188 computeMSVCVersion(const Driver *D, 189 const llvm::opt::ArgList &Args) const override; 190 191 unsigned GetDefaultDwarfVersion() const override { return 2; } 192 193 const ToolChain &HostTC; 194 CudaInstallationDetector CudaInstallation; 195 196 protected: 197 Tool *buildAssembler() const override; // ptxas 198 Tool *buildLinker() const override; // fatbinary (ok, not really a linker) 199 200 private: 201 const Action::OffloadKind OK; 202 }; 203 204 } // end namespace toolchains 205 } // end namespace driver 206 } // end namespace clang 207 208 #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_CUDA_H 209