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 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 llvm::SmallSet<CudaArch, 4> 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. isValid()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. version()63 CudaVersion version() const { return Version; } 64 /// Get the detected Cuda installation path. getInstallPath()65 StringRef getInstallPath() const { return InstallPath; } 66 /// Get the detected path to Cuda's bin directory. getBinPath()67 StringRef getBinPath() const { return BinPath; } 68 /// Get the detected Cuda Include path. getIncludePath()69 StringRef getIncludePath() const { return IncludePath; } 70 /// Get the detected Cuda library path. getLibPath()71 StringRef getLibPath() const { return LibPath; } 72 /// Get the detected Cuda device library path. getLibDevicePath()73 StringRef getLibDevicePath() const { return LibDevicePath; } 74 /// Get libdevice file for given architecture getLibDeviceFile(StringRef Gpu)75 std::string getLibDeviceFile(StringRef Gpu) const { 76 return LibDeviceMap.lookup(Gpu); 77 } 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: Assembler(const ToolChain & TC)86 Assembler(const ToolChain &TC) 87 : Tool("NVPTX::Assembler", "ptxas", TC, RF_Full, llvm::sys::WEM_UTF8, 88 "--options-file") {} 89 hasIntegratedCPP()90 bool hasIntegratedCPP() const override { return false; } 91 92 void ConstructJob(Compilation &C, const JobAction &JA, 93 const InputInfo &Output, const InputInfoList &Inputs, 94 const llvm::opt::ArgList &TCArgs, 95 const char *LinkingOutput) const override; 96 }; 97 98 // Runs fatbinary, which combines GPU object files ("cubin" files) and/or PTX 99 // assembly into a single output file. 100 class LLVM_LIBRARY_VISIBILITY Linker : public Tool { 101 public: Linker(const ToolChain & TC)102 Linker(const ToolChain &TC) 103 : Tool("NVPTX::Linker", "fatbinary", TC, RF_Full, llvm::sys::WEM_UTF8, 104 "--options-file") {} 105 hasIntegratedCPP()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: OpenMPLinker(const ToolChain & TC)116 OpenMPLinker(const ToolChain &TC) 117 : Tool("NVPTX::OpenMPLinker", "nvlink", TC, RF_Full, llvm::sys::WEM_UTF8, 118 "--options-file") {} 119 hasIntegratedCPP()120 bool hasIntegratedCPP() const override { return false; } 121 122 void ConstructJob(Compilation &C, const JobAction &JA, 123 const InputInfo &Output, const InputInfoList &Inputs, 124 const llvm::opt::ArgList &TCArgs, 125 const char *LinkingOutput) const override; 126 }; 127 128 } // end namespace NVPTX 129 } // end namespace tools 130 131 namespace toolchains { 132 133 class LLVM_LIBRARY_VISIBILITY CudaToolChain : public ToolChain { 134 public: 135 CudaToolChain(const Driver &D, const llvm::Triple &Triple, 136 const ToolChain &HostTC, const llvm::opt::ArgList &Args, 137 const Action::OffloadKind OK); 138 getAuxTriple()139 const llvm::Triple *getAuxTriple() const override { 140 return &HostTC.getTriple(); 141 } 142 143 std::string getInputFilename(const InputInfo &Input) const override; 144 145 llvm::opt::DerivedArgList * 146 TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, 147 Action::OffloadKind DeviceOffloadKind) const override; 148 void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, 149 llvm::opt::ArgStringList &CC1Args, 150 Action::OffloadKind DeviceOffloadKind) const override; 151 152 // Never try to use the integrated assembler with CUDA; always fork out to 153 // ptxas. useIntegratedAs()154 bool useIntegratedAs() const override { return false; } isCrossCompiling()155 bool isCrossCompiling() const override { return true; } isPICDefault()156 bool isPICDefault() const override { return false; } isPIEDefault()157 bool isPIEDefault() const override { return false; } isPICDefaultForced()158 bool isPICDefaultForced() const override { return false; } SupportsProfiling()159 bool SupportsProfiling() const override { return false; } 160 bool supportsDebugInfoOption(const llvm::opt::Arg *A) const override; 161 void adjustDebugInfoKind(codegenoptions::DebugInfoKind &DebugInfoKind, 162 const llvm::opt::ArgList &Args) const override; IsMathErrnoDefault()163 bool IsMathErrnoDefault() const override { return false; } 164 165 void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, 166 llvm::opt::ArgStringList &CC1Args) const override; 167 168 void addClangWarningOptions(llvm::opt::ArgStringList &CC1Args) const override; 169 CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override; 170 void 171 AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, 172 llvm::opt::ArgStringList &CC1Args) const override; 173 void AddClangCXXStdlibIncludeArgs( 174 const llvm::opt::ArgList &Args, 175 llvm::opt::ArgStringList &CC1Args) const override; 176 void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs, 177 llvm::opt::ArgStringList &CC1Args) const override; 178 179 SanitizerMask getSupportedSanitizers() const override; 180 181 VersionTuple 182 computeMSVCVersion(const Driver *D, 183 const llvm::opt::ArgList &Args) const override; 184 GetDefaultDwarfVersion()185 unsigned GetDefaultDwarfVersion() const override { return 2; } 186 187 const ToolChain &HostTC; 188 CudaInstallationDetector CudaInstallation; 189 190 protected: 191 Tool *buildAssembler() const override; // ptxas 192 Tool *buildLinker() const override; // fatbinary (ok, not really a linker) 193 194 private: 195 const Action::OffloadKind OK; 196 }; 197 198 } // end namespace toolchains 199 } // end namespace driver 200 } // end namespace clang 201 202 #endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_CUDA_H 203