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) : Tool("NVPTX::Assembler", "ptxas", TC) {} 93 94 bool hasIntegratedCPP() const override { return false; } 95 96 void ConstructJob(Compilation &C, const JobAction &JA, 97 const InputInfo &Output, const InputInfoList &Inputs, 98 const llvm::opt::ArgList &TCArgs, 99 const char *LinkingOutput) const override; 100 }; 101 102 // Runs fatbinary, which combines GPU object files ("cubin" files) and/or PTX 103 // assembly into a single output file. 104 class LLVM_LIBRARY_VISIBILITY Linker : public Tool { 105 public: 106 Linker(const ToolChain &TC) : Tool("NVPTX::Linker", "fatbinary", TC) {} 107 108 bool hasIntegratedCPP() const override { return false; } 109 110 void ConstructJob(Compilation &C, const JobAction &JA, 111 const InputInfo &Output, const InputInfoList &Inputs, 112 const llvm::opt::ArgList &TCArgs, 113 const char *LinkingOutput) const override; 114 }; 115 116 class LLVM_LIBRARY_VISIBILITY OpenMPLinker : public Tool { 117 public: 118 OpenMPLinker(const ToolChain &TC) 119 : Tool("NVPTX::OpenMPLinker", "nvlink", TC) {} 120 121 bool hasIntegratedCPP() const override { return false; } 122 123 void ConstructJob(Compilation &C, const JobAction &JA, 124 const InputInfo &Output, const InputInfoList &Inputs, 125 const llvm::opt::ArgList &TCArgs, 126 const char *LinkingOutput) const override; 127 }; 128 129 } // end namespace NVPTX 130 } // end namespace tools 131 132 namespace toolchains { 133 134 class LLVM_LIBRARY_VISIBILITY CudaToolChain : public ToolChain { 135 public: 136 CudaToolChain(const Driver &D, const llvm::Triple &Triple, 137 const ToolChain &HostTC, const llvm::opt::ArgList &Args, 138 const Action::OffloadKind OK); 139 140 const llvm::Triple *getAuxTriple() const override { 141 return &HostTC.getTriple(); 142 } 143 144 std::string getInputFilename(const InputInfo &Input) const override; 145 146 llvm::opt::DerivedArgList * 147 TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, 148 Action::OffloadKind DeviceOffloadKind) const override; 149 void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 150 llvm::opt::ArgStringList &CC1Args, 151 Action::OffloadKind DeviceOffloadKind) const override; 152 153 llvm::DenormalMode getDefaultDenormalModeForType( 154 const llvm::opt::ArgList &DriverArgs, const JobAction &JA, 155 const llvm::fltSemantics *FPType = nullptr) const override; 156 157 // Never try to use the integrated assembler with CUDA; always fork out to 158 // ptxas. 159 bool useIntegratedAs() const override { return false; } 160 bool isCrossCompiling() const override { return true; } 161 bool isPICDefault() const override { return false; } 162 bool isPIEDefault() const override { return false; } 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 192 const ToolChain &HostTC; 193 CudaInstallationDetector CudaInstallation; 194 195 protected: 196 Tool *buildAssembler() const override; // ptxas 197 Tool *buildLinker() const override; // fatbinary (ok, not really a linker) 198 199 private: 200 const Action::OffloadKind OK; 201 }; 202 203 } // end namespace toolchains 204 } // end namespace driver 205 } // end namespace clang 206 207 #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_CUDA_H 208