blob: add3b318aeb6dfaaf30af8fd9548d9f4af9d106a [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
43 TLSSupported = false;
Jonas Hahnfeld87d44262017-11-18 21:00:46 +000044 VLASupported = false;
Erich Keaneebba5922017-07-21 22:37:03 +000045 AddrSpaceMap = &NVPTXAddrSpaceMap;
46 UseAddrSpaceMapMangling = true;
47
48 // Define available target features
49 // These must be defined in sorted order!
50 NoAsmVariants = true;
51 GPU = CudaArch::SM_20;
52
53 if (TargetPointerWidth == 32)
54 resetDataLayout("e-p:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64");
55 else
56 resetDataLayout("e-i64:64-i128:128-v16:16-v32:32-n16:32:64");
57
58 // If possible, get a TargetInfo for our host triple, so we can match its
59 // types.
60 llvm::Triple HostTriple(Opts.HostTriple);
61 if (!HostTriple.isNVPTX())
62 HostTarget.reset(AllocateTarget(llvm::Triple(Opts.HostTriple), Opts));
63
64 // If no host target, make some guesses about the data layout and return.
65 if (!HostTarget) {
66 LongWidth = LongAlign = TargetPointerWidth;
67 PointerWidth = PointerAlign = TargetPointerWidth;
68 switch (TargetPointerWidth) {
69 case 32:
70 SizeType = TargetInfo::UnsignedInt;
71 PtrDiffType = TargetInfo::SignedInt;
72 IntPtrType = TargetInfo::SignedInt;
73 break;
74 case 64:
75 SizeType = TargetInfo::UnsignedLong;
76 PtrDiffType = TargetInfo::SignedLong;
77 IntPtrType = TargetInfo::SignedLong;
78 break;
79 default:
80 llvm_unreachable("TargetPointerWidth must be 32 or 64");
81 }
82 return;
83 }
84
85 // Copy properties from host target.
86 PointerWidth = HostTarget->getPointerWidth(/* AddrSpace = */ 0);
87 PointerAlign = HostTarget->getPointerAlign(/* AddrSpace = */ 0);
88 BoolWidth = HostTarget->getBoolWidth();
89 BoolAlign = HostTarget->getBoolAlign();
90 IntWidth = HostTarget->getIntWidth();
91 IntAlign = HostTarget->getIntAlign();
92 HalfWidth = HostTarget->getHalfWidth();
93 HalfAlign = HostTarget->getHalfAlign();
94 FloatWidth = HostTarget->getFloatWidth();
95 FloatAlign = HostTarget->getFloatAlign();
96 DoubleWidth = HostTarget->getDoubleWidth();
97 DoubleAlign = HostTarget->getDoubleAlign();
98 LongWidth = HostTarget->getLongWidth();
99 LongAlign = HostTarget->getLongAlign();
100 LongLongWidth = HostTarget->getLongLongWidth();
101 LongLongAlign = HostTarget->getLongLongAlign();
102 MinGlobalAlign = HostTarget->getMinGlobalAlign();
103 NewAlign = HostTarget->getNewAlign();
104 DefaultAlignForAttributeAligned =
105 HostTarget->getDefaultAlignForAttributeAligned();
106 SizeType = HostTarget->getSizeType();
107 IntMaxType = HostTarget->getIntMaxType();
108 PtrDiffType = HostTarget->getPtrDiffType(/* AddrSpace = */ 0);
109 IntPtrType = HostTarget->getIntPtrType();
110 WCharType = HostTarget->getWCharType();
111 WIntType = HostTarget->getWIntType();
112 Char16Type = HostTarget->getChar16Type();
113 Char32Type = HostTarget->getChar32Type();
114 Int64Type = HostTarget->getInt64Type();
115 SigAtomicType = HostTarget->getSigAtomicType();
116 ProcessIDType = HostTarget->getProcessIDType();
117
118 UseBitFieldTypeAlignment = HostTarget->useBitFieldTypeAlignment();
119 UseZeroLengthBitfieldAlignment = HostTarget->useZeroLengthBitfieldAlignment();
120 UseExplicitBitFieldAlignment = HostTarget->useExplicitBitFieldAlignment();
121 ZeroLengthBitfieldBoundary = HostTarget->getZeroLengthBitfieldBoundary();
122
123 // This is a bit of a lie, but it controls __GCC_ATOMIC_XXX_LOCK_FREE, and
124 // we need those macros to be identical on host and device, because (among
125 // other things) they affect which standard library classes are defined, and
126 // we need all classes to be defined on both the host and device.
127 MaxAtomicInlineWidth = HostTarget->getMaxAtomicInlineWidth();
128
129 // Properties intentionally not copied from host:
130 // - LargeArrayMinWidth, LargeArrayAlign: Not visible across the
131 // host/device boundary.
132 // - SuitableAlign: Not visible across the host/device boundary, and may
133 // correctly be different on host/device, e.g. if host has wider vector
134 // types than device.
135 // - LongDoubleWidth, LongDoubleAlign: nvptx's long double type is the same
136 // as its double type, but that's not necessarily true on the host.
137 // TODO: nvcc emits a warning when using long double on device; we should
138 // do the same.
139}
140
141ArrayRef<const char *> NVPTXTargetInfo::getGCCRegNames() const {
142 return llvm::makeArrayRef(GCCRegNames);
143}
144
145bool NVPTXTargetInfo::hasFeature(StringRef Feature) const {
146 return llvm::StringSwitch<bool>(Feature)
147 .Cases("ptx", "nvptx", true)
148 .Case("satom", GPU >= CudaArch::SM_60) // Atomics w/ scope.
149 .Default(false);
150}
151
152void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts,
153 MacroBuilder &Builder) const {
154 Builder.defineMacro("__PTX__");
155 Builder.defineMacro("__NVPTX__");
156 if (Opts.CUDAIsDevice) {
157 // Set __CUDA_ARCH__ for the GPU specified.
158 std::string CUDAArchCode = [this] {
159 switch (GPU) {
160 case CudaArch::UNKNOWN:
161 assert(false && "No GPU arch when compiling CUDA device code.");
162 return "";
163 case CudaArch::SM_20:
164 return "200";
165 case CudaArch::SM_21:
166 return "210";
167 case CudaArch::SM_30:
168 return "300";
169 case CudaArch::SM_32:
170 return "320";
171 case CudaArch::SM_35:
172 return "350";
173 case CudaArch::SM_37:
174 return "370";
175 case CudaArch::SM_50:
176 return "500";
177 case CudaArch::SM_52:
178 return "520";
179 case CudaArch::SM_53:
180 return "530";
181 case CudaArch::SM_60:
182 return "600";
183 case CudaArch::SM_61:
184 return "610";
185 case CudaArch::SM_62:
186 return "620";
Artem Belevich8af4e232017-09-07 18:14:32 +0000187 case CudaArch::SM_70:
188 return "700";
Erich Keaneebba5922017-07-21 22:37:03 +0000189 }
190 llvm_unreachable("unhandled CudaArch");
191 }();
192 Builder.defineMacro("__CUDA_ARCH__", CUDAArchCode);
193 }
194}
195
196ArrayRef<Builtin::Info> NVPTXTargetInfo::getTargetBuiltins() const {
197 return llvm::makeArrayRef(BuiltinInfo, clang::NVPTX::LastTSBuiltin -
198 Builtin::FirstTSBuiltin);
199}