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/ADT/Triple.h"
19 #include "llvm/Support/Compiler.h"
24 // Used by both the SPIR and SPIR-V targets.
25 static const unsigned SPIRDefIsPrivMap
[] = {
32 5, // opencl_global_device
33 6, // opencl_global_host
37 // SYCL address space values for this map are dummy
39 0, // sycl_global_device
40 0, // sycl_global_host
48 // Used by both the SPIR and SPIR-V targets.
49 static const unsigned SPIRDefIsGenMap
[] = {
51 // OpenCL address space values for this map are dummy and they can't be used
57 0, // opencl_global_device
58 0, // opencl_global_host
59 // cuda_* address space mapping is intended for HIPSPV (HIP to SPIR-V
60 // translation). This mapping is enabled when the language mode is HIP.
62 // cuda_constant pointer can be casted to default/"flat" pointer, but in
63 // SPIR-V casts between constant and generic pointers are not allowed. For
64 // this reason cuda_constant is mapped to SPIR-V CrossWorkgroup.
68 5, // sycl_global_device
69 6, // sycl_global_host
77 // Base class for SPIR and SPIR-V target info.
78 class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo
: public TargetInfo
{
80 BaseSPIRTargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&)
81 : TargetInfo(Triple
) {
82 assert((Triple
.isSPIR() || Triple
.isSPIRV()) &&
83 "Invalid architecture for SPIR or SPIR-V.");
84 assert(getTriple().getOS() == llvm::Triple::UnknownOS
&&
85 "SPIR(-V) target must use unknown OS");
86 assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment
&&
87 "SPIR(-V) target must use unknown environment type");
90 LongWidth
= LongAlign
= 64;
91 AddrSpaceMap
= &SPIRDefIsPrivMap
;
92 UseAddrSpaceMapMangling
= true;
93 HasLegalHalfType
= true;
95 // Define available target features
96 // These must be defined in sorted order!
101 // SPIR supports the half type and the only llvm intrinsic allowed in SPIR is
102 // memcpy as per section 3 of the SPIR spec.
103 bool useFP16ConversionIntrinsics() const override
{ return false; }
105 ArrayRef
<Builtin::Info
> getTargetBuiltins() const override
{ return None
; }
107 const char *getClobbers() const override
{ return ""; }
109 ArrayRef
<const char *> getGCCRegNames() const override
{ return None
; }
111 bool validateAsmConstraint(const char *&Name
,
112 TargetInfo::ConstraintInfo
&info
) const override
{
116 ArrayRef
<TargetInfo::GCCRegAlias
> getGCCRegAliases() const override
{
120 BuiltinVaListKind
getBuiltinVaListKind() const override
{
121 return TargetInfo::VoidPtrBuiltinVaList
;
125 getDWARFAddressSpace(unsigned AddressSpace
) const override
{
129 CallingConvCheckResult
checkCallingConvention(CallingConv CC
) const override
{
130 return (CC
== CC_SpirFunction
|| CC
== CC_OpenCLKernel
) ? CCCR_OK
134 CallingConv
getDefaultCallingConv() const override
{
135 return CC_SpirFunction
;
138 void setAddressSpaceMap(bool DefaultIsGeneric
) {
139 AddrSpaceMap
= DefaultIsGeneric
? &SPIRDefIsGenMap
: &SPIRDefIsPrivMap
;
142 void adjust(DiagnosticsEngine
&Diags
, LangOptions
&Opts
) override
{
143 TargetInfo::adjust(Diags
, Opts
);
144 // FIXME: SYCL specification considers unannotated pointers and references
145 // to be pointing to the generic address space. See section 5.9.3 of
146 // SYCL 2020 specification.
147 // Currently, there is no way of representing SYCL's and HIP/CUDA's default
148 // address space language semantic along with the semantics of embedded C's
149 // default address space in the same address space map. Hence the map needs
150 // to be reset to allow mapping to the desired value of 'Default' entry for
151 // SYCL and HIP/CUDA.
153 /*DefaultIsGeneric=*/Opts
.SYCLIsDevice
||
154 // The address mapping from HIP/CUDA language for device code is only
155 // defined for SPIR-V.
156 (getTriple().isSPIRV() && Opts
.CUDAIsDevice
));
159 void setSupportedOpenCLOpts() override
{
160 // Assume all OpenCL extensions and optional core features are supported
161 // for SPIR and SPIR-V since they are generic targets.
162 supportAllOpenCLOpts();
165 bool hasBitIntType() const override
{ return true; }
167 bool hasInt128Type() const override
{ return false; }
170 class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo
: public BaseSPIRTargetInfo
{
172 SPIRTargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
173 : BaseSPIRTargetInfo(Triple
, Opts
) {
174 assert(Triple
.isSPIR() && "Invalid architecture for SPIR.");
175 assert(getTriple().getOS() == llvm::Triple::UnknownOS
&&
176 "SPIR target must use unknown OS");
177 assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment
&&
178 "SPIR target must use unknown environment type");
181 void getTargetDefines(const LangOptions
&Opts
,
182 MacroBuilder
&Builder
) const override
;
184 bool hasFeature(StringRef Feature
) const override
{
185 return Feature
== "spir";
189 class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo
: public SPIRTargetInfo
{
191 SPIR32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
192 : SPIRTargetInfo(Triple
, Opts
) {
193 assert(Triple
.getArch() == llvm::Triple::spir
&&
194 "Invalid architecture for 32-bit SPIR.");
195 PointerWidth
= PointerAlign
= 32;
196 SizeType
= TargetInfo::UnsignedInt
;
197 PtrDiffType
= IntPtrType
= TargetInfo::SignedInt
;
198 resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"
199 "v96:128-v192:256-v256:256-v512:512-v1024:1024");
202 void getTargetDefines(const LangOptions
&Opts
,
203 MacroBuilder
&Builder
) const override
;
206 class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo
: public SPIRTargetInfo
{
208 SPIR64TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
209 : SPIRTargetInfo(Triple
, Opts
) {
210 assert(Triple
.getArch() == llvm::Triple::spir64
&&
211 "Invalid architecture for 64-bit SPIR.");
212 PointerWidth
= PointerAlign
= 64;
213 SizeType
= TargetInfo::UnsignedLong
;
214 PtrDiffType
= IntPtrType
= TargetInfo::SignedLong
;
215 resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"
216 "v96:128-v192:256-v256:256-v512:512-v1024:1024");
219 void getTargetDefines(const LangOptions
&Opts
,
220 MacroBuilder
&Builder
) const override
;
223 class LLVM_LIBRARY_VISIBILITY SPIRVTargetInfo
: public BaseSPIRTargetInfo
{
225 SPIRVTargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
226 : BaseSPIRTargetInfo(Triple
, Opts
) {
227 assert(Triple
.isSPIRV() && "Invalid architecture for SPIR-V.");
228 assert(getTriple().getOS() == llvm::Triple::UnknownOS
&&
229 "SPIR-V target must use unknown OS");
230 assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment
&&
231 "SPIR-V target must use unknown environment type");
234 void getTargetDefines(const LangOptions
&Opts
,
235 MacroBuilder
&Builder
) const override
;
237 bool hasFeature(StringRef Feature
) const override
{
238 return Feature
== "spirv";
242 class LLVM_LIBRARY_VISIBILITY SPIRV32TargetInfo
: public SPIRVTargetInfo
{
244 SPIRV32TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
245 : SPIRVTargetInfo(Triple
, Opts
) {
246 assert(Triple
.getArch() == llvm::Triple::spirv32
&&
247 "Invalid architecture for 32-bit SPIR-V.");
248 PointerWidth
= PointerAlign
= 32;
249 SizeType
= TargetInfo::UnsignedInt
;
250 PtrDiffType
= IntPtrType
= TargetInfo::SignedInt
;
251 resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"
252 "v96:128-v192:256-v256:256-v512:512-v1024:1024");
255 void getTargetDefines(const LangOptions
&Opts
,
256 MacroBuilder
&Builder
) const override
;
259 class LLVM_LIBRARY_VISIBILITY SPIRV64TargetInfo
: public SPIRVTargetInfo
{
261 SPIRV64TargetInfo(const llvm::Triple
&Triple
, const TargetOptions
&Opts
)
262 : SPIRVTargetInfo(Triple
, Opts
) {
263 assert(Triple
.getArch() == llvm::Triple::spirv64
&&
264 "Invalid architecture for 64-bit SPIR-V.");
265 PointerWidth
= PointerAlign
= 64;
266 SizeType
= TargetInfo::UnsignedLong
;
267 PtrDiffType
= IntPtrType
= TargetInfo::SignedLong
;
268 resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"
269 "v96:128-v192:256-v256:256-v512:512-v1024:1024");
272 void getTargetDefines(const LangOptions
&Opts
,
273 MacroBuilder
&Builder
) const override
;
276 } // namespace targets
278 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H