clang 17.0.0git
SPIR.h
Go to the documentation of this file.
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.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H
14#define LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H
15
16#include "Targets.h"
19#include "llvm/Support/Compiler.h"
20#include "llvm/TargetParser/Triple.h"
21#include <optional>
22
23namespace clang {
24namespace targets {
25
26// Used by both the SPIR and SPIR-V targets.
27static 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
52};
53
54// Used by both the SPIR and SPIR-V targets.
55static 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
85};
86
87// Base class for SPIR and SPIR-V target info.
88class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo {
89 std::unique_ptr<TargetInfo> HostTarget;
90
91protected:
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 assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
97 "SPIR(-V) target must use unknown OS");
98 assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
99 "SPIR(-V) target must use unknown environment type");
100 TLSSupported = false;
101 VLASupported = false;
102 LongWidth = LongAlign = 64;
103 AddrSpaceMap = &SPIRDefIsPrivMap;
104 UseAddrSpaceMapMangling = true;
105 HasLegalHalfType = true;
106 HasFloat16 = true;
107 // Define available target features
108 // These must be defined in sorted order!
109 NoAsmVariants = true;
110
111 llvm::Triple HostTriple(Opts.HostTriple);
112 if (!HostTriple.isSPIR() && !HostTriple.isSPIRV() &&
113 HostTriple.getArch() != llvm::Triple::UnknownArch) {
114 HostTarget = AllocateTarget(llvm::Triple(Opts.HostTriple), Opts);
115
116 // Copy properties from host target.
117 BoolWidth = HostTarget->getBoolWidth();
118 BoolAlign = HostTarget->getBoolAlign();
119 IntWidth = HostTarget->getIntWidth();
120 IntAlign = HostTarget->getIntAlign();
121 HalfWidth = HostTarget->getHalfWidth();
122 HalfAlign = HostTarget->getHalfAlign();
123 FloatWidth = HostTarget->getFloatWidth();
124 FloatAlign = HostTarget->getFloatAlign();
125 DoubleWidth = HostTarget->getDoubleWidth();
126 DoubleAlign = HostTarget->getDoubleAlign();
127 LongWidth = HostTarget->getLongWidth();
128 LongAlign = HostTarget->getLongAlign();
129 LongLongWidth = HostTarget->getLongLongWidth();
130 LongLongAlign = HostTarget->getLongLongAlign();
131 MinGlobalAlign = HostTarget->getMinGlobalAlign(/* TypeSize = */ 0);
132 NewAlign = HostTarget->getNewAlign();
133 DefaultAlignForAttributeAligned =
134 HostTarget->getDefaultAlignForAttributeAligned();
135 IntMaxType = HostTarget->getIntMaxType();
136 WCharType = HostTarget->getWCharType();
137 WIntType = HostTarget->getWIntType();
138 Char16Type = HostTarget->getChar16Type();
139 Char32Type = HostTarget->getChar32Type();
140 Int64Type = HostTarget->getInt64Type();
141 SigAtomicType = HostTarget->getSigAtomicType();
142 ProcessIDType = HostTarget->getProcessIDType();
143
144 UseBitFieldTypeAlignment = HostTarget->useBitFieldTypeAlignment();
145 UseZeroLengthBitfieldAlignment =
146 HostTarget->useZeroLengthBitfieldAlignment();
147 UseExplicitBitFieldAlignment = HostTarget->useExplicitBitFieldAlignment();
148 ZeroLengthBitfieldBoundary = HostTarget->getZeroLengthBitfieldBoundary();
149
150 // This is a bit of a lie, but it controls __GCC_ATOMIC_XXX_LOCK_FREE, and
151 // we need those macros to be identical on host and device, because (among
152 // other things) they affect which standard library classes are defined,
153 // and we need all classes to be defined on both the host and device.
154 MaxAtomicInlineWidth = HostTarget->getMaxAtomicInlineWidth();
155 }
156 }
157
158public:
159 // SPIR supports the half type and the only llvm intrinsic allowed in SPIR is
160 // memcpy as per section 3 of the SPIR spec.
161 bool useFP16ConversionIntrinsics() const override { return false; }
162
164 return std::nullopt;
165 }
166
167 std::string_view getClobbers() const override { return ""; }
168
170 return std::nullopt;
171 }
172
173 bool validateAsmConstraint(const char *&Name,
174 TargetInfo::ConstraintInfo &info) const override {
175 return true;
176 }
177
179 return std::nullopt;
180 }
181
183 return TargetInfo::VoidPtrBuiltinVaList;
184 }
185
186 std::optional<unsigned>
187 getDWARFAddressSpace(unsigned AddressSpace) const override {
188 return AddressSpace;
189 }
190
192 return (CC == CC_SpirFunction || CC == CC_OpenCLKernel) ? CCCR_OK
193 : CCCR_Warning;
194 }
195
197 return CC_SpirFunction;
198 }
199
200 void setAddressSpaceMap(bool DefaultIsGeneric) {
201 AddrSpaceMap = DefaultIsGeneric ? &SPIRDefIsGenMap : &SPIRDefIsPrivMap;
202 }
203
204 void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override {
205 TargetInfo::adjust(Diags, Opts);
206 // FIXME: SYCL specification considers unannotated pointers and references
207 // to be pointing to the generic address space. See section 5.9.3 of
208 // SYCL 2020 specification.
209 // Currently, there is no way of representing SYCL's and HIP/CUDA's default
210 // address space language semantic along with the semantics of embedded C's
211 // default address space in the same address space map. Hence the map needs
212 // to be reset to allow mapping to the desired value of 'Default' entry for
213 // SYCL and HIP/CUDA.
214 setAddressSpaceMap(
215 /*DefaultIsGeneric=*/Opts.SYCLIsDevice ||
216 // The address mapping from HIP/CUDA language for device code is only
217 // defined for SPIR-V.
218 (getTriple().isSPIRV() && Opts.CUDAIsDevice));
219 }
220
221 void setSupportedOpenCLOpts() override {
222 // Assume all OpenCL extensions and optional core features are supported
223 // for SPIR and SPIR-V since they are generic targets.
224 supportAllOpenCLOpts();
225 }
226
227 bool hasBitIntType() const override { return true; }
228
229 bool hasInt128Type() const override { return false; }
230};
231
232class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public BaseSPIRTargetInfo {
233public:
234 SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
235 : BaseSPIRTargetInfo(Triple, Opts) {
236 assert(Triple.isSPIR() && "Invalid architecture for SPIR.");
237 assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
238 "SPIR target must use unknown OS");
239 assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
240 "SPIR target must use unknown environment type");
241 }
242
243 void getTargetDefines(const LangOptions &Opts,
244 MacroBuilder &Builder) const override;
245
246 bool hasFeature(StringRef Feature) const override {
247 return Feature == "spir";
248 }
249
250 bool checkArithmeticFenceSupported() const override { return true; }
251};
252
253class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo {
254public:
255 SPIR32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
256 : SPIRTargetInfo(Triple, Opts) {
257 assert(Triple.getArch() == llvm::Triple::spir &&
258 "Invalid architecture for 32-bit SPIR.");
259 PointerWidth = PointerAlign = 32;
260 SizeType = TargetInfo::UnsignedInt;
261 PtrDiffType = IntPtrType = TargetInfo::SignedInt;
262 resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"
263 "v96:128-v192:256-v256:256-v512:512-v1024:1024");
264 }
265
266 void getTargetDefines(const LangOptions &Opts,
267 MacroBuilder &Builder) const override;
268};
269
270class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo : public SPIRTargetInfo {
271public:
272 SPIR64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
273 : SPIRTargetInfo(Triple, Opts) {
274 assert(Triple.getArch() == llvm::Triple::spir64 &&
275 "Invalid architecture for 64-bit SPIR.");
276 PointerWidth = PointerAlign = 64;
277 SizeType = TargetInfo::UnsignedLong;
278 PtrDiffType = IntPtrType = TargetInfo::SignedLong;
279 resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"
280 "v96:128-v192:256-v256:256-v512:512-v1024:1024");
281 }
282
283 void getTargetDefines(const LangOptions &Opts,
284 MacroBuilder &Builder) const override;
285};
286
287class LLVM_LIBRARY_VISIBILITY SPIRVTargetInfo : public BaseSPIRTargetInfo {
288public:
289 SPIRVTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
290 : BaseSPIRTargetInfo(Triple, Opts) {
291 assert(Triple.isSPIRV() && "Invalid architecture for SPIR-V.");
292 assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
293 "SPIR-V target must use unknown OS");
294 assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
295 "SPIR-V target must use unknown environment type");
296 }
297
298 void getTargetDefines(const LangOptions &Opts,
299 MacroBuilder &Builder) const override;
300
301 bool hasFeature(StringRef Feature) const override {
302 return Feature == "spirv";
303 }
304};
305
306class LLVM_LIBRARY_VISIBILITY SPIRV32TargetInfo : public SPIRVTargetInfo {
307public:
308 SPIRV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
309 : SPIRVTargetInfo(Triple, Opts) {
310 assert(Triple.getArch() == llvm::Triple::spirv32 &&
311 "Invalid architecture for 32-bit SPIR-V.");
312 PointerWidth = PointerAlign = 32;
313 SizeType = TargetInfo::UnsignedInt;
314 PtrDiffType = IntPtrType = TargetInfo::SignedInt;
315 resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"
316 "v96:128-v192:256-v256:256-v512:512-v1024:1024");
317 }
318
319 void getTargetDefines(const LangOptions &Opts,
320 MacroBuilder &Builder) const override;
321};
322
323class LLVM_LIBRARY_VISIBILITY SPIRV64TargetInfo : public SPIRVTargetInfo {
324public:
325 SPIRV64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
326 : SPIRVTargetInfo(Triple, Opts) {
327 assert(Triple.getArch() == llvm::Triple::spirv64 &&
328 "Invalid architecture for 64-bit SPIR-V.");
329 PointerWidth = PointerAlign = 64;
330 SizeType = TargetInfo::UnsignedLong;
331 PtrDiffType = IntPtrType = TargetInfo::SignedLong;
332 resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"
333 "v96:128-v192:256-v256:256-v512:512-v1024:1024");
334 }
335
336 void getTargetDefines(const LangOptions &Opts,
337 MacroBuilder &Builder) const override;
338};
339
340} // namespace targets
341} // namespace clang
342#endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H
Defines the clang::TargetOptions class.
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:192
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:82
Exposes information about the current target.
Definition: TargetInfo.h:206
BuiltinVaListKind
The different kinds of __builtin_va_list types defined by the target implementation.
Definition: TargetInfo.h:290
Options for controlling the target.
Definition: TargetOptions.h:26
std::string HostTriple
When compiling for the device side, contains the triple used to compile for the host.
Definition: TargetOptions.h:33
ArrayRef< Builtin::Info > getTargetBuiltins() const override
Return information about target-specific builtins for the current primary target, and info about whic...
Definition: SPIR.h:163
BuiltinVaListKind getBuiltinVaListKind() const override
Returns the kind of __builtin_va_list type that should be used with this target.
Definition: SPIR.h:182
ArrayRef< const char * > getGCCRegNames() const override
Definition: SPIR.h:169
void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override
Set forced language options.
Definition: SPIR.h:204
bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &info) const override
Definition: SPIR.h:173
bool hasInt128Type() const override
Determine whether the __int128 type is supported on this target.
Definition: SPIR.h:229
void setAddressSpaceMap(bool DefaultIsGeneric)
Definition: SPIR.h:200
bool useFP16ConversionIntrinsics() const override
Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used to convert to and from __fp...
Definition: SPIR.h:161
ArrayRef< TargetInfo::GCCRegAlias > getGCCRegAliases() const override
Definition: SPIR.h:178
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override
Determines whether a given calling convention is valid for the target.
Definition: SPIR.h:191
std::optional< unsigned > getDWARFAddressSpace(unsigned AddressSpace) const override
Definition: SPIR.h:187
BaseSPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
Definition: SPIR.h:92
bool hasBitIntType() const override
Determine whether the _BitInt type is supported on this target.
Definition: SPIR.h:227
void setSupportedOpenCLOpts() override
Set supported OpenCL extensions and optional core features.
Definition: SPIR.h:221
std::string_view getClobbers() const override
Returns a string of target-specific clobbers, in LLVM format.
Definition: SPIR.h:167
CallingConv getDefaultCallingConv() const override
Gets the default calling convention for the given target and declaration context.
Definition: SPIR.h:196
SPIR32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
Definition: SPIR.h:255
SPIR64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
Definition: SPIR.h:272
SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
Definition: SPIR.h:234
bool checkArithmeticFenceSupported() const override
Controls if __arithmetic_fence is supported in the targeted backend.
Definition: SPIR.h:250
bool hasFeature(StringRef Feature) const override
Determine whether the given target has the given feature.
Definition: SPIR.h:246
SPIRV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
Definition: SPIR.h:308
SPIRV64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
Definition: SPIR.h:325
bool hasFeature(StringRef Feature) const override
Determine whether the given target has the given feature.
Definition: SPIR.h:301
SPIRVTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
Definition: SPIR.h:289
Defines the clang::TargetInfo interface.
static const unsigned SPIRDefIsPrivMap[]
Definition: SPIR.h:27
static const unsigned SPIRDefIsGenMap[]
Definition: SPIR.h:55
std::unique_ptr< TargetInfo > AllocateTarget(const llvm::Triple &Triple, const TargetOptions &Opts)
Definition: Targets.cpp:111
CallingConv
CallingConv - Specifies the calling convention that a function uses.
Definition: Specifiers.h:269
@ CC_OpenCLKernel
Definition: Specifiers.h:283
@ CC_SpirFunction
Definition: Specifiers.h:282