SPIR.h 9.9 KB

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