xref: /openbsd-src/gnu/llvm/clang/lib/Driver/ToolChains/Cuda.h (revision 12c855180aad702bbcca06e0398d774beeafb155)
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