clang 20.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/Support/VersionTuple.h"
21#include "llvm/TargetParser/Triple.h"
22#include <optional>
23
24namespace clang {
25namespace targets {
26
27// Used by both the SPIR and SPIR-V targets.
28static const unsigned SPIRDefIsPrivMap[] = {
29 0, // Default
30 1, // opencl_global
31 3, // opencl_local
32 2, // opencl_constant
33 0, // opencl_private
34 4, // opencl_generic
35 5, // opencl_global_device
36 6, // opencl_global_host
37 0, // cuda_device
38 0, // cuda_constant
39 0, // cuda_shared
40 // SYCL address space values for this map are dummy
41 0, // sycl_global
42 0, // sycl_global_device
43 0, // sycl_global_host
44 0, // sycl_local
45 0, // sycl_private
46 0, // ptr32_sptr
47 0, // ptr32_uptr
48 0, // ptr64
49 0, // hlsl_groupshared
50 2, // hlsl_constant
51 // Wasm address space values for this target are dummy values,
52 // as it is only enabled for Wasm targets.
53 20, // wasm_funcref
54};
55
56// Used by both the SPIR and SPIR-V targets.
57static const unsigned SPIRDefIsGenMap[] = {
58 4, // Default
59 // OpenCL address space values for this map are dummy and they can't be used
60 0, // opencl_global
61 0, // opencl_local
62 0, // opencl_constant
63 0, // opencl_private
64 0, // opencl_generic
65 0, // opencl_global_device
66 0, // opencl_global_host
67 // cuda_* address space mapping is intended for HIPSPV (HIP to SPIR-V
68 // translation). This mapping is enabled when the language mode is HIP.
69 1, // cuda_device
70 // cuda_constant pointer can be casted to default/"flat" pointer, but in
71 // SPIR-V casts between constant and generic pointers are not allowed. For
72 // this reason cuda_constant is mapped to SPIR-V CrossWorkgroup.
73 1, // cuda_constant
74 3, // cuda_shared
75 1, // sycl_global
76 5, // sycl_global_device
77 6, // sycl_global_host
78 3, // sycl_local
79 0, // sycl_private
80 0, // ptr32_sptr
81 0, // ptr32_uptr
82 0, // ptr64
83 0, // hlsl_groupshared
84 0, // hlsl_constant
85 // Wasm address space values for this target are dummy values,
86 // as it is only enabled for Wasm targets.
87 20, // wasm_funcref
88};
89
90// Base class for SPIR and SPIR-V target info.
91class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo {
92 std::unique_ptr<TargetInfo> HostTarget;
93
94protected:
95 BaseSPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
96 : TargetInfo(Triple) {
97 assert((Triple.isSPIR() || Triple.isSPIRV()) &&
98 "Invalid architecture for SPIR or SPIR-V.");
99 TLSSupported = false;
100 VLASupported = false;
101 LongWidth = LongAlign = 64;
102 AddrSpaceMap = &SPIRDefIsPrivMap;
103 UseAddrSpaceMapMangling = true;
104 HasLegalHalfType = true;
105 HasFloat16 = true;
106 // Define available target features
107 // These must be defined in sorted order!
108 NoAsmVariants = true;
109
110 llvm::Triple HostTriple(Opts.HostTriple);
111 if (!HostTriple.isSPIR() && !HostTriple.isSPIRV() &&
112 HostTriple.getArch() != llvm::Triple::UnknownArch) {
113 HostTarget = AllocateTarget(llvm::Triple(Opts.HostTriple), Opts);
114
115 // Copy properties from host target.
116 BoolWidth = HostTarget->getBoolWidth();
117 BoolAlign = HostTarget->getBoolAlign();
118 IntWidth = HostTarget->getIntWidth();
119 IntAlign = HostTarget->getIntAlign();
120 HalfWidth = HostTarget->getHalfWidth();
121 HalfAlign = HostTarget->getHalfAlign();
122 FloatWidth = HostTarget->getFloatWidth();
123 FloatAlign = HostTarget->getFloatAlign();
124 DoubleWidth = HostTarget->getDoubleWidth();
125 DoubleAlign = HostTarget->getDoubleAlign();
126 LongWidth = HostTarget->getLongWidth();
127 LongAlign = HostTarget->getLongAlign();
128 LongLongWidth = HostTarget->getLongLongWidth();
129 LongLongAlign = HostTarget->getLongLongAlign();
130 MinGlobalAlign =
131 HostTarget->getMinGlobalAlign(/* TypeSize = */ 0,
132 /* HasNonWeakDef = */ true);
133 NewAlign = HostTarget->getNewAlign();
134 DefaultAlignForAttributeAligned =
135 HostTarget->getDefaultAlignForAttributeAligned();
136 IntMaxType = HostTarget->getIntMaxType();
137 WCharType = HostTarget->getWCharType();
138 WIntType = HostTarget->getWIntType();
139 Char16Type = HostTarget->getChar16Type();
140 Char32Type = HostTarget->getChar32Type();
141 Int64Type = HostTarget->getInt64Type();
142 SigAtomicType = HostTarget->getSigAtomicType();
143 ProcessIDType = HostTarget->getProcessIDType();
144
145 UseBitFieldTypeAlignment = HostTarget->useBitFieldTypeAlignment();
146 UseZeroLengthBitfieldAlignment =
147 HostTarget->useZeroLengthBitfieldAlignment();
148 UseExplicitBitFieldAlignment = HostTarget->useExplicitBitFieldAlignment();
149 ZeroLengthBitfieldBoundary = HostTarget->getZeroLengthBitfieldBoundary();
150
151 // This is a bit of a lie, but it controls __GCC_ATOMIC_XXX_LOCK_FREE, and
152 // we need those macros to be identical on host and device, because (among
153 // other things) they affect which standard library classes are defined,
154 // and we need all classes to be defined on both the host and device.
155 MaxAtomicInlineWidth = HostTarget->getMaxAtomicInlineWidth();
156 }
157 }
158
159public:
160 // SPIR supports the half type and the only llvm intrinsic allowed in SPIR is
161 // memcpy as per section 3 of the SPIR spec.
162 bool useFP16ConversionIntrinsics() const override { return false; }
163
164 ArrayRef<Builtin::Info> getTargetBuiltins() const override { return {}; }
165
166 std::string_view getClobbers() const override { return ""; }
167
168 ArrayRef<const char *> getGCCRegNames() const override { return {}; }
169
170 bool validateAsmConstraint(const char *&Name,
171 TargetInfo::ConstraintInfo &info) const override {
172 return true;
173 }
174
176 return {};
177 }
178
180 return TargetInfo::VoidPtrBuiltinVaList;
181 }
182
183 std::optional<unsigned>
184 getDWARFAddressSpace(unsigned AddressSpace) const override {
185 return AddressSpace;
186 }
187
189 return (CC == CC_SpirFunction || CC == CC_OpenCLKernel) ? CCCR_OK
190 : CCCR_Warning;
191 }
192
194 return CC_SpirFunction;
195 }
196
197 void setAddressSpaceMap(bool DefaultIsGeneric) {
198 AddrSpaceMap = DefaultIsGeneric ? &SPIRDefIsGenMap : &SPIRDefIsPrivMap;
199 }
200
201 void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override {
202 TargetInfo::adjust(Diags, Opts);
203 // FIXME: SYCL specification considers unannotated pointers and references
204 // to be pointing to the generic address space. See section 5.9.3 of
205 // SYCL 2020 specification.
206 // Currently, there is no way of representing SYCL's and HIP/CUDA's default
207 // address space language semantic along with the semantics of embedded C's
208 // default address space in the same address space map. Hence the map needs
209 // to be reset to allow mapping to the desired value of 'Default' entry for
210 // SYCL and HIP/CUDA.
211 setAddressSpaceMap(
212 /*DefaultIsGeneric=*/Opts.SYCLIsDevice ||
213 // The address mapping from HIP/CUDA language for device code is only
214 // defined for SPIR-V.
215 (getTriple().isSPIRV() && Opts.CUDAIsDevice));
216 }
217
218 void setSupportedOpenCLOpts() override {
219 // Assume all OpenCL extensions and optional core features are supported
220 // for SPIR and SPIR-V since they are generic targets.
221 supportAllOpenCLOpts();
222 }
223
224 bool hasBitIntType() const override { return true; }
225
226 bool hasInt128Type() const override { return false; }
227};
228
229class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public BaseSPIRTargetInfo {
230public:
231 SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
232 : BaseSPIRTargetInfo(Triple, Opts) {
233 assert(Triple.isSPIR() && "Invalid architecture for SPIR.");
234 assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
235 "SPIR target must use unknown OS");
236 assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
237 "SPIR target must use unknown environment type");
238 }
239
240 void getTargetDefines(const LangOptions &Opts,
241 MacroBuilder &Builder) const override;
242
243 bool hasFeature(StringRef Feature) const override {
244 return Feature == "spir";
245 }
246
247 bool checkArithmeticFenceSupported() const override { return true; }
248};
249
250class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo {
251public:
252 SPIR32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
253 : SPIRTargetInfo(Triple, Opts) {
254 assert(Triple.getArch() == llvm::Triple::spir &&
255 "Invalid architecture for 32-bit SPIR.");
256 PointerWidth = PointerAlign = 32;
257 SizeType = TargetInfo::UnsignedInt;
258 PtrDiffType = IntPtrType = TargetInfo::SignedInt;
259 resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"
260 "v96:128-v192:256-v256:256-v512:512-v1024:1024-G1");
261 }
262
263 void getTargetDefines(const LangOptions &Opts,
264 MacroBuilder &Builder) const override;
265};
266
267class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo : public SPIRTargetInfo {
268public:
269 SPIR64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
270 : SPIRTargetInfo(Triple, Opts) {
271 assert(Triple.getArch() == llvm::Triple::spir64 &&
272 "Invalid architecture for 64-bit SPIR.");
273 PointerWidth = PointerAlign = 64;
274 SizeType = TargetInfo::UnsignedLong;
275 PtrDiffType = IntPtrType = TargetInfo::SignedLong;
276 resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"
277 "v96:128-v192:256-v256:256-v512:512-v1024:1024-G1");
278 }
279
280 void getTargetDefines(const LangOptions &Opts,
281 MacroBuilder &Builder) const override;
282};
283
284class LLVM_LIBRARY_VISIBILITY BaseSPIRVTargetInfo : public BaseSPIRTargetInfo {
285public:
286 BaseSPIRVTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
287 : BaseSPIRTargetInfo(Triple, Opts) {
288 assert(Triple.isSPIRV() && "Invalid architecture for SPIR-V.");
289 }
290
291 bool hasFeature(StringRef Feature) const override {
292 return Feature == "spirv";
293 }
294
295 void getTargetDefines(const LangOptions &Opts,
296 MacroBuilder &Builder) const override;
297};
298
299class LLVM_LIBRARY_VISIBILITY SPIRVTargetInfo : public BaseSPIRVTargetInfo {
300public:
301 SPIRVTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
302 : BaseSPIRVTargetInfo(Triple, Opts) {
303 assert(Triple.getArch() == llvm::Triple::spirv &&
304 "Invalid architecture for Logical SPIR-V.");
305 assert(Triple.getOS() == llvm::Triple::Vulkan &&
306 Triple.getVulkanVersion() != llvm::VersionTuple(0) &&
307 "Logical SPIR-V requires a valid Vulkan environment.");
308 assert(Triple.getEnvironment() >= llvm::Triple::Pixel &&
309 Triple.getEnvironment() <= llvm::Triple::Amplification &&
310 "Logical SPIR-V environment must be a valid shader stage.");
311 PointerWidth = PointerAlign = 64;
312
313 // SPIR-V IDs are represented with a single 32-bit word.
314 SizeType = TargetInfo::UnsignedInt;
315 resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-"
316 "v256:256-v512:512-v1024:1024-n8:16:32:64-G1");
317 }
318 ArrayRef<Builtin::Info> getTargetBuiltins() const override;
319 void getTargetDefines(const LangOptions &Opts,
320 MacroBuilder &Builder) const override;
321};
322
323class LLVM_LIBRARY_VISIBILITY SPIRV32TargetInfo : public BaseSPIRVTargetInfo {
324public:
325 SPIRV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
326 : BaseSPIRVTargetInfo(Triple, Opts) {
327 assert(Triple.getArch() == llvm::Triple::spirv32 &&
328 "Invalid architecture for 32-bit SPIR-V.");
329 assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
330 "32-bit SPIR-V target must use unknown OS");
331 assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
332 "32-bit SPIR-V target must use unknown environment type");
333 PointerWidth = PointerAlign = 32;
334 SizeType = TargetInfo::UnsignedInt;
335 PtrDiffType = IntPtrType = TargetInfo::SignedInt;
336 // SPIR-V has core support for atomic ops, and Int32 is always available;
337 // we take the maximum because it's possible the Host supports wider types.
338 MaxAtomicInlineWidth = std::max<unsigned char>(MaxAtomicInlineWidth, 32);
339 resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-"
340 "v192:256-v256:256-v512:512-v1024:1024-n8:16:32:64-G1");
341 }
342
343 void getTargetDefines(const LangOptions &Opts,
344 MacroBuilder &Builder) const override;
345};
346
347class LLVM_LIBRARY_VISIBILITY SPIRV64TargetInfo : public BaseSPIRVTargetInfo {
348public:
349 SPIRV64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
350 : BaseSPIRVTargetInfo(Triple, Opts) {
351 assert(Triple.getArch() == llvm::Triple::spirv64 &&
352 "Invalid architecture for 64-bit SPIR-V.");
353 assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
354 "64-bit SPIR-V target must use unknown OS");
355 assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
356 "64-bit SPIR-V target must use unknown environment type");
357 PointerWidth = PointerAlign = 64;
358 SizeType = TargetInfo::UnsignedLong;
359 PtrDiffType = IntPtrType = TargetInfo::SignedLong;
360 // SPIR-V has core support for atomic ops, and Int64 is always available;
361 // we take the maximum because it's possible the Host supports wider types.
362 MaxAtomicInlineWidth = std::max<unsigned char>(MaxAtomicInlineWidth, 64);
363 resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-"
364 "v256:256-v512:512-v1024:1024-n8:16:32:64-G1");
365 }
366
367 void getTargetDefines(const LangOptions &Opts,
368 MacroBuilder &Builder) const override;
369};
370
371class LLVM_LIBRARY_VISIBILITY SPIRV64AMDGCNTargetInfo final
372 : public BaseSPIRVTargetInfo {
373public:
374 SPIRV64AMDGCNTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
375 : BaseSPIRVTargetInfo(Triple, Opts) {
376 assert(Triple.getArch() == llvm::Triple::spirv64 &&
377 "Invalid architecture for 64-bit AMDGCN SPIR-V.");
378 assert(Triple.getVendor() == llvm::Triple::VendorType::AMD &&
379 "64-bit AMDGCN SPIR-V target must use AMD vendor");
380 assert(getTriple().getOS() == llvm::Triple::OSType::AMDHSA &&
381 "64-bit AMDGCN SPIR-V target must use AMDHSA OS");
382 assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
383 "64-bit SPIR-V target must use unknown environment type");
384 PointerWidth = PointerAlign = 64;
385 SizeType = TargetInfo::UnsignedLong;
386 PtrDiffType = IntPtrType = TargetInfo::SignedLong;
387 AddrSpaceMap = &SPIRDefIsGenMap;
388
389 resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-"
390 "v256:256-v512:512-v1024:1024-n32:64-S32-G1-P4-A0");
391
392 BFloat16Width = BFloat16Align = 16;
393 BFloat16Format = &llvm::APFloat::BFloat();
394
395 HasLegalHalfType = true;
396 HasFloat16 = true;
397 HalfArgsAndReturns = true;
398 }
399
400 bool hasBFloat16Type() const override { return true; }
401
402 ArrayRef<const char *> getGCCRegNames() const override;
403
404 bool initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
405 StringRef,
406 const std::vector<std::string> &) const override;
407
408 bool validateAsmConstraint(const char *&Name,
409 TargetInfo::ConstraintInfo &Info) const override;
410
411 std::string convertConstraint(const char *&Constraint) const override;
412
413 ArrayRef<Builtin::Info> getTargetBuiltins() const override;
414
415 void getTargetDefines(const LangOptions &Opts,
416 MacroBuilder &Builder) const override;
417
418 void setAuxTarget(const TargetInfo *Aux) override;
419
420 void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override {
421 TargetInfo::adjust(Diags, Opts);
422 }
423
424 bool hasInt128Type() const override { return TargetInfo::hasInt128Type(); }
425};
426
427} // namespace targets
428} // namespace clang
429#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:231
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:500
Exposes information about the current target.
Definition: TargetInfo.h:220
BuiltinVaListKind
The different kinds of __builtin_va_list types defined by the target implementation.
Definition: TargetInfo.h:318
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:164
BuiltinVaListKind getBuiltinVaListKind() const override
Returns the kind of __builtin_va_list type that should be used with this target.
Definition: SPIR.h:179
ArrayRef< const char * > getGCCRegNames() const override
Definition: SPIR.h:168
void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override
Set forced language options.
Definition: SPIR.h:201
bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &info) const override
Definition: SPIR.h:170
bool hasInt128Type() const override
Determine whether the __int128 type is supported on this target.
Definition: SPIR.h:226
void setAddressSpaceMap(bool DefaultIsGeneric)
Definition: SPIR.h:197
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:162
ArrayRef< TargetInfo::GCCRegAlias > getGCCRegAliases() const override
Definition: SPIR.h:175
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override
Determines whether a given calling convention is valid for the target.
Definition: SPIR.h:188
std::optional< unsigned > getDWARFAddressSpace(unsigned AddressSpace) const override
Definition: SPIR.h:184
BaseSPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
Definition: SPIR.h:95
bool hasBitIntType() const override
Determine whether the _BitInt type is supported on this target.
Definition: SPIR.h:224
void setSupportedOpenCLOpts() override
Set supported OpenCL extensions and optional core features.
Definition: SPIR.h:218
std::string_view getClobbers() const override
Returns a string of target-specific clobbers, in LLVM format.
Definition: SPIR.h:166
CallingConv getDefaultCallingConv() const override
Gets the default calling convention for the given target and declaration context.
Definition: SPIR.h:193
bool hasFeature(StringRef Feature) const override
Determine whether the given target has the given feature.
Definition: SPIR.h:291
BaseSPIRVTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
Definition: SPIR.h:286
SPIR32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
Definition: SPIR.h:252
SPIR64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
Definition: SPIR.h:269
SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
Definition: SPIR.h:231
bool checkArithmeticFenceSupported() const override
Controls if __arithmetic_fence is supported in the targeted backend.
Definition: SPIR.h:247
bool hasFeature(StringRef Feature) const override
Determine whether the given target has the given feature.
Definition: SPIR.h:243
SPIRV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
Definition: SPIR.h:325
void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override
Set forced language options.
Definition: SPIR.h:420
bool hasInt128Type() const override
Determine whether the __int128 type is supported on this target.
Definition: SPIR.h:424
bool hasBFloat16Type() const override
Determine whether the _BFloat16 type is supported on this target.
Definition: SPIR.h:400
SPIRV64AMDGCNTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
Definition: SPIR.h:374
SPIRV64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
Definition: SPIR.h:349
SPIRVTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
Definition: SPIR.h:301
Defines the clang::TargetInfo interface.
static const unsigned SPIRDefIsPrivMap[]
Definition: SPIR.h:28
static const unsigned SPIRDefIsGenMap[]
Definition: SPIR.h:57
std::unique_ptr< clang::TargetInfo > AllocateTarget(const llvm::Triple &Triple, const clang::TargetOptions &Opts)
Definition: Targets.cpp:112
The JSON file list parser is used to communicate input to InstallAPI.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
Definition: Specifiers.h:278
@ CC_OpenCLKernel
Definition: Specifiers.h:292
@ CC_SpirFunction
Definition: Specifiers.h:291