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