blob: fd4ee1606061194decfa5aad895e50f088b4696b [file] [log] [blame]
Erich Keaneebba5922017-07-21 22:37:03 +00001//===--- 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
21using namespace clang;
22using namespace clang::targets;
23
24const 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
34const char *const NVPTXTargetInfo::GCCRegNames[] = {"r0"};
35
36NVPTXTargetInfo::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
Artem Belevich24e8a682018-04-11 17:51:19 +000043 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
Erich Keaneebba5922017-07-21 22:37:03 +000059 TLSSupported = false;
Jonas Hahnfeld87d44262017-11-18 21:00:46 +000060 VLASupported = false;
Erich Keaneebba5922017-07-21 22:37:03 +000061 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");
Artem Belevich679dafe2018-05-09 23:10:09 +000071 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");
Erich Keaneebba5922017-07-21 22:37:03 +000074 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
160ArrayRef<const char *> NVPTXTargetInfo::getGCCRegNames() const {
161 return llvm::makeArrayRef(GCCRegNames);
162}
163
164bool NVPTXTargetInfo::hasFeature(StringRef Feature) const {
165 return llvm::StringSwitch<bool>(Feature)
166 .Cases("ptx", "nvptx", true)
Erich Keaneebba5922017-07-21 22:37:03 +0000167 .Default(false);
168}
169
170void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts,
171 MacroBuilder &Builder) const {
172 Builder.defineMacro("__PTX__");
173 Builder.defineMacro("__NVPTX__");
Yaxun Liubec8a662018-04-09 15:43:01 +0000174 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::LAST:
192 break;
193 case CudaArch::UNKNOWN:
194 assert(false && "No GPU arch when compiling CUDA device code.");
195 return "";
196 case CudaArch::SM_20:
197 return "200";
198 case CudaArch::SM_21:
199 return "210";
200 case CudaArch::SM_30:
201 return "300";
202 case CudaArch::SM_32:
203 return "320";
204 case CudaArch::SM_35:
205 return "350";
206 case CudaArch::SM_37:
207 return "370";
208 case CudaArch::SM_50:
209 return "500";
210 case CudaArch::SM_52:
211 return "520";
212 case CudaArch::SM_53:
213 return "530";
214 case CudaArch::SM_60:
215 return "600";
216 case CudaArch::SM_61:
217 return "610";
218 case CudaArch::SM_62:
219 return "620";
220 case CudaArch::SM_70:
221 return "700";
222 case CudaArch::SM_72:
223 return "720";
224 }
225 llvm_unreachable("unhandled CudaArch");
226 }();
227 Builder.defineMacro("__CUDA_ARCH__", CUDAArchCode);
228 }
Erich Keaneebba5922017-07-21 22:37:03 +0000229}
230
231ArrayRef<Builtin::Info> NVPTXTargetInfo::getTargetBuiltins() const {
232 return llvm::makeArrayRef(BuiltinInfo, clang::NVPTX::LastTSBuiltin -
233 Builtin::FirstTSBuiltin);
234}