NVPTX.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. //===--- NVPTX.cpp - Implement NVPTX target feature support ---------------===//
  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 implements NVPTX TargetInfo objects.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "NVPTX.h"
  13. #include "Targets.h"
  14. #include "clang/Basic/Builtins.h"
  15. #include "clang/Basic/MacroBuilder.h"
  16. #include "clang/Basic/TargetBuiltins.h"
  17. #include "llvm/ADT/StringSwitch.h"
  18. using namespace clang;
  19. using namespace clang::targets;
  20. const Builtin::Info NVPTXTargetInfo::BuiltinInfo[] = {
  21. #define BUILTIN(ID, TYPE, ATTRS) \
  22. {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
  23. #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
  24. {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
  25. #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
  26. {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
  27. #include "clang/Basic/BuiltinsNVPTX.def"
  28. };
  29. const char *const NVPTXTargetInfo::GCCRegNames[] = {"r0"};
  30. NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple,
  31. const TargetOptions &Opts,
  32. unsigned TargetPointerWidth)
  33. : TargetInfo(Triple) {
  34. assert((TargetPointerWidth == 32 || TargetPointerWidth == 64) &&
  35. "NVPTX only supports 32- and 64-bit modes.");
  36. PTXVersion = 32;
  37. for (const StringRef Feature : Opts.FeaturesAsWritten) {
  38. if (!Feature.startswith("+ptx"))
  39. continue;
  40. PTXVersion = llvm::StringSwitch<unsigned>(Feature)
  41. .Case("+ptx64", 64)
  42. .Case("+ptx63", 63)
  43. .Case("+ptx61", 61)
  44. .Case("+ptx60", 60)
  45. .Case("+ptx50", 50)
  46. .Case("+ptx43", 43)
  47. .Case("+ptx42", 42)
  48. .Case("+ptx41", 41)
  49. .Case("+ptx40", 40)
  50. .Case("+ptx32", 32)
  51. .Default(32);
  52. }
  53. TLSSupported = false;
  54. VLASupported = false;
  55. AddrSpaceMap = &NVPTXAddrSpaceMap;
  56. UseAddrSpaceMapMangling = true;
  57. // Define available target features
  58. // These must be defined in sorted order!
  59. NoAsmVariants = true;
  60. GPU = CudaArch::SM_20;
  61. if (TargetPointerWidth == 32)
  62. resetDataLayout("e-p:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64");
  63. else if (Opts.NVPTXUseShortPointers)
  64. resetDataLayout(
  65. "e-p3:32:32-p4:32:32-p5:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64");
  66. else
  67. resetDataLayout("e-i64:64-i128:128-v16:16-v32:32-n16:32:64");
  68. // If possible, get a TargetInfo for our host triple, so we can match its
  69. // types.
  70. llvm::Triple HostTriple(Opts.HostTriple);
  71. if (!HostTriple.isNVPTX())
  72. HostTarget.reset(AllocateTarget(llvm::Triple(Opts.HostTriple), Opts));
  73. // If no host target, make some guesses about the data layout and return.
  74. if (!HostTarget) {
  75. LongWidth = LongAlign = TargetPointerWidth;
  76. PointerWidth = PointerAlign = TargetPointerWidth;
  77. switch (TargetPointerWidth) {
  78. case 32:
  79. SizeType = TargetInfo::UnsignedInt;
  80. PtrDiffType = TargetInfo::SignedInt;
  81. IntPtrType = TargetInfo::SignedInt;
  82. break;
  83. case 64:
  84. SizeType = TargetInfo::UnsignedLong;
  85. PtrDiffType = TargetInfo::SignedLong;
  86. IntPtrType = TargetInfo::SignedLong;
  87. break;
  88. default:
  89. llvm_unreachable("TargetPointerWidth must be 32 or 64");
  90. }
  91. return;
  92. }
  93. // Copy properties from host target.
  94. PointerWidth = HostTarget->getPointerWidth(/* AddrSpace = */ 0);
  95. PointerAlign = HostTarget->getPointerAlign(/* AddrSpace = */ 0);
  96. BoolWidth = HostTarget->getBoolWidth();
  97. BoolAlign = HostTarget->getBoolAlign();
  98. IntWidth = HostTarget->getIntWidth();
  99. IntAlign = HostTarget->getIntAlign();
  100. HalfWidth = HostTarget->getHalfWidth();
  101. HalfAlign = HostTarget->getHalfAlign();
  102. FloatWidth = HostTarget->getFloatWidth();
  103. FloatAlign = HostTarget->getFloatAlign();
  104. DoubleWidth = HostTarget->getDoubleWidth();
  105. DoubleAlign = HostTarget->getDoubleAlign();
  106. LongWidth = HostTarget->getLongWidth();
  107. LongAlign = HostTarget->getLongAlign();
  108. LongLongWidth = HostTarget->getLongLongWidth();
  109. LongLongAlign = HostTarget->getLongLongAlign();
  110. MinGlobalAlign = HostTarget->getMinGlobalAlign(/* TypeSize = */ 0);
  111. NewAlign = HostTarget->getNewAlign();
  112. DefaultAlignForAttributeAligned =
  113. HostTarget->getDefaultAlignForAttributeAligned();
  114. SizeType = HostTarget->getSizeType();
  115. IntMaxType = HostTarget->getIntMaxType();
  116. PtrDiffType = HostTarget->getPtrDiffType(/* AddrSpace = */ 0);
  117. IntPtrType = HostTarget->getIntPtrType();
  118. WCharType = HostTarget->getWCharType();
  119. WIntType = HostTarget->getWIntType();
  120. Char16Type = HostTarget->getChar16Type();
  121. Char32Type = HostTarget->getChar32Type();
  122. Int64Type = HostTarget->getInt64Type();
  123. SigAtomicType = HostTarget->getSigAtomicType();
  124. ProcessIDType = HostTarget->getProcessIDType();
  125. UseBitFieldTypeAlignment = HostTarget->useBitFieldTypeAlignment();
  126. UseZeroLengthBitfieldAlignment = HostTarget->useZeroLengthBitfieldAlignment();
  127. UseExplicitBitFieldAlignment = HostTarget->useExplicitBitFieldAlignment();
  128. ZeroLengthBitfieldBoundary = HostTarget->getZeroLengthBitfieldBoundary();
  129. // This is a bit of a lie, but it controls __GCC_ATOMIC_XXX_LOCK_FREE, and
  130. // we need those macros to be identical on host and device, because (among
  131. // other things) they affect which standard library classes are defined, and
  132. // we need all classes to be defined on both the host and device.
  133. MaxAtomicInlineWidth = HostTarget->getMaxAtomicInlineWidth();
  134. // Properties intentionally not copied from host:
  135. // - LargeArrayMinWidth, LargeArrayAlign: Not visible across the
  136. // host/device boundary.
  137. // - SuitableAlign: Not visible across the host/device boundary, and may
  138. // correctly be different on host/device, e.g. if host has wider vector
  139. // types than device.
  140. // - LongDoubleWidth, LongDoubleAlign: nvptx's long double type is the same
  141. // as its double type, but that's not necessarily true on the host.
  142. // TODO: nvcc emits a warning when using long double on device; we should
  143. // do the same.
  144. }
  145. ArrayRef<const char *> NVPTXTargetInfo::getGCCRegNames() const {
  146. return llvm::makeArrayRef(GCCRegNames);
  147. }
  148. bool NVPTXTargetInfo::hasFeature(StringRef Feature) const {
  149. return llvm::StringSwitch<bool>(Feature)
  150. .Cases("ptx", "nvptx", true)
  151. .Default(false);
  152. }
  153. void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts,
  154. MacroBuilder &Builder) const {
  155. Builder.defineMacro("__PTX__");
  156. Builder.defineMacro("__NVPTX__");
  157. if (Opts.CUDAIsDevice) {
  158. // Set __CUDA_ARCH__ for the GPU specified.
  159. std::string CUDAArchCode = [this] {
  160. switch (GPU) {
  161. case CudaArch::GFX600:
  162. case CudaArch::GFX601:
  163. case CudaArch::GFX700:
  164. case CudaArch::GFX701:
  165. case CudaArch::GFX702:
  166. case CudaArch::GFX703:
  167. case CudaArch::GFX704:
  168. case CudaArch::GFX801:
  169. case CudaArch::GFX802:
  170. case CudaArch::GFX803:
  171. case CudaArch::GFX810:
  172. case CudaArch::GFX900:
  173. case CudaArch::GFX902:
  174. case CudaArch::GFX904:
  175. case CudaArch::GFX906:
  176. case CudaArch::GFX908:
  177. case CudaArch::GFX909:
  178. case CudaArch::GFX1010:
  179. case CudaArch::GFX1011:
  180. case CudaArch::GFX1012:
  181. case CudaArch::LAST:
  182. break;
  183. case CudaArch::UNKNOWN:
  184. assert(false && "No GPU arch when compiling CUDA device code.");
  185. return "";
  186. case CudaArch::SM_20:
  187. return "200";
  188. case CudaArch::SM_21:
  189. return "210";
  190. case CudaArch::SM_30:
  191. return "300";
  192. case CudaArch::SM_32:
  193. return "320";
  194. case CudaArch::SM_35:
  195. return "350";
  196. case CudaArch::SM_37:
  197. return "370";
  198. case CudaArch::SM_50:
  199. return "500";
  200. case CudaArch::SM_52:
  201. return "520";
  202. case CudaArch::SM_53:
  203. return "530";
  204. case CudaArch::SM_60:
  205. return "600";
  206. case CudaArch::SM_61:
  207. return "610";
  208. case CudaArch::SM_62:
  209. return "620";
  210. case CudaArch::SM_70:
  211. return "700";
  212. case CudaArch::SM_72:
  213. return "720";
  214. case CudaArch::SM_75:
  215. return "750";
  216. }
  217. llvm_unreachable("unhandled CudaArch");
  218. }();
  219. Builder.defineMacro("__CUDA_ARCH__", CUDAArchCode);
  220. }
  221. }
  222. ArrayRef<Builtin::Info> NVPTXTargetInfo::getTargetBuiltins() const {
  223. return llvm::makeArrayRef(BuiltinInfo, clang::NVPTX::LastTSBuiltin -
  224. Builtin::FirstTSBuiltin);
  225. }