blob: 050676ed1e0162bcb9610984b86c041338c3df33 [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 Zhuravlyovb7b86122018-02-15 02:27:45 +000065 } GPU;
Erich Keaneebba5922017-07-21 22:37:03 +000066
Konstantin Zhuravlyovb7b86122018-02-15 02:27:45 +000067 struct NameGPUKind {
Erich Keanee44bdb32018-02-08 23:16:55 +000068 llvm::StringLiteral Name;
69 AMDGPUTargetInfo::GPUKind Kind;
70 };
71
Konstantin Zhuravlyovb7b86122018-02-15 02:27:45 +000072 static constexpr NameGPUKind R600Names[26] = {
73 {{"r600"}, GK_R600},
74 {{"rv630"}, GK_R600},
75 {{"rv635"}, GK_R600},
76 {{"r630"}, GK_R600},
77 {{"rs780"}, GK_R600},
78 {{"rs880"}, GK_R600},
79 {{"rv610"}, GK_R600},
80 {{"rv620"}, GK_R600},
81 {{"rv670"}, GK_R600_DOUBLE_OPS},
82 {{"rv710"}, GK_R700},
83 {{"rv730"}, GK_R700},
84 {{"rv740"}, GK_R700_DOUBLE_OPS},
85 {{"rv770"}, GK_R700_DOUBLE_OPS},
86 {{"cedar"}, GK_EVERGREEN},
87 {{"palm"}, GK_EVERGREEN},
88 {{"cypress"}, GK_EVERGREEN_DOUBLE_OPS},
89 {{"hemlock"}, GK_EVERGREEN_DOUBLE_OPS},
90 {{"juniper"}, GK_EVERGREEN},
91 {{"redwood"}, GK_EVERGREEN},
92 {{"sumo"}, GK_EVERGREEN},
93 {{"sumo2"}, GK_EVERGREEN},
94 {{"barts"}, GK_NORTHERN_ISLANDS},
95 {{"caicos"}, GK_NORTHERN_ISLANDS},
96 {{"turks"}, GK_NORTHERN_ISLANDS},
97 {{"aruba"}, GK_CAYMAN},
98 {{"cayman"}, GK_CAYMAN},
Erich Keanee44bdb32018-02-08 23:16:55 +000099 };
Konstantin Zhuravlyovb7b86122018-02-15 02:27:45 +0000100 static constexpr NameGPUKind AMDGCNNames[30] = {
101 {{"gfx600"}, GK_GFX6},
102 {{"tahiti"}, GK_GFX6},
103 {{"gfx601"}, GK_GFX6},
104 {{"hainan"}, GK_GFX6},
105 {{"oland"}, GK_GFX6},
106 {{"pitcairn"}, GK_GFX6},
107 {{"verde"}, GK_GFX6},
108 {{"gfx700"}, GK_GFX7},
109 {{"kaveri"}, GK_GFX7},
110 {{"gfx701"}, GK_GFX7},
111 {{"hawaii"}, GK_GFX7},
112 {{"gfx702"}, GK_GFX7},
113 {{"gfx703"}, GK_GFX7},
114 {{"kabini"}, GK_GFX7},
115 {{"mullins"}, GK_GFX7},
116 {{"gfx704"}, GK_GFX7},
117 {{"bonaire"}, GK_GFX7},
118 {{"gfx801"}, GK_GFX8},
119 {{"carrizo"}, GK_GFX8},
120 {{"gfx802"}, GK_GFX8},
121 {{"iceland"}, GK_GFX8},
122 {{"tonga"}, GK_GFX8},
123 {{"gfx803"}, GK_GFX8},
124 {{"fiji"}, GK_GFX8},
125 {{"polaris10"}, GK_GFX8},
126 {{"polaris11"}, GK_GFX8},
127 {{"gfx810"}, GK_GFX8},
128 {{"stoney"}, GK_GFX8},
129 {{"gfx900"}, GK_GFX9},
130 {{"gfx902"}, GK_GFX9},
Erich Keanee44bdb32018-02-08 23:16:55 +0000131 };
132
Erich Keaneebba5922017-07-21 22:37:03 +0000133 bool hasFP64 : 1;
134 bool hasFMAF : 1;
135 bool hasLDEXPF : 1;
136 const AddrSpace AS;
137
138 static bool hasFullSpeedFMAF32(StringRef GPUName) {
Konstantin Zhuravlyovb7b86122018-02-15 02:27:45 +0000139 return parseAMDGCNName(GPUName) >= GK_GFX9;
Erich Keaneebba5922017-07-21 22:37:03 +0000140 }
141
142 static bool isAMDGCN(const llvm::Triple &TT) {
143 return TT.getArch() == llvm::Triple::amdgcn;
144 }
145
Yaxun Liuf5f45e52018-02-02 16:08:24 +0000146 static bool isGenericZero(const llvm::Triple &TT) { return true; }
Erich Keaneebba5922017-07-21 22:37:03 +0000147
148public:
149 AMDGPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
150
151 void setAddressSpaceMap(bool DefaultIsPrivate);
152
153 void adjust(LangOptions &Opts) override;
154
155 uint64_t getPointerWidthV(unsigned AddrSpace) const override {
Konstantin Zhuravlyovb7b86122018-02-15 02:27:45 +0000156 if (GPU <= GK_CAYMAN)
Erich Keaneebba5922017-07-21 22:37:03 +0000157 return 32;
158
159 if (AddrSpace == AS.Private || AddrSpace == AS.Local) {
160 return 32;
161 }
162 return 64;
163 }
164
165 uint64_t getPointerAlignV(unsigned AddrSpace) const override {
166 return getPointerWidthV(AddrSpace);
167 }
168
169 uint64_t getMaxPointerWidth() const override {
170 return getTriple().getArch() == llvm::Triple::amdgcn ? 64 : 32;
171 }
172
173 const char *getClobbers() const override { return ""; }
174
175 ArrayRef<const char *> getGCCRegNames() const override;
176
177 ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
178 return None;
179 }
180
Yaxun Liu304f3492017-09-28 19:07:59 +0000181 /// Accepted register names: (n, m is unsigned integer, n < m)
182 /// v
183 /// s
184 /// {vn}, {v[n]}
185 /// {sn}, {s[n]}
186 /// {S} , where S is a special register name
187 ////{v[n:m]}
188 /// {s[n:m]}
Erich Keaneebba5922017-07-21 22:37:03 +0000189 bool validateAsmConstraint(const char *&Name,
190 TargetInfo::ConstraintInfo &Info) const override {
Yaxun Liu304f3492017-09-28 19:07:59 +0000191 static const ::llvm::StringSet<> SpecialRegs({
192 "exec", "vcc", "flat_scratch", "m0", "scc", "tba", "tma",
193 "flat_scratch_lo", "flat_scratch_hi", "vcc_lo", "vcc_hi", "exec_lo",
194 "exec_hi", "tma_lo", "tma_hi", "tba_lo", "tba_hi",
195 });
196
197 StringRef S(Name);
198 bool HasLeftParen = false;
199 if (S.front() == '{') {
200 HasLeftParen = true;
201 S = S.drop_front();
202 }
203 if (S.empty())
204 return false;
205 if (S.front() != 'v' && S.front() != 's') {
206 if (!HasLeftParen)
207 return false;
208 auto E = S.find('}');
209 if (!SpecialRegs.count(S.substr(0, E)))
210 return false;
211 S = S.drop_front(E + 1);
212 if (!S.empty())
213 return false;
214 // Found {S} where S is a special register.
Erich Keaneebba5922017-07-21 22:37:03 +0000215 Info.setAllowsRegister();
Yaxun Liu304f3492017-09-28 19:07:59 +0000216 Name = S.data() - 1;
Erich Keaneebba5922017-07-21 22:37:03 +0000217 return true;
218 }
Yaxun Liu304f3492017-09-28 19:07:59 +0000219 S = S.drop_front();
220 if (!HasLeftParen) {
221 if (!S.empty())
222 return false;
223 // Found s or v.
224 Info.setAllowsRegister();
225 Name = S.data() - 1;
226 return true;
227 }
228 bool HasLeftBracket = false;
229 if (!S.empty() && S.front() == '[') {
230 HasLeftBracket = true;
231 S = S.drop_front();
232 }
233 unsigned long long N;
234 if (S.empty() || consumeUnsignedInteger(S, 10, N))
235 return false;
236 if (!S.empty() && S.front() == ':') {
237 if (!HasLeftBracket)
238 return false;
239 S = S.drop_front();
240 unsigned long long M;
241 if (consumeUnsignedInteger(S, 10, M) || N >= M)
242 return false;
243 }
244 if (HasLeftBracket) {
245 if (S.empty() || S.front() != ']')
246 return false;
247 S = S.drop_front();
248 }
249 if (S.empty() || S.front() != '}')
250 return false;
251 S = S.drop_front();
252 if (!S.empty())
253 return false;
254 // Found {vn}, {sn}, {v[n]}, {s[n]}, {v[n:m]}, or {s[n:m]}.
255 Info.setAllowsRegister();
256 Name = S.data() - 1;
257 return true;
Erich Keaneebba5922017-07-21 22:37:03 +0000258 }
259
260 bool
261 initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
262 StringRef CPU,
263 const std::vector<std::string> &FeatureVec) const override;
264
265 void adjustTargetOptions(const CodeGenOptions &CGOpts,
266 TargetOptions &TargetOpts) const override;
267
268 ArrayRef<Builtin::Info> getTargetBuiltins() const override;
269
270 void getTargetDefines(const LangOptions &Opts,
271 MacroBuilder &Builder) const override;
272
273 BuiltinVaListKind getBuiltinVaListKind() const override {
274 return TargetInfo::CharPtrBuiltinVaList;
275 }
276
Konstantin Zhuravlyovb7b86122018-02-15 02:27:45 +0000277 static GPUKind parseR600Name(StringRef Name);
Erich Keaneebba5922017-07-21 22:37:03 +0000278
Konstantin Zhuravlyovb7b86122018-02-15 02:27:45 +0000279 static GPUKind parseAMDGCNName(StringRef Name);
Erich Keaneebba5922017-07-21 22:37:03 +0000280
281 bool isValidCPUName(StringRef Name) const override {
282 if (getTriple().getArch() == llvm::Triple::amdgcn)
Konstantin Zhuravlyovb7b86122018-02-15 02:27:45 +0000283 return GK_NONE != parseAMDGCNName(Name);
Erich Keaneebba5922017-07-21 22:37:03 +0000284 else
Konstantin Zhuravlyovb7b86122018-02-15 02:27:45 +0000285 return GK_NONE != parseR600Name(Name);
Erich Keaneebba5922017-07-21 22:37:03 +0000286 }
287
Erich Keanee44bdb32018-02-08 23:16:55 +0000288 void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
289
Erich Keaneebba5922017-07-21 22:37:03 +0000290 bool setCPU(const std::string &Name) override {
291 if (getTriple().getArch() == llvm::Triple::amdgcn)
292 GPU = parseAMDGCNName(Name);
293 else
294 GPU = parseR600Name(Name);
295
Konstantin Zhuravlyovb7b86122018-02-15 02:27:45 +0000296 return GPU != GK_NONE;
Erich Keaneebba5922017-07-21 22:37:03 +0000297 }
298
299 void setSupportedOpenCLOpts() override {
300 auto &Opts = getSupportedOpenCLOpts();
301 Opts.support("cl_clang_storage_class_specifiers");
302 Opts.support("cl_khr_icd");
303
304 if (hasFP64)
305 Opts.support("cl_khr_fp64");
Konstantin Zhuravlyovb7b86122018-02-15 02:27:45 +0000306 if (GPU >= GK_EVERGREEN) {
Erich Keaneebba5922017-07-21 22:37:03 +0000307 Opts.support("cl_khr_byte_addressable_store");
308 Opts.support("cl_khr_global_int32_base_atomics");
309 Opts.support("cl_khr_global_int32_extended_atomics");
310 Opts.support("cl_khr_local_int32_base_atomics");
311 Opts.support("cl_khr_local_int32_extended_atomics");
312 }
Konstantin Zhuravlyovb7b86122018-02-15 02:27:45 +0000313 if (GPU >= GK_GFX6) {
Erich Keaneebba5922017-07-21 22:37:03 +0000314 Opts.support("cl_khr_fp16");
315 Opts.support("cl_khr_int64_base_atomics");
316 Opts.support("cl_khr_int64_extended_atomics");
317 Opts.support("cl_khr_mipmap_image");
318 Opts.support("cl_khr_subgroups");
319 Opts.support("cl_khr_3d_image_writes");
320 Opts.support("cl_amd_media_ops");
321 Opts.support("cl_amd_media_ops2");
322 }
323 }
324
Sven van Haastregt3bb7eaf2017-12-06 10:11:28 +0000325 LangAS getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const override {
326 switch (TK) {
327 case OCLTK_Image:
328 return LangAS::opencl_constant;
Sven van Haastregtefb4d4c2017-08-15 09:38:18 +0000329
Sven van Haastregt3bb7eaf2017-12-06 10:11:28 +0000330 case OCLTK_ClkEvent:
331 case OCLTK_Queue:
332 case OCLTK_ReserveID:
Yaxun Liue3779352017-09-13 18:50:42 +0000333 return LangAS::opencl_global;
Sven van Haastregtefb4d4c2017-08-15 09:38:18 +0000334
335 default:
Sven van Haastregt3bb7eaf2017-12-06 10:11:28 +0000336 return TargetInfo::getOpenCLTypeAddrSpace(TK);
Sven van Haastregtefb4d4c2017-08-15 09:38:18 +0000337 }
Erich Keaneebba5922017-07-21 22:37:03 +0000338 }
339
Alexander Richardson6d989432017-10-15 18:48:14 +0000340 llvm::Optional<LangAS> getConstantAddressSpace() const override {
341 return getLangASFromTargetAS(AS.Constant);
Erich Keaneebba5922017-07-21 22:37:03 +0000342 }
343
344 /// \returns Target specific vtbl ptr address space.
345 unsigned getVtblPtrAddressSpace() const override { return AS.Constant; }
346
347 /// \returns If a target requires an address within a target specific address
348 /// space \p AddressSpace to be converted in order to be used, then return the
349 /// corresponding target specific DWARF address space.
350 ///
351 /// \returns Otherwise return None and no conversion will be emitted in the
352 /// DWARF.
353 Optional<unsigned>
354 getDWARFAddressSpace(unsigned AddressSpace) const override {
355 const unsigned DWARF_Private = 1;
356 const unsigned DWARF_Local = 2;
357 if (AddressSpace == AS.Private) {
358 return DWARF_Private;
359 } else if (AddressSpace == AS.Local) {
360 return DWARF_Local;
361 } else {
362 return None;
363 }
364 }
365
366 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
367 switch (CC) {
368 default:
369 return CCCR_Warning;
370 case CC_C:
371 case CC_OpenCLKernel:
372 return CCCR_OK;
373 }
374 }
375
376 // In amdgcn target the null pointer in global, constant, and generic
377 // address space has value 0 but in private and local address space has
378 // value ~0.
Alexander Richardson6d989432017-10-15 18:48:14 +0000379 uint64_t getNullPointerValue(LangAS AS) const override {
Erich Keaneebba5922017-07-21 22:37:03 +0000380 return AS == LangAS::opencl_local ? ~0 : 0;
381 }
382};
383
384} // namespace targets
385} // namespace clang
386
387#endif // LLVM_CLANG_LIB_BASIC_TARGETS_AMDGPU_H