1 //===--- SPIR.h - Declare SPIR and SPIR-V target feature support *- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
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 "clang/Basic/TargetInfo.h"
17 #include "clang/Basic/TargetOptions.h"
18 #include "llvm/Support/Compiler.h"
19 #include "llvm/TargetParser/Triple.h"
25 // Used by both the SPIR and SPIR-V targets.
26 static const unsigned SPIRDefIsPrivMap
[] = {
33 5, // opencl_global_device
34 6, // opencl_global_host
38 // SYCL address space values for this map are dummy
40 0, // sycl_global_device
41 0, // sycl_global_host
47 0, // hlsl_groupshared
50 // Used by both the SPIR and SPIR-V targets.
51 static const unsigned SPIRDefIsGenMap
[] = {
53 // OpenCL address space values for this map are dummy and they can't be used
59 0, // opencl_global_device
60 0, // opencl_global_host
61 // cuda_* address space mapping is intended for HIPSPV (HIP to SPIR-V
62 // translation). This mapping is enabled when the language mode is HIP.
64 // cuda_constant pointer can be casted to default/"flat" pointer, but in
65 // SPIR-V casts between constant and generic pointers are not allowed. For
66 // this reason cuda_constant is mapped to SPIR-V CrossWorkgroup.
70 5, // sycl_global_device
71 6, // sycl_global_host
77 0, // hlsl_groupshared
80 // Base class for SPIR and SPIR-V target info.
81 class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo
: public TargetInfo
{
83 BaseSPIRTargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&)
84 : TargetInfo(Triple
) {
85 assert((Triple
.isSPIR() || Triple
.isSPIRV()) &&
86 "Invalid architecture for SPIR or SPIR-V.");
87 assert(getTriple().getOS() == llvm::Triple::UnknownOS
&&
88 "SPIR(-V) target must use unknown OS");
89 assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment
&&
90 "SPIR(-V) target must use unknown environment type");
93 LongWidth
= LongAlign
= 64;
94 AddrSpaceMap
= &SPIRDefIsPrivMap
;
95 UseAddrSpaceMapMangling
= true;
96 HasLegalHalfType
= true;
98 // Define available target features
99 // These must be defined in sorted order!
100 NoAsmVariants
= true;
104 // SPIR supports the half type and the only llvm intrinsic allowed in SPIR is
105 // memcpy as per section 3 of the SPIR spec.
106 bool useFP16ConversionIntrinsics() const override
{ return false; }
108 ArrayRef
<Builtin::Info
> getTargetBuiltins() const override
{
112 const char *getClobbers() const override
{ return ""; }
114 ArrayRef
<const char *> getGCCRegNames() const override
{
118 bool validateAsmConstraint(const char *&Name
,
119 TargetInfo::ConstraintInfo
&info
) const override
{
123 ArrayRef
<TargetInfo::GCCRegAlias
> getGCCRegAliases() const override
{
127 BuiltinVaListKind
getBuiltinVaListKind() const override
{
128 return TargetInfo::VoidPtrBuiltinVaList
;
131 std::optional
<unsigned>
132 getDWARFAddressSpace(unsigned AddressSpace
) const override
{
136 CallingConvCheckResult
checkCallingConvention(CallingConv CC
) const override
{
137 return (CC
== CC_SpirFunction
|| CC
== CC_OpenCLKernel
) ? CCCR_OK
141 CallingConv
getDefaultCallingConv() const override
{
142 return CC_SpirFunction
;
145 void setAddressSpaceMap(bool DefaultIsGeneric
) {
146 AddrSpaceMap
= DefaultIsGeneric
? &SPIRDefIsGenMap
: &SPIRDefIsPrivMap
;
149 void adjust(DiagnosticsEngine
&Diags
, LangOptions
&Opts
) override
{
150 TargetInfo::adjust(Diags
, Opts
);
151 // FIXME: SYCL specification considers unannotated pointers and references
152 // to be pointing to the generic address space. See section 5.9.3 of
153 // SYCL 2020 specification.
154 // Currently, there is no way of representing SYCL's and HIP/CUDA's default
155 // address space language semantic along with the semantics of embedded C's
156 // default address space in the same address space map. Hence the map needs
157 // to be reset to allow mapping to the desired value of 'Default' entry for
158 // SYCL and HIP/CUDA.
160 /*DefaultIsGeneric=*/Opts
.SYCLIsDevice
||
161 // The address mapping from HIP/CUDA language for device code is only
162 // defined for SPIR-V.
163 (getTriple().isSPIRV() && Opts
.CUDAIsDevice
));
166 void setSupportedOpenCLOpts() override
{
167 // Assume all OpenCL extensions and optional core features are supported
168 // for SPIR and SPIR-V since they are generic targets.
169 supportAllOpenCLOpts();
172 bool hasBitIntType() const override
{ return true; }
174 bool hasInt128Type() const override
{ return false; }
177 class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo
: public BaseSPIRTargetInfo
{
179 SPIRTargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
180 : BaseSPIRTargetInfo(Triple
, Opts
) {
181 assert(Triple
.isSPIR() && "Invalid architecture for SPIR.");
182 assert(getTriple().getOS() == llvm::Triple::UnknownOS
&&
183 "SPIR target must use unknown OS");
184 assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment
&&
185 "SPIR target must use unknown environment type");
188 void getTargetDefines(const LangOptions
&Opts
,
189 MacroBuilder
&Builder
) const override
;
191 bool hasFeature(StringRef Feature
) const override
{
192 return Feature
== "spir";
195 bool checkArithmeticFenceSupported() const override
{ return true; }
198 class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo
: public SPIRTargetInfo
{
200 SPIR32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
201 : SPIRTargetInfo(Triple
, Opts
) {
202 assert(Triple
.getArch() == llvm::Triple::spir
&&
203 "Invalid architecture for 32-bit SPIR.");
204 PointerWidth
= PointerAlign
= 32;
205 SizeType
= TargetInfo::UnsignedInt
;
206 PtrDiffType
= IntPtrType
= TargetInfo::SignedInt
;
207 resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"
208 "v96:128-v192:256-v256:256-v512:512-v1024:1024");
211 void getTargetDefines(const LangOptions
&Opts
,
212 MacroBuilder
&Builder
) const override
;
215 class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo
: public SPIRTargetInfo
{
217 SPIR64TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
218 : SPIRTargetInfo(Triple
, Opts
) {
219 assert(Triple
.getArch() == llvm::Triple::spir64
&&
220 "Invalid architecture for 64-bit SPIR.");
221 PointerWidth
= PointerAlign
= 64;
222 SizeType
= TargetInfo::UnsignedLong
;
223 PtrDiffType
= IntPtrType
= TargetInfo::SignedLong
;
224 resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"
225 "v96:128-v192:256-v256:256-v512:512-v1024:1024");
228 void getTargetDefines(const LangOptions
&Opts
,
229 MacroBuilder
&Builder
) const override
;
232 class LLVM_LIBRARY_VISIBILITY SPIRVTargetInfo
: public BaseSPIRTargetInfo
{
234 SPIRVTargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
235 : BaseSPIRTargetInfo(Triple
, Opts
) {
236 assert(Triple
.isSPIRV() && "Invalid architecture for SPIR-V.");
237 assert(getTriple().getOS() == llvm::Triple::UnknownOS
&&
238 "SPIR-V target must use unknown OS");
239 assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment
&&
240 "SPIR-V target must use unknown environment type");
243 void getTargetDefines(const LangOptions
&Opts
,
244 MacroBuilder
&Builder
) const override
;
246 bool hasFeature(StringRef Feature
) const override
{
247 return Feature
== "spirv";
251 class LLVM_LIBRARY_VISIBILITY SPIRV32TargetInfo
: public SPIRVTargetInfo
{
253 SPIRV32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
254 : SPIRVTargetInfo(Triple
, Opts
) {
255 assert(Triple
.getArch() == llvm::Triple::spirv32
&&
256 "Invalid architecture for 32-bit SPIR-V.");
257 PointerWidth
= PointerAlign
= 32;
258 SizeType
= TargetInfo::UnsignedInt
;
259 PtrDiffType
= IntPtrType
= TargetInfo::SignedInt
;
260 resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"
261 "v96:128-v192:256-v256:256-v512:512-v1024:1024");
264 void getTargetDefines(const LangOptions
&Opts
,
265 MacroBuilder
&Builder
) const override
;
268 class LLVM_LIBRARY_VISIBILITY SPIRV64TargetInfo
: public SPIRVTargetInfo
{
270 SPIRV64TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
271 : SPIRVTargetInfo(Triple
, Opts
) {
272 assert(Triple
.getArch() == llvm::Triple::spirv64
&&
273 "Invalid architecture for 64-bit SPIR-V.");
274 PointerWidth
= PointerAlign
= 64;
275 SizeType
= TargetInfo::UnsignedLong
;
276 PtrDiffType
= IntPtrType
= TargetInfo::SignedLong
;
277 resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"
278 "v96:128-v192:256-v256:256-v512:512-v1024:1024");
281 void getTargetDefines(const LangOptions
&Opts
,
282 MacroBuilder
&Builder
) const override
;
285 } // namespace targets
287 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H