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

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of clang/lib/Basic/Targets/NVPTX.h