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