[clang-format] Fix a bug in aligning comments above PPDirective (#72791)
[llvm-project.git] / clang / lib / Basic / Targets / SPIR.h
blob9ab2b7c60936392009c7c2787dbf4a6b446fce4f
1 //===--- SPIR.h - Declare SPIR and SPIR-V 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 SPIR and SPIR-V TargetInfo objects.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H
14 #define LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H
16 #include "Targets.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>
23 namespace clang {
24 namespace targets {
26 // Used by both the SPIR and SPIR-V targets.
27 static const unsigned SPIRDefIsPrivMap[] = {
28 0, // Default
29 1, // opencl_global
30 3, // opencl_local
31 2, // opencl_constant
32 0, // opencl_private
33 4, // opencl_generic
34 5, // opencl_global_device
35 6, // opencl_global_host
36 0, // cuda_device
37 0, // cuda_constant
38 0, // cuda_shared
39 // SYCL address space values for this map are dummy
40 0, // sycl_global
41 0, // sycl_global_device
42 0, // sycl_global_host
43 0, // sycl_local
44 0, // sycl_private
45 0, // ptr32_sptr
46 0, // ptr32_uptr
47 0, // ptr64
48 0, // hlsl_groupshared
49 // Wasm address space values for this target are dummy values,
50 // as it is only enabled for Wasm targets.
51 20, // wasm_funcref
54 // Used by both the SPIR and SPIR-V targets.
55 static const unsigned SPIRDefIsGenMap[] = {
56 4, // Default
57 // OpenCL address space values for this map are dummy and they can't be used
58 0, // opencl_global
59 0, // opencl_local
60 0, // opencl_constant
61 0, // opencl_private
62 0, // opencl_generic
63 0, // opencl_global_device
64 0, // opencl_global_host
65 // cuda_* address space mapping is intended for HIPSPV (HIP to SPIR-V
66 // translation). This mapping is enabled when the language mode is HIP.
67 1, // cuda_device
68 // cuda_constant pointer can be casted to default/"flat" pointer, but in
69 // SPIR-V casts between constant and generic pointers are not allowed. For
70 // this reason cuda_constant is mapped to SPIR-V CrossWorkgroup.
71 1, // cuda_constant
72 3, // cuda_shared
73 1, // sycl_global
74 5, // sycl_global_device
75 6, // sycl_global_host
76 3, // sycl_local
77 0, // sycl_private
78 0, // ptr32_sptr
79 0, // ptr32_uptr
80 0, // ptr64
81 0, // hlsl_groupshared
82 // Wasm address space values for this target are dummy values,
83 // as it is only enabled for Wasm targets.
84 20, // wasm_funcref
87 // Base class for SPIR and SPIR-V target info.
88 class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo {
89 std::unique_ptr<TargetInfo> HostTarget;
91 protected:
92 BaseSPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
93 : TargetInfo(Triple) {
94 assert((Triple.isSPIR() || Triple.isSPIRV()) &&
95 "Invalid architecture for SPIR or SPIR-V.");
96 TLSSupported = false;
97 VLASupported = false;
98 LongWidth = LongAlign = 64;
99 AddrSpaceMap = &SPIRDefIsPrivMap;
100 UseAddrSpaceMapMangling = true;
101 HasLegalHalfType = true;
102 HasFloat16 = true;
103 // Define available target features
104 // These must be defined in sorted order!
105 NoAsmVariants = true;
107 llvm::Triple HostTriple(Opts.HostTriple);
108 if (!HostTriple.isSPIR() && !HostTriple.isSPIRV() &&
109 HostTriple.getArch() != llvm::Triple::UnknownArch) {
110 HostTarget = AllocateTarget(llvm::Triple(Opts.HostTriple), Opts);
112 // Copy properties from host target.
113 BoolWidth = HostTarget->getBoolWidth();
114 BoolAlign = HostTarget->getBoolAlign();
115 IntWidth = HostTarget->getIntWidth();
116 IntAlign = HostTarget->getIntAlign();
117 HalfWidth = HostTarget->getHalfWidth();
118 HalfAlign = HostTarget->getHalfAlign();
119 FloatWidth = HostTarget->getFloatWidth();
120 FloatAlign = HostTarget->getFloatAlign();
121 DoubleWidth = HostTarget->getDoubleWidth();
122 DoubleAlign = HostTarget->getDoubleAlign();
123 LongWidth = HostTarget->getLongWidth();
124 LongAlign = HostTarget->getLongAlign();
125 LongLongWidth = HostTarget->getLongLongWidth();
126 LongLongAlign = HostTarget->getLongLongAlign();
127 MinGlobalAlign = HostTarget->getMinGlobalAlign(/* TypeSize = */ 0);
128 NewAlign = HostTarget->getNewAlign();
129 DefaultAlignForAttributeAligned =
130 HostTarget->getDefaultAlignForAttributeAligned();
131 IntMaxType = HostTarget->getIntMaxType();
132 WCharType = HostTarget->getWCharType();
133 WIntType = HostTarget->getWIntType();
134 Char16Type = HostTarget->getChar16Type();
135 Char32Type = HostTarget->getChar32Type();
136 Int64Type = HostTarget->getInt64Type();
137 SigAtomicType = HostTarget->getSigAtomicType();
138 ProcessIDType = HostTarget->getProcessIDType();
140 UseBitFieldTypeAlignment = HostTarget->useBitFieldTypeAlignment();
141 UseZeroLengthBitfieldAlignment =
142 HostTarget->useZeroLengthBitfieldAlignment();
143 UseExplicitBitFieldAlignment = HostTarget->useExplicitBitFieldAlignment();
144 ZeroLengthBitfieldBoundary = HostTarget->getZeroLengthBitfieldBoundary();
146 // This is a bit of a lie, but it controls __GCC_ATOMIC_XXX_LOCK_FREE, and
147 // we need those macros to be identical on host and device, because (among
148 // other things) they affect which standard library classes are defined,
149 // and we need all classes to be defined on both the host and device.
150 MaxAtomicInlineWidth = HostTarget->getMaxAtomicInlineWidth();
154 public:
155 // SPIR supports the half type and the only llvm intrinsic allowed in SPIR is
156 // memcpy as per section 3 of the SPIR spec.
157 bool useFP16ConversionIntrinsics() const override { return false; }
159 ArrayRef<Builtin::Info> getTargetBuiltins() const override {
160 return std::nullopt;
163 std::string_view getClobbers() const override { return ""; }
165 ArrayRef<const char *> getGCCRegNames() const override {
166 return std::nullopt;
169 bool validateAsmConstraint(const char *&Name,
170 TargetInfo::ConstraintInfo &info) const override {
171 return true;
174 ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
175 return std::nullopt;
178 BuiltinVaListKind getBuiltinVaListKind() const override {
179 return TargetInfo::VoidPtrBuiltinVaList;
182 std::optional<unsigned>
183 getDWARFAddressSpace(unsigned AddressSpace) const override {
184 return AddressSpace;
187 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
188 return (CC == CC_SpirFunction || CC == CC_OpenCLKernel) ? CCCR_OK
189 : CCCR_Warning;
192 CallingConv getDefaultCallingConv() const override {
193 return CC_SpirFunction;
196 void setAddressSpaceMap(bool DefaultIsGeneric) {
197 AddrSpaceMap = DefaultIsGeneric ? &SPIRDefIsGenMap : &SPIRDefIsPrivMap;
200 void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override {
201 TargetInfo::adjust(Diags, Opts);
202 // FIXME: SYCL specification considers unannotated pointers and references
203 // to be pointing to the generic address space. See section 5.9.3 of
204 // SYCL 2020 specification.
205 // Currently, there is no way of representing SYCL's and HIP/CUDA's default
206 // address space language semantic along with the semantics of embedded C's
207 // default address space in the same address space map. Hence the map needs
208 // to be reset to allow mapping to the desired value of 'Default' entry for
209 // SYCL and HIP/CUDA.
210 setAddressSpaceMap(
211 /*DefaultIsGeneric=*/Opts.SYCLIsDevice ||
212 // The address mapping from HIP/CUDA language for device code is only
213 // defined for SPIR-V.
214 (getTriple().isSPIRV() && Opts.CUDAIsDevice));
217 void setSupportedOpenCLOpts() override {
218 // Assume all OpenCL extensions and optional core features are supported
219 // for SPIR and SPIR-V since they are generic targets.
220 supportAllOpenCLOpts();
223 bool hasBitIntType() const override { return true; }
225 bool hasInt128Type() const override { return false; }
228 class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public BaseSPIRTargetInfo {
229 public:
230 SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
231 : BaseSPIRTargetInfo(Triple, Opts) {
232 assert(Triple.isSPIR() && "Invalid architecture for SPIR.");
233 assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
234 "SPIR target must use unknown OS");
235 assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
236 "SPIR target must use unknown environment type");
239 void getTargetDefines(const LangOptions &Opts,
240 MacroBuilder &Builder) const override;
242 bool hasFeature(StringRef Feature) const override {
243 return Feature == "spir";
246 bool checkArithmeticFenceSupported() const override { return true; }
249 class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo {
250 public:
251 SPIR32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
252 : SPIRTargetInfo(Triple, Opts) {
253 assert(Triple.getArch() == llvm::Triple::spir &&
254 "Invalid architecture for 32-bit SPIR.");
255 PointerWidth = PointerAlign = 32;
256 SizeType = TargetInfo::UnsignedInt;
257 PtrDiffType = IntPtrType = TargetInfo::SignedInt;
258 resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"
259 "v96:128-v192:256-v256:256-v512:512-v1024:1024");
262 void getTargetDefines(const LangOptions &Opts,
263 MacroBuilder &Builder) const override;
266 class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo : public SPIRTargetInfo {
267 public:
268 SPIR64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
269 : SPIRTargetInfo(Triple, Opts) {
270 assert(Triple.getArch() == llvm::Triple::spir64 &&
271 "Invalid architecture for 64-bit SPIR.");
272 PointerWidth = PointerAlign = 64;
273 SizeType = TargetInfo::UnsignedLong;
274 PtrDiffType = IntPtrType = TargetInfo::SignedLong;
275 resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"
276 "v96:128-v192:256-v256:256-v512:512-v1024:1024");
279 void getTargetDefines(const LangOptions &Opts,
280 MacroBuilder &Builder) const override;
283 class LLVM_LIBRARY_VISIBILITY BaseSPIRVTargetInfo : public BaseSPIRTargetInfo {
284 public:
285 BaseSPIRVTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
286 : BaseSPIRTargetInfo(Triple, Opts) {
287 assert(Triple.isSPIRV() && "Invalid architecture for SPIR-V.");
290 bool hasFeature(StringRef Feature) const override {
291 return Feature == "spirv";
294 void getTargetDefines(const LangOptions &Opts,
295 MacroBuilder &Builder) const override;
298 class LLVM_LIBRARY_VISIBILITY SPIRVTargetInfo : public BaseSPIRVTargetInfo {
299 public:
300 SPIRVTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
301 : BaseSPIRVTargetInfo(Triple, Opts) {
302 assert(Triple.getArch() == llvm::Triple::spirv &&
303 "Invalid architecture for Logical SPIR-V.");
304 assert(Triple.getOS() == llvm::Triple::ShaderModel &&
305 "Logical SPIR-V requires a valid ShaderModel.");
306 assert(Triple.getEnvironment() >= llvm::Triple::Pixel &&
307 Triple.getEnvironment() <= llvm::Triple::Amplification &&
308 "Logical SPIR-V environment must be a valid shader stage.");
310 // SPIR-V IDs are represented with a single 32-bit word.
311 SizeType = TargetInfo::UnsignedInt;
312 resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"
313 "v96:128-v192:256-v256:256-v512:512-v1024:1024");
316 void getTargetDefines(const LangOptions &Opts,
317 MacroBuilder &Builder) const override;
320 class LLVM_LIBRARY_VISIBILITY SPIRV32TargetInfo : public BaseSPIRVTargetInfo {
321 public:
322 SPIRV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
323 : BaseSPIRVTargetInfo(Triple, Opts) {
324 assert(Triple.getArch() == llvm::Triple::spirv32 &&
325 "Invalid architecture for 32-bit SPIR-V.");
326 assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
327 "32-bit SPIR-V target must use unknown OS");
328 assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
329 "32-bit SPIR-V target must use unknown environment type");
330 PointerWidth = PointerAlign = 32;
331 SizeType = TargetInfo::UnsignedInt;
332 PtrDiffType = IntPtrType = TargetInfo::SignedInt;
333 resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"
334 "v96:128-v192:256-v256:256-v512:512-v1024:1024");
337 void getTargetDefines(const LangOptions &Opts,
338 MacroBuilder &Builder) const override;
341 class LLVM_LIBRARY_VISIBILITY SPIRV64TargetInfo : public BaseSPIRVTargetInfo {
342 public:
343 SPIRV64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
344 : BaseSPIRVTargetInfo(Triple, Opts) {
345 assert(Triple.getArch() == llvm::Triple::spirv64 &&
346 "Invalid architecture for 64-bit SPIR-V.");
347 assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
348 "64-bit SPIR-V target must use unknown OS");
349 assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
350 "64-bit SPIR-V target must use unknown environment type");
351 PointerWidth = PointerAlign = 64;
352 SizeType = TargetInfo::UnsignedLong;
353 PtrDiffType = IntPtrType = TargetInfo::SignedLong;
354 resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"
355 "v96:128-v192:256-v256:256-v512:512-v1024:1024");
358 void getTargetDefines(const LangOptions &Opts,
359 MacroBuilder &Builder) const override;
362 } // namespace targets
363 } // namespace clang
364 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H