xref: /freebsd/contrib/llvm-project/clang/lib/Basic/Targets/NVPTX.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 //===--- NVPTX.h - Declare NVPTX target feature support ---------*- 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 // This file declares NVPTX TargetInfo objects.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_NVPTX_H
14 #define LLVM_CLANG_LIB_BASIC_TARGETS_NVPTX_H
15 
16 #include "clang/Basic/Cuda.h"
17 #include "clang/Basic/TargetInfo.h"
18 #include "clang/Basic/TargetOptions.h"
19 #include "llvm/Support/Compiler.h"
20 #include "llvm/TargetParser/Triple.h"
21 #include <optional>
22 
23 namespace clang {
24 namespace targets {
25 
26 static const unsigned NVPTXAddrSpaceMap[] = {
27     0, // Default
28     1, // opencl_global
29     3, // opencl_local
30     4, // opencl_constant
31     0, // opencl_private
32     // FIXME: generic has to be added to the target
33     0, // opencl_generic
34     1, // opencl_global_device
35     1, // opencl_global_host
36     1, // cuda_device
37     4, // cuda_constant
38     3, // cuda_shared
39     1, // sycl_global
40     1, // sycl_global_device
41     1, // sycl_global_host
42     3, // sycl_local
43     0, // sycl_private
44     0, // ptr32_sptr
45     0, // ptr32_uptr
46     0, // ptr64
47     0, // hlsl_groupshared
48     // Wasm address space values for this target are dummy values,
49     // as it is only enabled for Wasm targets.
50     20, // wasm_funcref
51 };
52 
53 /// The DWARF address class. Taken from
54 /// https://docs.nvidia.com/cuda/archive/10.0/ptx-writers-guide-to-interoperability/index.html#cuda-specific-dwarf
55 static const int NVPTXDWARFAddrSpaceMap[] = {
56     -1, // Default, opencl_private or opencl_generic - not defined
57     5,  // opencl_global
58     -1,
59     8,  // opencl_local or cuda_shared
60     4,  // opencl_constant or cuda_constant
61 };
62 
63 class LLVM_LIBRARY_VISIBILITY NVPTXTargetInfo : public TargetInfo {
64   static const char *const GCCRegNames[];
65   OffloadArch GPU;
66   uint32_t PTXVersion;
67   std::unique_ptr<TargetInfo> HostTarget;
68 
69 public:
70   NVPTXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts,
71                   unsigned TargetPointerWidth);
72 
73   void getTargetDefines(const LangOptions &Opts,
74                         MacroBuilder &Builder) const override;
75 
76   ArrayRef<Builtin::Info> getTargetBuiltins() const override;
77 
useFP16ConversionIntrinsics()78   bool useFP16ConversionIntrinsics() const override { return false; }
79 
80   bool
initFeatureMap(llvm::StringMap<bool> & Features,DiagnosticsEngine & Diags,StringRef CPU,const std::vector<std::string> & FeaturesVec)81   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
82                  StringRef CPU,
83                  const std::vector<std::string> &FeaturesVec) const override {
84     if (GPU != OffloadArch::UNUSED)
85       Features[OffloadArchToString(GPU)] = true;
86     Features["ptx" + std::to_string(PTXVersion)] = true;
87     return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
88   }
89 
90   bool hasFeature(StringRef Feature) const override;
91 
92   ArrayRef<const char *> getGCCRegNames() const override;
93 
getGCCRegAliases()94   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
95     // No aliases.
96     return std::nullopt;
97   }
98 
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info)99   bool validateAsmConstraint(const char *&Name,
100                              TargetInfo::ConstraintInfo &Info) const override {
101     switch (*Name) {
102     default:
103       return false;
104     case 'c':
105     case 'h':
106     case 'r':
107     case 'l':
108     case 'f':
109     case 'd':
110     case 'q':
111       Info.setAllowsRegister();
112       return true;
113     }
114   }
115 
getClobbers()116   std::string_view getClobbers() const override {
117     // FIXME: Is this really right?
118     return "";
119   }
120 
getBuiltinVaListKind()121   BuiltinVaListKind getBuiltinVaListKind() const override {
122     return TargetInfo::VoidPtrBuiltinVaList;
123   }
124 
isValidCPUName(StringRef Name)125   bool isValidCPUName(StringRef Name) const override {
126     return StringToOffloadArch(Name) != OffloadArch::UNKNOWN;
127   }
128 
fillValidCPUList(SmallVectorImpl<StringRef> & Values)129   void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override {
130     for (int i = static_cast<int>(OffloadArch::SM_20);
131          i < static_cast<int>(OffloadArch::Generic); ++i)
132       Values.emplace_back(OffloadArchToString(static_cast<OffloadArch>(i)));
133   }
134 
setCPU(const std::string & Name)135   bool setCPU(const std::string &Name) override {
136     GPU = StringToOffloadArch(Name);
137     return GPU != OffloadArch::UNKNOWN;
138   }
139 
setSupportedOpenCLOpts()140   void setSupportedOpenCLOpts() override {
141     auto &Opts = getSupportedOpenCLOpts();
142     Opts["cl_clang_storage_class_specifiers"] = true;
143     Opts["__cl_clang_function_pointers"] = true;
144     Opts["__cl_clang_variadic_functions"] = true;
145     Opts["__cl_clang_non_portable_kernel_param_types"] = true;
146     Opts["__cl_clang_bitfields"] = true;
147 
148     Opts["cl_khr_fp64"] = true;
149     Opts["__opencl_c_fp64"] = true;
150     Opts["cl_khr_byte_addressable_store"] = true;
151     Opts["cl_khr_global_int32_base_atomics"] = true;
152     Opts["cl_khr_global_int32_extended_atomics"] = true;
153     Opts["cl_khr_local_int32_base_atomics"] = true;
154     Opts["cl_khr_local_int32_extended_atomics"] = true;
155   }
156 
getGridValue()157   const llvm::omp::GV &getGridValue() const override {
158     return llvm::omp::NVPTXGridValues;
159   }
160 
161   /// \returns If a target requires an address within a target specific address
162   /// space \p AddressSpace to be converted in order to be used, then return the
163   /// corresponding target specific DWARF address space.
164   ///
165   /// \returns Otherwise return std::nullopt and no conversion will be emitted
166   /// in the DWARF.
167   std::optional<unsigned>
getDWARFAddressSpace(unsigned AddressSpace)168   getDWARFAddressSpace(unsigned AddressSpace) const override {
169     if (AddressSpace >= std::size(NVPTXDWARFAddrSpaceMap) ||
170         NVPTXDWARFAddrSpaceMap[AddressSpace] < 0)
171       return std::nullopt;
172     return NVPTXDWARFAddrSpaceMap[AddressSpace];
173   }
174 
checkCallingConvention(CallingConv CC)175   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
176     // CUDA compilations support all of the host's calling conventions.
177     //
178     // TODO: We should warn if you apply a non-default CC to anything other than
179     // a host function.
180     if (HostTarget)
181       return HostTarget->checkCallingConvention(CC);
182     return CCCR_Warning;
183   }
184 
hasBitIntType()185   bool hasBitIntType() const override { return true; }
hasBFloat16Type()186   bool hasBFloat16Type() const override { return true; }
187 
getGPU()188   OffloadArch getGPU() const { return GPU; }
189 };
190 } // namespace targets
191 } // namespace clang
192 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_NVPTX_H
193