1 //===--- SPIR.h - Declare SPIR 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 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 "clang/Basic/TargetInfo.h"
17 #include "clang/Basic/TargetOptions.h"
18 #include "llvm/ADT/Triple.h"
19 #include "llvm/Support/Compiler.h"
20 
21 namespace clang {
22 namespace targets {
23 
24 static const unsigned SPIRDefIsPrivMap[] = {
25     0, // Default
26     1, // opencl_global
27     3, // opencl_local
28     2, // opencl_constant
29     0, // opencl_private
30     4, // opencl_generic
31     5, // opencl_global_device
32     6, // opencl_global_host
33     0, // cuda_device
34     0, // cuda_constant
35     0, // cuda_shared
36     // SYCL address space values for this map are dummy
37     0, // sycl_global
38     0, // sycl_global_device
39     0, // sycl_global_host
40     0, // sycl_local
41     0, // sycl_private
42     0, // ptr32_sptr
43     0, // ptr32_uptr
44     0  // ptr64
45 };
46 
47 static const unsigned SPIRDefIsGenMap[] = {
48     4, // Default
49     // OpenCL address space values for this map are dummy and they can't be used
50     0, // opencl_global
51     0, // opencl_local
52     0, // opencl_constant
53     0, // opencl_private
54     0, // opencl_generic
55     0, // opencl_global_device
56     0, // opencl_global_host
57     0, // cuda_device
58     0, // cuda_constant
59     0, // cuda_shared
60     1, // sycl_global
61     5, // sycl_global_device
62     6, // sycl_global_host
63     3, // sycl_local
64     0, // sycl_private
65     0, // ptr32_sptr
66     0, // ptr32_uptr
67     0  // ptr64
68 };
69 
70 class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public TargetInfo {
71 public:
SPIRTargetInfo(const llvm::Triple & Triple,const TargetOptions &)72   SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
73       : TargetInfo(Triple) {
74     assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
75            "SPIR target must use unknown OS");
76     assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
77            "SPIR target must use unknown environment type");
78     TLSSupported = false;
79     VLASupported = false;
80     LongWidth = LongAlign = 64;
81     AddrSpaceMap = &SPIRDefIsPrivMap;
82     UseAddrSpaceMapMangling = true;
83     HasLegalHalfType = true;
84     HasFloat16 = true;
85     // Define available target features
86     // These must be defined in sorted order!
87     NoAsmVariants = true;
88   }
89 
90   void getTargetDefines(const LangOptions &Opts,
91                         MacroBuilder &Builder) const override;
92 
hasFeature(StringRef Feature)93   bool hasFeature(StringRef Feature) const override {
94     return Feature == "spir";
95   }
96 
97   // SPIR supports the half type and the only llvm intrinsic allowed in SPIR is
98   // memcpy as per section 3 of the SPIR spec.
useFP16ConversionIntrinsics()99   bool useFP16ConversionIntrinsics() const override { return false; }
100 
getTargetBuiltins()101   ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; }
102 
getClobbers()103   const char *getClobbers() const override { return ""; }
104 
getGCCRegNames()105   ArrayRef<const char *> getGCCRegNames() const override { return None; }
106 
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & info)107   bool validateAsmConstraint(const char *&Name,
108                              TargetInfo::ConstraintInfo &info) const override {
109     return true;
110   }
111 
getGCCRegAliases()112   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
113     return None;
114   }
115 
getBuiltinVaListKind()116   BuiltinVaListKind getBuiltinVaListKind() const override {
117     return TargetInfo::VoidPtrBuiltinVaList;
118   }
119 
120   Optional<unsigned>
getDWARFAddressSpace(unsigned AddressSpace)121   getDWARFAddressSpace(unsigned AddressSpace) const override {
122     return AddressSpace;
123   }
124 
checkCallingConvention(CallingConv CC)125   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
126     return (CC == CC_SpirFunction || CC == CC_OpenCLKernel) ? CCCR_OK
127                                                             : CCCR_Warning;
128   }
129 
getDefaultCallingConv()130   CallingConv getDefaultCallingConv() const override {
131     return CC_SpirFunction;
132   }
133 
setAddressSpaceMap(bool DefaultIsGeneric)134   void setAddressSpaceMap(bool DefaultIsGeneric) {
135     AddrSpaceMap = DefaultIsGeneric ? &SPIRDefIsGenMap : &SPIRDefIsPrivMap;
136   }
137 
adjust(DiagnosticsEngine & Diags,LangOptions & Opts)138   void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override {
139     TargetInfo::adjust(Diags, Opts);
140     // FIXME: SYCL specification considers unannotated pointers and references
141     // to be pointing to the generic address space. See section 5.9.3 of
142     // SYCL 2020 specification.
143     // Currently, there is no way of representing SYCL's default address space
144     // language semantic along with the semantics of embedded C's default
145     // address space in the same address space map. Hence the map needs to be
146     // reset to allow mapping to the desired value of 'Default' entry for SYCL.
147     setAddressSpaceMap(/*DefaultIsGeneric=*/Opts.SYCLIsDevice);
148   }
149 
setSupportedOpenCLOpts()150   void setSupportedOpenCLOpts() override {
151     // Assume all OpenCL extensions and optional core features are supported
152     // for SPIR since it is a generic target.
153     supportAllOpenCLOpts();
154   }
155 
hasExtIntType()156   bool hasExtIntType() const override { return true; }
157 
hasInt128Type()158   bool hasInt128Type() const override { return false; }
159 };
160 
161 class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo {
162 public:
SPIR32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)163   SPIR32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
164       : SPIRTargetInfo(Triple, Opts) {
165     PointerWidth = PointerAlign = 32;
166     SizeType = TargetInfo::UnsignedInt;
167     PtrDiffType = IntPtrType = TargetInfo::SignedInt;
168     resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-"
169                     "v96:128-v192:256-v256:256-v512:512-v1024:1024");
170   }
171 
172   void getTargetDefines(const LangOptions &Opts,
173                         MacroBuilder &Builder) const override;
174 };
175 
176 class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo : public SPIRTargetInfo {
177 public:
SPIR64TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)178   SPIR64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
179       : SPIRTargetInfo(Triple, Opts) {
180     PointerWidth = PointerAlign = 64;
181     SizeType = TargetInfo::UnsignedLong;
182     PtrDiffType = IntPtrType = TargetInfo::SignedLong;
183     resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-"
184                     "v96:128-v192:256-v256:256-v512:512-v1024:1024");
185   }
186 
187   void getTargetDefines(const LangOptions &Opts,
188                         MacroBuilder &Builder) const override;
189 };
190 } // namespace targets
191 } // namespace clang
192 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H
193