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