blob: 8e4ccc500f7b1eefea8ab8232521e2774e735f02 [file] [log] [blame]
Erich Keaneebba5922017-07-21 22:37:03 +00001//===--- AMDGPU.h - Declare AMDGPU target feature support -------*- C++ -*-===//
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 declares AMDGPU TargetInfo objects.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_AMDGPU_H
15#define LLVM_CLANG_LIB_BASIC_TARGETS_AMDGPU_H
16
17#include "clang/Basic/TargetInfo.h"
18#include "clang/Basic/TargetOptions.h"
Yaxun Liu304f3492017-09-28 19:07:59 +000019#include "llvm/ADT/StringSet.h"
Erich Keaneebba5922017-07-21 22:37:03 +000020#include "llvm/ADT/Triple.h"
21#include "llvm/Support/Compiler.h"
22
23namespace clang {
24namespace targets {
25
26class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo {
27
28 static const Builtin::Info BuiltinInfo[];
29 static const char *const GCCRegNames[];
30
31 struct LLVM_LIBRARY_VISIBILITY AddrSpace {
32 unsigned Generic, Global, Local, Constant, Private;
33 AddrSpace(bool IsGenericZero_ = false) {
34 if (IsGenericZero_) {
35 Generic = 0;
36 Global = 1;
37 Local = 3;
38 Constant = 2;
39 Private = 5;
40 } else {
41 Generic = 4;
42 Global = 1;
43 Local = 3;
44 Constant = 2;
45 Private = 0;
46 }
47 }
48 };
49
50 /// \brief The GPU profiles supported by the AMDGPU target.
51 enum GPUKind {
52 GK_NONE,
53 GK_R600,
54 GK_R600_DOUBLE_OPS,
55 GK_R700,
56 GK_R700_DOUBLE_OPS,
57 GK_EVERGREEN,
58 GK_EVERGREEN_DOUBLE_OPS,
59 GK_NORTHERN_ISLANDS,
60 GK_CAYMAN,
61 GK_GFX6,
62 GK_GFX7,
63 GK_GFX8,
64 GK_GFX9
Konstantin Zhuravlyovcf717612018-02-15 02:37:04 +000065 };
Erich Keaneebba5922017-07-21 22:37:03 +000066
Konstantin Zhuravlyovcf717612018-02-15 02:37:04 +000067 struct GPUInfo {
Erich Keanee44bdb32018-02-08 23:16:55 +000068 llvm::StringLiteral Name;
Konstantin Zhuravlyovcf717612018-02-15 02:37:04 +000069 llvm::StringLiteral CanonicalName;
Erich Keanee44bdb32018-02-08 23:16:55 +000070 AMDGPUTargetInfo::GPUKind Kind;
71 };
72
Konstantin Zhuravlyovcf717612018-02-15 02:37:04 +000073 GPUInfo GPU;
74
75 static constexpr GPUInfo InvalidGPU = {{""}, {""}, GK_NONE};
76 static constexpr GPUInfo R600Names[26] = {
77 {{"r600"}, {"r600"}, GK_R600},
78 {{"rv630"}, {"r600"}, GK_R600},
79 {{"rv635"}, {"r600"}, GK_R600},
80 {{"r630"}, {"r630"}, GK_R600},
81 {{"rs780"}, {"rs880"}, GK_R600},
82 {{"rs880"}, {"rs880"}, GK_R600},
83 {{"rv610"}, {"rs880"}, GK_R600},
84 {{"rv620"}, {"rs880"}, GK_R600},
85 {{"rv670"}, {"rv670"}, GK_R600_DOUBLE_OPS},
86 {{"rv710"}, {"rv710"}, GK_R700},
87 {{"rv730"}, {"rv730"}, GK_R700},
88 {{"rv740"}, {"rv770"}, GK_R700_DOUBLE_OPS},
89 {{"rv770"}, {"rv770"}, GK_R700_DOUBLE_OPS},
90 {{"cedar"}, {"cedar"}, GK_EVERGREEN},
91 {{"palm"}, {"cedar"}, GK_EVERGREEN},
92 {{"cypress"}, {"cypress"}, GK_EVERGREEN_DOUBLE_OPS},
93 {{"hemlock"}, {"cypress"}, GK_EVERGREEN_DOUBLE_OPS},
94 {{"juniper"}, {"juniper"}, GK_EVERGREEN},
95 {{"redwood"}, {"redwood"}, GK_EVERGREEN},
96 {{"sumo"}, {"sumo"}, GK_EVERGREEN},
97 {{"sumo2"}, {"sumo"}, GK_EVERGREEN},
98 {{"barts"}, {"barts"}, GK_NORTHERN_ISLANDS},
99 {{"caicos"}, {"caicos"}, GK_NORTHERN_ISLANDS},
100 {{"turks"}, {"turks"}, GK_NORTHERN_ISLANDS},
101 {{"aruba"}, {"cayman"}, GK_CAYMAN},
102 {{"cayman"}, {"cayman"}, GK_CAYMAN},
Erich Keanee44bdb32018-02-08 23:16:55 +0000103 };
Konstantin Zhuravlyovcf717612018-02-15 02:37:04 +0000104 static constexpr GPUInfo AMDGCNNames[30] = {
105 {{"gfx600"}, {"gfx600"}, GK_GFX6},
106 {{"tahiti"}, {"gfx600"}, GK_GFX6},
107 {{"gfx601"}, {"gfx601"}, GK_GFX6},
108 {{"hainan"}, {"gfx601"}, GK_GFX6},
109 {{"oland"}, {"gfx601"}, GK_GFX6},
110 {{"pitcairn"}, {"gfx601"}, GK_GFX6},
111 {{"verde"}, {"gfx601"}, GK_GFX6},
112 {{"gfx700"}, {"gfx700"}, GK_GFX7},
113 {{"kaveri"}, {"gfx700"}, GK_GFX7},
114 {{"gfx701"}, {"gfx701"}, GK_GFX7},
115 {{"hawaii"}, {"gfx701"}, GK_GFX7},
116 {{"gfx702"}, {"gfx702"}, GK_GFX7},
117 {{"gfx703"}, {"gfx703"}, GK_GFX7},
118 {{"kabini"}, {"gfx703"}, GK_GFX7},
119 {{"mullins"}, {"gfx703"}, GK_GFX7},
120 {{"gfx704"}, {"gfx704"}, GK_GFX7},
121 {{"bonaire"}, {"gfx704"}, GK_GFX7},
122 {{"gfx801"}, {"gfx801"}, GK_GFX8},
123 {{"carrizo"}, {"gfx801"}, GK_GFX8},
124 {{"gfx802"}, {"gfx802"}, GK_GFX8},
125 {{"iceland"}, {"gfx802"}, GK_GFX8},
126 {{"tonga"}, {"gfx802"}, GK_GFX8},
127 {{"gfx803"}, {"gfx803"}, GK_GFX8},
128 {{"fiji"}, {"gfx803"}, GK_GFX8},
129 {{"polaris10"}, {"gfx803"}, GK_GFX8},
130 {{"polaris11"}, {"gfx803"}, GK_GFX8},
131 {{"gfx810"}, {"gfx810"}, GK_GFX8},
132 {{"stoney"}, {"gfx810"}, GK_GFX8},
133 {{"gfx900"}, {"gfx900"}, GK_GFX9},
134 {{"gfx902"}, {"gfx902"}, GK_GFX9},
Erich Keanee44bdb32018-02-08 23:16:55 +0000135 };
136
Erich Keaneebba5922017-07-21 22:37:03 +0000137 bool hasFP64 : 1;
138 bool hasFMAF : 1;
139 bool hasLDEXPF : 1;
140 const AddrSpace AS;
141
142 static bool hasFullSpeedFMAF32(StringRef GPUName) {
Konstantin Zhuravlyovcf717612018-02-15 02:37:04 +0000143 return parseAMDGCNName(GPUName).Kind >= GK_GFX9;
Erich Keaneebba5922017-07-21 22:37:03 +0000144 }
145
146 static bool isAMDGCN(const llvm::Triple &TT) {
147 return TT.getArch() == llvm::Triple::amdgcn;
148 }
149
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000150 static bool isGenericZero(const llvm::Triple &TT) { return true; }
Erich Keaneebba5922017-07-21 22:37:03 +0000151
152public:
153 AMDGPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
154
155 void setAddressSpaceMap(bool DefaultIsPrivate);
156
157 void adjust(LangOptions &Opts) override;
158
159 uint64_t getPointerWidthV(unsigned AddrSpace) const override {
Konstantin Zhuravlyovcf717612018-02-15 02:37:04 +0000160 if (GPU.Kind <= GK_CAYMAN)
Erich Keaneebba5922017-07-21 22:37:03 +0000161 return 32;
162
163 if (AddrSpace == AS.Private || AddrSpace == AS.Local) {
164 return 32;
165 }
166 return 64;
167 }
168
169 uint64_t getPointerAlignV(unsigned AddrSpace) const override {
170 return getPointerWidthV(AddrSpace);
171 }
172
173 uint64_t getMaxPointerWidth() const override {
174 return getTriple().getArch() == llvm::Triple::amdgcn ? 64 : 32;
175 }
176
177 const char *getClobbers() const override { return ""; }
178
179 ArrayRef<const char *> getGCCRegNames() const override;
180
181 ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
182 return None;
183 }
184
Yaxun Liu304f3492017-09-28 19:07:59 +0000185 /// Accepted register names: (n, m is unsigned integer, n < m)
186 /// v
187 /// s
188 /// {vn}, {v[n]}
189 /// {sn}, {s[n]}
190 /// {S} , where S is a special register name
191 ////{v[n:m]}
192 /// {s[n:m]}
Erich Keaneebba5922017-07-21 22:37:03 +0000193 bool validateAsmConstraint(const char *&Name,
194 TargetInfo::ConstraintInfo &Info) const override {
Yaxun Liu304f3492017-09-28 19:07:59 +0000195 static const ::llvm::StringSet<> SpecialRegs({
196 "exec", "vcc", "flat_scratch", "m0", "scc", "tba", "tma",
197 "flat_scratch_lo", "flat_scratch_hi", "vcc_lo", "vcc_hi", "exec_lo",
198 "exec_hi", "tma_lo", "tma_hi", "tba_lo", "tba_hi",
199 });
200
201 StringRef S(Name);
202 bool HasLeftParen = false;
203 if (S.front() == '{') {
204 HasLeftParen = true;
205 S = S.drop_front();
206 }
207 if (S.empty())
208 return false;
209 if (S.front() != 'v' && S.front() != 's') {
210 if (!HasLeftParen)
211 return false;
212 auto E = S.find('}');
213 if (!SpecialRegs.count(S.substr(0, E)))
214 return false;
215 S = S.drop_front(E + 1);
216 if (!S.empty())
217 return false;
218 // Found {S} where S is a special register.
Erich Keaneebba5922017-07-21 22:37:03 +0000219 Info.setAllowsRegister();
Yaxun Liu304f3492017-09-28 19:07:59 +0000220 Name = S.data() - 1;
Erich Keaneebba5922017-07-21 22:37:03 +0000221 return true;
222 }
Yaxun Liu304f3492017-09-28 19:07:59 +0000223 S = S.drop_front();
224 if (!HasLeftParen) {
225 if (!S.empty())
226 return false;
227 // Found s or v.
228 Info.setAllowsRegister();
229 Name = S.data() - 1;
230 return true;
231 }
232 bool HasLeftBracket = false;
233 if (!S.empty() && S.front() == '[') {
234 HasLeftBracket = true;
235 S = S.drop_front();
236 }
237 unsigned long long N;
238 if (S.empty() || consumeUnsignedInteger(S, 10, N))
239 return false;
240 if (!S.empty() && S.front() == ':') {
241 if (!HasLeftBracket)
242 return false;
243 S = S.drop_front();
244 unsigned long long M;
245 if (consumeUnsignedInteger(S, 10, M) || N >= M)
246 return false;
247 }
248 if (HasLeftBracket) {
249 if (S.empty() || S.front() != ']')
250 return false;
251 S = S.drop_front();
252 }
253 if (S.empty() || S.front() != '}')
254 return false;
255 S = S.drop_front();
256 if (!S.empty())
257 return false;
258 // Found {vn}, {sn}, {v[n]}, {s[n]}, {v[n:m]}, or {s[n:m]}.
259 Info.setAllowsRegister();
260 Name = S.data() - 1;
261 return true;
Erich Keaneebba5922017-07-21 22:37:03 +0000262 }
263
264 bool
265 initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
266 StringRef CPU,
267 const std::vector<std::string> &FeatureVec) const override;
268
269 void adjustTargetOptions(const CodeGenOptions &CGOpts,
270 TargetOptions &TargetOpts) const override;
271
272 ArrayRef<Builtin::Info> getTargetBuiltins() const override;
273
274 void getTargetDefines(const LangOptions &Opts,
275 MacroBuilder &Builder) const override;
276
277 BuiltinVaListKind getBuiltinVaListKind() const override {
278 return TargetInfo::CharPtrBuiltinVaList;
279 }
280
Konstantin Zhuravlyovcf717612018-02-15 02:37:04 +0000281 static GPUInfo parseR600Name(StringRef Name);
Erich Keaneebba5922017-07-21 22:37:03 +0000282
Konstantin Zhuravlyovcf717612018-02-15 02:37:04 +0000283 static GPUInfo parseAMDGCNName(StringRef Name);
Erich Keaneebba5922017-07-21 22:37:03 +0000284
285 bool isValidCPUName(StringRef Name) const override {
286 if (getTriple().getArch() == llvm::Triple::amdgcn)
Konstantin Zhuravlyovcf717612018-02-15 02:37:04 +0000287 return GK_NONE != parseAMDGCNName(Name).Kind;
Erich Keaneebba5922017-07-21 22:37:03 +0000288 else
Konstantin Zhuravlyovcf717612018-02-15 02:37:04 +0000289 return GK_NONE != parseR600Name(Name).Kind;
Erich Keaneebba5922017-07-21 22:37:03 +0000290 }
291
Erich Keanee44bdb32018-02-08 23:16:55 +0000292 void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
293
Erich Keaneebba5922017-07-21 22:37:03 +0000294 bool setCPU(const std::string &Name) override {
295 if (getTriple().getArch() == llvm::Triple::amdgcn)
296 GPU = parseAMDGCNName(Name);
297 else
298 GPU = parseR600Name(Name);
299
Konstantin Zhuravlyovcf717612018-02-15 02:37:04 +0000300 return GPU.Kind != GK_NONE;
Erich Keaneebba5922017-07-21 22:37:03 +0000301 }
302
303 void setSupportedOpenCLOpts() override {
304 auto &Opts = getSupportedOpenCLOpts();
305 Opts.support("cl_clang_storage_class_specifiers");
306 Opts.support("cl_khr_icd");
307
308 if (hasFP64)
309 Opts.support("cl_khr_fp64");
Konstantin Zhuravlyovcf717612018-02-15 02:37:04 +0000310 if (GPU.Kind >= GK_EVERGREEN) {
Erich Keaneebba5922017-07-21 22:37:03 +0000311 Opts.support("cl_khr_byte_addressable_store");
312 Opts.support("cl_khr_global_int32_base_atomics");
313 Opts.support("cl_khr_global_int32_extended_atomics");
314 Opts.support("cl_khr_local_int32_base_atomics");
315 Opts.support("cl_khr_local_int32_extended_atomics");
316 }
Konstantin Zhuravlyovcf717612018-02-15 02:37:04 +0000317 if (GPU.Kind >= GK_GFX6) {
Erich Keaneebba5922017-07-21 22:37:03 +0000318 Opts.support("cl_khr_fp16");
319 Opts.support("cl_khr_int64_base_atomics");
320 Opts.support("cl_khr_int64_extended_atomics");
321 Opts.support("cl_khr_mipmap_image");
322 Opts.support("cl_khr_subgroups");
323 Opts.support("cl_khr_3d_image_writes");
324 Opts.support("cl_amd_media_ops");
325 Opts.support("cl_amd_media_ops2");
326 }
327 }
328
Sven van Haastregt3bb7eaf2017-12-06 10:11:28 +0000329 LangAS getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const override {
330 switch (TK) {
331 case OCLTK_Image:
332 return LangAS::opencl_constant;
Sven van Haastregtefb4d4c2017-08-15 09:38:18 +0000333
Sven van Haastregt3bb7eaf2017-12-06 10:11:28 +0000334 case OCLTK_ClkEvent:
335 case OCLTK_Queue:
336 case OCLTK_ReserveID:
Yaxun Liue3779352017-09-13 18:50:42 +0000337 return LangAS::opencl_global;
Sven van Haastregtefb4d4c2017-08-15 09:38:18 +0000338
339 default:
Sven van Haastregt3bb7eaf2017-12-06 10:11:28 +0000340 return TargetInfo::getOpenCLTypeAddrSpace(TK);
Sven van Haastregtefb4d4c2017-08-15 09:38:18 +0000341 }
Erich Keaneebba5922017-07-21 22:37:03 +0000342 }
343
Alexander Richardson6d989432017-10-15 18:48:14 +0000344 llvm::Optional<LangAS> getConstantAddressSpace() const override {
345 return getLangASFromTargetAS(AS.Constant);
Erich Keaneebba5922017-07-21 22:37:03 +0000346 }
347
348 /// \returns Target specific vtbl ptr address space.
349 unsigned getVtblPtrAddressSpace() const override { return AS.Constant; }
350
351 /// \returns If a target requires an address within a target specific address
352 /// space \p AddressSpace to be converted in order to be used, then return the
353 /// corresponding target specific DWARF address space.
354 ///
355 /// \returns Otherwise return None and no conversion will be emitted in the
356 /// DWARF.
357 Optional<unsigned>
358 getDWARFAddressSpace(unsigned AddressSpace) const override {
359 const unsigned DWARF_Private = 1;
360 const unsigned DWARF_Local = 2;
361 if (AddressSpace == AS.Private) {
362 return DWARF_Private;
363 } else if (AddressSpace == AS.Local) {
364 return DWARF_Local;
365 } else {
366 return None;
367 }
368 }
369
370 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
371 switch (CC) {
372 default:
373 return CCCR_Warning;
374 case CC_C:
375 case CC_OpenCLKernel:
376 return CCCR_OK;
377 }
378 }
379
380 // In amdgcn target the null pointer in global, constant, and generic
381 // address space has value 0 but in private and local address space has
382 // value ~0.
Alexander Richardson6d989432017-10-15 18:48:14 +0000383 uint64_t getNullPointerValue(LangAS AS) const override {
Erich Keaneebba5922017-07-21 22:37:03 +0000384 return AS == LangAS::opencl_local ? ~0 : 0;
385 }
386};
387
388} // namespace targets
389} // namespace clang
390
391#endif // LLVM_CLANG_LIB_BASIC_TARGETS_AMDGPU_H