SPIR.h 10 KB

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