Clang Project

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