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