xref: /openbsd-src/gnu/llvm/clang/lib/Basic/Targets/SPIR.h (revision 12c855180aad702bbcca06e0398d774beeafb155)
1*12c85518Srobert //===--- SPIR.h - Declare SPIR and SPIR-V target feature support *- C++ -*-===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick //
9*12c85518Srobert // This file declares SPIR and SPIR-V TargetInfo objects.
10e5dd7070Spatrick //
11e5dd7070Spatrick //===----------------------------------------------------------------------===//
12e5dd7070Spatrick 
13e5dd7070Spatrick #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H
14e5dd7070Spatrick #define LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H
15e5dd7070Spatrick 
16e5dd7070Spatrick #include "clang/Basic/TargetInfo.h"
17e5dd7070Spatrick #include "clang/Basic/TargetOptions.h"
18e5dd7070Spatrick #include "llvm/ADT/Triple.h"
19e5dd7070Spatrick #include "llvm/Support/Compiler.h"
20*12c85518Srobert #include <optional>
21e5dd7070Spatrick 
22e5dd7070Spatrick namespace clang {
23e5dd7070Spatrick namespace targets {
24e5dd7070Spatrick 
25*12c85518Srobert // Used by both the SPIR and SPIR-V targets.
26a9ac8606Spatrick static const unsigned SPIRDefIsPrivMap[] = {
27e5dd7070Spatrick     0, // Default
28e5dd7070Spatrick     1, // opencl_global
29e5dd7070Spatrick     3, // opencl_local
30e5dd7070Spatrick     2, // opencl_constant
31e5dd7070Spatrick     0, // opencl_private
32e5dd7070Spatrick     4, // opencl_generic
33a9ac8606Spatrick     5, // opencl_global_device
34a9ac8606Spatrick     6, // opencl_global_host
35e5dd7070Spatrick     0, // cuda_device
36e5dd7070Spatrick     0, // cuda_constant
37e5dd7070Spatrick     0, // cuda_shared
38a9ac8606Spatrick     // SYCL address space values for this map are dummy
39a9ac8606Spatrick     0, // sycl_global
40a9ac8606Spatrick     0, // sycl_global_device
41a9ac8606Spatrick     0, // sycl_global_host
42a9ac8606Spatrick     0, // sycl_local
43a9ac8606Spatrick     0, // sycl_private
44a9ac8606Spatrick     0, // ptr32_sptr
45a9ac8606Spatrick     0, // ptr32_uptr
46*12c85518Srobert     0, // ptr64
47*12c85518Srobert     0, // hlsl_groupshared
48a9ac8606Spatrick };
49a9ac8606Spatrick 
50*12c85518Srobert // Used by both the SPIR and SPIR-V targets.
51a9ac8606Spatrick static const unsigned SPIRDefIsGenMap[] = {
52a9ac8606Spatrick     4, // Default
53a9ac8606Spatrick     // OpenCL address space values for this map are dummy and they can't be used
54a9ac8606Spatrick     0, // opencl_global
55a9ac8606Spatrick     0, // opencl_local
56a9ac8606Spatrick     0, // opencl_constant
57a9ac8606Spatrick     0, // opencl_private
58a9ac8606Spatrick     0, // opencl_generic
59a9ac8606Spatrick     0, // opencl_global_device
60a9ac8606Spatrick     0, // opencl_global_host
61*12c85518Srobert     // cuda_* address space mapping is intended for HIPSPV (HIP to SPIR-V
62*12c85518Srobert     // translation). This mapping is enabled when the language mode is HIP.
63*12c85518Srobert     1, // cuda_device
64*12c85518Srobert     // cuda_constant pointer can be casted to default/"flat" pointer, but in
65*12c85518Srobert     // SPIR-V casts between constant and generic pointers are not allowed. For
66*12c85518Srobert     // this reason cuda_constant is mapped to SPIR-V CrossWorkgroup.
67*12c85518Srobert     1, // cuda_constant
68*12c85518Srobert     3, // cuda_shared
69a9ac8606Spatrick     1, // sycl_global
70a9ac8606Spatrick     5, // sycl_global_device
71a9ac8606Spatrick     6, // sycl_global_host
72a9ac8606Spatrick     3, // sycl_local
73a9ac8606Spatrick     0, // sycl_private
74e5dd7070Spatrick     0, // ptr32_sptr
75e5dd7070Spatrick     0, // ptr32_uptr
76*12c85518Srobert     0, // ptr64
77*12c85518Srobert     0, // hlsl_groupshared
78e5dd7070Spatrick };
79e5dd7070Spatrick 
80*12c85518Srobert // Base class for SPIR and SPIR-V target info.
81*12c85518Srobert class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo {
82*12c85518Srobert protected:
BaseSPIRTargetInfo(const llvm::Triple & Triple,const TargetOptions &)83*12c85518Srobert   BaseSPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
84e5dd7070Spatrick       : TargetInfo(Triple) {
85*12c85518Srobert     assert((Triple.isSPIR() || Triple.isSPIRV()) &&
86*12c85518Srobert            "Invalid architecture for SPIR or SPIR-V.");
87e5dd7070Spatrick     assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
88*12c85518Srobert            "SPIR(-V) target must use unknown OS");
89e5dd7070Spatrick     assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
90*12c85518Srobert            "SPIR(-V) target must use unknown environment type");
91e5dd7070Spatrick     TLSSupported = false;
92e5dd7070Spatrick     VLASupported = false;
93e5dd7070Spatrick     LongWidth = LongAlign = 64;
94a9ac8606Spatrick     AddrSpaceMap = &SPIRDefIsPrivMap;
95e5dd7070Spatrick     UseAddrSpaceMapMangling = true;
96e5dd7070Spatrick     HasLegalHalfType = true;
97e5dd7070Spatrick     HasFloat16 = true;
98e5dd7070Spatrick     // Define available target features
99e5dd7070Spatrick     // These must be defined in sorted order!
100e5dd7070Spatrick     NoAsmVariants = true;
101e5dd7070Spatrick   }
102e5dd7070Spatrick 
103*12c85518Srobert public:
104e5dd7070Spatrick   // SPIR supports the half type and the only llvm intrinsic allowed in SPIR is
105e5dd7070Spatrick   // memcpy as per section 3 of the SPIR spec.
useFP16ConversionIntrinsics()106e5dd7070Spatrick   bool useFP16ConversionIntrinsics() const override { return false; }
107e5dd7070Spatrick 
getTargetBuiltins()108*12c85518Srobert   ArrayRef<Builtin::Info> getTargetBuiltins() const override {
109*12c85518Srobert     return std::nullopt;
110*12c85518Srobert   }
111e5dd7070Spatrick 
getClobbers()112e5dd7070Spatrick   const char *getClobbers() const override { return ""; }
113e5dd7070Spatrick 
getGCCRegNames()114*12c85518Srobert   ArrayRef<const char *> getGCCRegNames() const override {
115*12c85518Srobert     return std::nullopt;
116*12c85518Srobert   }
117e5dd7070Spatrick 
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & info)118e5dd7070Spatrick   bool validateAsmConstraint(const char *&Name,
119e5dd7070Spatrick                              TargetInfo::ConstraintInfo &info) const override {
120e5dd7070Spatrick     return true;
121e5dd7070Spatrick   }
122e5dd7070Spatrick 
getGCCRegAliases()123e5dd7070Spatrick   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
124*12c85518Srobert     return std::nullopt;
125e5dd7070Spatrick   }
126e5dd7070Spatrick 
getBuiltinVaListKind()127e5dd7070Spatrick   BuiltinVaListKind getBuiltinVaListKind() const override {
128e5dd7070Spatrick     return TargetInfo::VoidPtrBuiltinVaList;
129e5dd7070Spatrick   }
130e5dd7070Spatrick 
131*12c85518Srobert   std::optional<unsigned>
getDWARFAddressSpace(unsigned AddressSpace)132a9ac8606Spatrick   getDWARFAddressSpace(unsigned AddressSpace) const override {
133a9ac8606Spatrick     return AddressSpace;
134a9ac8606Spatrick   }
135a9ac8606Spatrick 
checkCallingConvention(CallingConv CC)136e5dd7070Spatrick   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
137e5dd7070Spatrick     return (CC == CC_SpirFunction || CC == CC_OpenCLKernel) ? CCCR_OK
138e5dd7070Spatrick                                                             : CCCR_Warning;
139e5dd7070Spatrick   }
140e5dd7070Spatrick 
getDefaultCallingConv()141e5dd7070Spatrick   CallingConv getDefaultCallingConv() const override {
142e5dd7070Spatrick     return CC_SpirFunction;
143e5dd7070Spatrick   }
144e5dd7070Spatrick 
setAddressSpaceMap(bool DefaultIsGeneric)145a9ac8606Spatrick   void setAddressSpaceMap(bool DefaultIsGeneric) {
146a9ac8606Spatrick     AddrSpaceMap = DefaultIsGeneric ? &SPIRDefIsGenMap : &SPIRDefIsPrivMap;
147a9ac8606Spatrick   }
148a9ac8606Spatrick 
adjust(DiagnosticsEngine & Diags,LangOptions & Opts)149a9ac8606Spatrick   void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override {
150a9ac8606Spatrick     TargetInfo::adjust(Diags, Opts);
151a9ac8606Spatrick     // FIXME: SYCL specification considers unannotated pointers and references
152a9ac8606Spatrick     // to be pointing to the generic address space. See section 5.9.3 of
153a9ac8606Spatrick     // SYCL 2020 specification.
154*12c85518Srobert     // Currently, there is no way of representing SYCL's and HIP/CUDA's default
155*12c85518Srobert     // address space language semantic along with the semantics of embedded C's
156*12c85518Srobert     // default address space in the same address space map. Hence the map needs
157*12c85518Srobert     // to be reset to allow mapping to the desired value of 'Default' entry for
158*12c85518Srobert     // SYCL and HIP/CUDA.
159*12c85518Srobert     setAddressSpaceMap(
160*12c85518Srobert         /*DefaultIsGeneric=*/Opts.SYCLIsDevice ||
161*12c85518Srobert         // The address mapping from HIP/CUDA language for device code is only
162*12c85518Srobert         // defined for SPIR-V.
163*12c85518Srobert         (getTriple().isSPIRV() && Opts.CUDAIsDevice));
164a9ac8606Spatrick   }
165a9ac8606Spatrick 
setSupportedOpenCLOpts()166e5dd7070Spatrick   void setSupportedOpenCLOpts() override {
167e5dd7070Spatrick     // Assume all OpenCL extensions and optional core features are supported
168*12c85518Srobert     // for SPIR and SPIR-V since they are generic targets.
169a9ac8606Spatrick     supportAllOpenCLOpts();
170e5dd7070Spatrick   }
171ec727ea7Spatrick 
hasBitIntType()172*12c85518Srobert   bool hasBitIntType() const override { return true; }
173a9ac8606Spatrick 
hasInt128Type()174a9ac8606Spatrick   bool hasInt128Type() const override { return false; }
175e5dd7070Spatrick };
176a9ac8606Spatrick 
177*12c85518Srobert class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public BaseSPIRTargetInfo {
178*12c85518Srobert public:
SPIRTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)179*12c85518Srobert   SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
180*12c85518Srobert       : BaseSPIRTargetInfo(Triple, Opts) {
181*12c85518Srobert     assert(Triple.isSPIR() && "Invalid architecture for SPIR.");
182*12c85518Srobert     assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
183*12c85518Srobert            "SPIR target must use unknown OS");
184*12c85518Srobert     assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
185*12c85518Srobert            "SPIR target must use unknown environment type");
186*12c85518Srobert   }
187*12c85518Srobert 
188*12c85518Srobert   void getTargetDefines(const LangOptions &Opts,
189*12c85518Srobert                         MacroBuilder &Builder) const override;
190*12c85518Srobert 
hasFeature(StringRef Feature)191*12c85518Srobert   bool hasFeature(StringRef Feature) const override {
192*12c85518Srobert     return Feature == "spir";
193*12c85518Srobert   }
194*12c85518Srobert };
195*12c85518Srobert 
196e5dd7070Spatrick class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo {
197e5dd7070Spatrick public:
SPIR32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)198e5dd7070Spatrick   SPIR32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
199e5dd7070Spatrick       : SPIRTargetInfo(Triple, Opts) {
200*12c85518Srobert     assert(Triple.getArch() == llvm::Triple::spir &&
201*12c85518Srobert            "Invalid architecture for 32-bit SPIR.");
202e5dd7070Spatrick     PointerWidth = PointerAlign = 32;
203e5dd7070Spatrick     SizeType = TargetInfo::UnsignedInt;
204e5dd7070Spatrick     PtrDiffType = IntPtrType = TargetInfo::SignedInt;
205e5dd7070Spatrick     resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"
206e5dd7070Spatrick                     "v96:128-v192:256-v256:256-v512:512-v1024:1024");
207e5dd7070Spatrick   }
208e5dd7070Spatrick 
209e5dd7070Spatrick   void getTargetDefines(const LangOptions &Opts,
210e5dd7070Spatrick                         MacroBuilder &Builder) const override;
211e5dd7070Spatrick };
212e5dd7070Spatrick 
213e5dd7070Spatrick class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo : public SPIRTargetInfo {
214e5dd7070Spatrick public:
SPIR64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)215e5dd7070Spatrick   SPIR64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
216e5dd7070Spatrick       : SPIRTargetInfo(Triple, Opts) {
217*12c85518Srobert     assert(Triple.getArch() == llvm::Triple::spir64 &&
218*12c85518Srobert            "Invalid architecture for 64-bit SPIR.");
219e5dd7070Spatrick     PointerWidth = PointerAlign = 64;
220e5dd7070Spatrick     SizeType = TargetInfo::UnsignedLong;
221e5dd7070Spatrick     PtrDiffType = IntPtrType = TargetInfo::SignedLong;
222e5dd7070Spatrick     resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"
223e5dd7070Spatrick                     "v96:128-v192:256-v256:256-v512:512-v1024:1024");
224e5dd7070Spatrick   }
225e5dd7070Spatrick 
226e5dd7070Spatrick   void getTargetDefines(const LangOptions &Opts,
227e5dd7070Spatrick                         MacroBuilder &Builder) const override;
228e5dd7070Spatrick };
229*12c85518Srobert 
230*12c85518Srobert class LLVM_LIBRARY_VISIBILITY SPIRVTargetInfo : public BaseSPIRTargetInfo {
231*12c85518Srobert public:
SPIRVTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)232*12c85518Srobert   SPIRVTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
233*12c85518Srobert       : BaseSPIRTargetInfo(Triple, Opts) {
234*12c85518Srobert     assert(Triple.isSPIRV() && "Invalid architecture for SPIR-V.");
235*12c85518Srobert     assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
236*12c85518Srobert            "SPIR-V target must use unknown OS");
237*12c85518Srobert     assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
238*12c85518Srobert            "SPIR-V target must use unknown environment type");
239*12c85518Srobert   }
240*12c85518Srobert 
241*12c85518Srobert   void getTargetDefines(const LangOptions &Opts,
242*12c85518Srobert                         MacroBuilder &Builder) const override;
243*12c85518Srobert 
hasFeature(StringRef Feature)244*12c85518Srobert   bool hasFeature(StringRef Feature) const override {
245*12c85518Srobert     return Feature == "spirv";
246*12c85518Srobert   }
247*12c85518Srobert };
248*12c85518Srobert 
249*12c85518Srobert class LLVM_LIBRARY_VISIBILITY SPIRV32TargetInfo : public SPIRVTargetInfo {
250*12c85518Srobert public:
SPIRV32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)251*12c85518Srobert   SPIRV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
252*12c85518Srobert       : SPIRVTargetInfo(Triple, Opts) {
253*12c85518Srobert     assert(Triple.getArch() == llvm::Triple::spirv32 &&
254*12c85518Srobert            "Invalid architecture for 32-bit SPIR-V.");
255*12c85518Srobert     PointerWidth = PointerAlign = 32;
256*12c85518Srobert     SizeType = TargetInfo::UnsignedInt;
257*12c85518Srobert     PtrDiffType = IntPtrType = TargetInfo::SignedInt;
258*12c85518Srobert     resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"
259*12c85518Srobert                     "v96:128-v192:256-v256:256-v512:512-v1024:1024");
260*12c85518Srobert   }
261*12c85518Srobert 
262*12c85518Srobert   void getTargetDefines(const LangOptions &Opts,
263*12c85518Srobert                         MacroBuilder &Builder) const override;
264*12c85518Srobert };
265*12c85518Srobert 
266*12c85518Srobert class LLVM_LIBRARY_VISIBILITY SPIRV64TargetInfo : public SPIRVTargetInfo {
267*12c85518Srobert public:
SPIRV64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)268*12c85518Srobert   SPIRV64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
269*12c85518Srobert       : SPIRVTargetInfo(Triple, Opts) {
270*12c85518Srobert     assert(Triple.getArch() == llvm::Triple::spirv64 &&
271*12c85518Srobert            "Invalid architecture for 64-bit SPIR-V.");
272*12c85518Srobert     PointerWidth = PointerAlign = 64;
273*12c85518Srobert     SizeType = TargetInfo::UnsignedLong;
274*12c85518Srobert     PtrDiffType = IntPtrType = TargetInfo::SignedLong;
275*12c85518Srobert     resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"
276*12c85518Srobert                     "v96:128-v192:256-v256:256-v512:512-v1024:1024");
277*12c85518Srobert   }
278*12c85518Srobert 
279*12c85518Srobert   void getTargetDefines(const LangOptions &Opts,
280*12c85518Srobert                         MacroBuilder &Builder) const override;
281*12c85518Srobert };
282*12c85518Srobert 
283e5dd7070Spatrick } // namespace targets
284e5dd7070Spatrick } // namespace clang
285e5dd7070Spatrick #endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H
286