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