]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/Basic/Targets/AMDGPU.h
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / lib / Basic / Targets / AMDGPU.h
1 //===--- 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"
19 #include "llvm/ADT/StringSet.h"
20 #include "llvm/ADT/Triple.h"
21 #include "llvm/Support/Compiler.h"
22
23 namespace clang {
24 namespace targets {
25
26 class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo {
27
28   static const Builtin::Info BuiltinInfo[];
29   static const char *const GCCRegNames[];
30
31   enum AddrSpace {
32     Generic = 0,
33     Global = 1,
34     Local = 3,
35     Constant = 4,
36     Private = 5
37   };
38   static const LangASMap AMDGPUDefIsGenMap;
39   static const LangASMap AMDGPUDefIsPrivMap;
40
41   /// GPU kinds supported by the AMDGPU target.
42   enum GPUKind : uint32_t {
43     // Not specified processor.
44     GK_NONE = 0,
45
46     // R600-based processors.
47     GK_R600,
48     GK_R630,
49     GK_RS880,
50     GK_RV670,
51     GK_RV710,
52     GK_RV730,
53     GK_RV770,
54     GK_CEDAR,
55     GK_CYPRESS,
56     GK_JUNIPER,
57     GK_REDWOOD,
58     GK_SUMO,
59     GK_BARTS,
60     GK_CAICOS,
61     GK_CAYMAN,
62     GK_TURKS,
63
64     GK_R600_FIRST = GK_R600,
65     GK_R600_LAST = GK_TURKS,
66
67     // AMDGCN-based processors.
68     GK_GFX600,
69     GK_GFX601,
70     GK_GFX700,
71     GK_GFX701,
72     GK_GFX702,
73     GK_GFX703,
74     GK_GFX704,
75     GK_GFX801,
76     GK_GFX802,
77     GK_GFX803,
78     GK_GFX810,
79     GK_GFX900,
80     GK_GFX902,
81     GK_GFX904,
82     GK_GFX906,
83
84     GK_AMDGCN_FIRST = GK_GFX600,
85     GK_AMDGCN_LAST = GK_GFX906,
86   };
87
88   struct GPUInfo {
89     llvm::StringLiteral Name;
90     llvm::StringLiteral CanonicalName;
91     AMDGPUTargetInfo::GPUKind Kind;
92     bool HasFMAF;
93     bool HasFastFMAF;
94     bool HasLDEXPF;
95     bool HasFP64;
96     bool HasFastFMA;
97   };
98
99   static constexpr GPUInfo InvalidGPU =
100     {{""}, {""}, GK_NONE, false, false, false, false, false};
101   static constexpr GPUInfo R600GPUs[26] = {
102   // Name         Canonical    Kind        Has    Has    Has    Has    Has
103   //              Name                     FMAF   Fast   LDEXPF FP64   Fast
104   //                                              FMAF                 FMA
105     {{"r600"},    {"r600"},    GK_R600,    false, false, false, false, false},
106     {{"rv630"},   {"r600"},    GK_R600,    false, false, false, false, false},
107     {{"rv635"},   {"r600"},    GK_R600,    false, false, false, false, false},
108     {{"r630"},    {"r630"},    GK_R630,    false, false, false, false, false},
109     {{"rs780"},   {"rs880"},   GK_RS880,   false, false, false, false, false},
110     {{"rs880"},   {"rs880"},   GK_RS880,   false, false, false, false, false},
111     {{"rv610"},   {"rs880"},   GK_RS880,   false, false, false, false, false},
112     {{"rv620"},   {"rs880"},   GK_RS880,   false, false, false, false, false},
113     {{"rv670"},   {"rv670"},   GK_RV670,   false, false, false, false, false},
114     {{"rv710"},   {"rv710"},   GK_RV710,   false, false, false, false, false},
115     {{"rv730"},   {"rv730"},   GK_RV730,   false, false, false, false, false},
116     {{"rv740"},   {"rv770"},   GK_RV770,   false, false, false, false, false},
117     {{"rv770"},   {"rv770"},   GK_RV770,   false, false, false, false, false},
118     {{"cedar"},   {"cedar"},   GK_CEDAR,   false, false, false, false, false},
119     {{"palm"},    {"cedar"},   GK_CEDAR,   false, false, false, false, false},
120     {{"cypress"}, {"cypress"}, GK_CYPRESS, true,  false, false, false, false},
121     {{"hemlock"}, {"cypress"}, GK_CYPRESS, true,  false, false, false, false},
122     {{"juniper"}, {"juniper"}, GK_JUNIPER, false, false, false, false, false},
123     {{"redwood"}, {"redwood"}, GK_REDWOOD, false, false, false, false, false},
124     {{"sumo"},    {"sumo"},    GK_SUMO,    false, false, false, false, false},
125     {{"sumo2"},   {"sumo"},    GK_SUMO,    false, false, false, false, false},
126     {{"barts"},   {"barts"},   GK_BARTS,   false, false, false, false, false},
127     {{"caicos"},  {"caicos"},  GK_BARTS,   false, false, false, false, false},
128     {{"aruba"},   {"cayman"},  GK_CAYMAN,  true,  false, false, false, false},
129     {{"cayman"},  {"cayman"},  GK_CAYMAN,  true,  false, false, false, false},
130     {{"turks"},   {"turks"},   GK_TURKS,   false, false, false, false, false},
131   };
132   static constexpr GPUInfo AMDGCNGPUs[32] = {
133   // Name           Canonical    Kind        Has   Has    Has    Has   Has
134   //                Name                     FMAF  Fast   LDEXPF FP64  Fast
135   //                                               FMAF                FMA
136     {{"gfx600"},    {"gfx600"},  GK_GFX600,  true, true,  true,  true, true},
137     {{"tahiti"},    {"gfx600"},  GK_GFX600,  true, true,  true,  true, true},
138     {{"gfx601"},    {"gfx601"},  GK_GFX601,  true, false, true,  true, true},
139     {{"hainan"},    {"gfx601"},  GK_GFX601,  true, false, true,  true, true},
140     {{"oland"},     {"gfx601"},  GK_GFX601,  true, false, true,  true, true},
141     {{"pitcairn"},  {"gfx601"},  GK_GFX601,  true, false, true,  true, true},
142     {{"verde"},     {"gfx601"},  GK_GFX601,  true, false, true,  true, true},
143     {{"gfx700"},    {"gfx700"},  GK_GFX700,  true, false, true,  true, true},
144     {{"kaveri"},    {"gfx700"},  GK_GFX700,  true, false, true,  true, true},
145     {{"gfx701"},    {"gfx701"},  GK_GFX701,  true, true,  true,  true, true},
146     {{"hawaii"},    {"gfx701"},  GK_GFX701,  true, true,  true,  true, true},
147     {{"gfx702"},    {"gfx702"},  GK_GFX702,  true, true,  true,  true, true},
148     {{"gfx703"},    {"gfx703"},  GK_GFX703,  true, false, true,  true, true},
149     {{"kabini"},    {"gfx703"},  GK_GFX703,  true, false, true,  true, true},
150     {{"mullins"},   {"gfx703"},  GK_GFX703,  true, false, true,  true, true},
151     {{"gfx704"},    {"gfx704"},  GK_GFX704,  true, false, true,  true, true},
152     {{"bonaire"},   {"gfx704"},  GK_GFX704,  true, false, true,  true, true},
153     {{"gfx801"},    {"gfx801"},  GK_GFX801,  true, true,  true,  true, true},
154     {{"carrizo"},   {"gfx801"},  GK_GFX801,  true, true,  true,  true, true},
155     {{"gfx802"},    {"gfx802"},  GK_GFX802,  true, false, true,  true, true},
156     {{"iceland"},   {"gfx802"},  GK_GFX802,  true, false, true,  true, true},
157     {{"tonga"},     {"gfx802"},  GK_GFX802,  true, false, true,  true, true},
158     {{"gfx803"},    {"gfx803"},  GK_GFX803,  true, false, true,  true, true},
159     {{"fiji"},      {"gfx803"},  GK_GFX803,  true, false, true,  true, true},
160     {{"polaris10"}, {"gfx803"},  GK_GFX803,  true, false, true,  true, true},
161     {{"polaris11"}, {"gfx803"},  GK_GFX803,  true, false, true,  true, true},
162     {{"gfx810"},    {"gfx810"},  GK_GFX810,  true, false, true,  true, true},
163     {{"stoney"},    {"gfx810"},  GK_GFX810,  true, false, true,  true, true},
164     {{"gfx900"},    {"gfx900"},  GK_GFX900,  true, true,  true,  true, true},
165     {{"gfx902"},    {"gfx902"},  GK_GFX900,  true, true,  true,  true, true},
166     {{"gfx904"},    {"gfx904"},  GK_GFX904,  true, true,  true,  true, true},
167     {{"gfx906"},    {"gfx906"},  GK_GFX906,  true, true,  true,  true, true},
168   };
169
170   static GPUInfo parseR600Name(StringRef Name);
171
172   static GPUInfo parseAMDGCNName(StringRef Name);
173
174   GPUInfo parseGPUName(StringRef Name) const;
175
176   GPUInfo GPU;
177
178   static bool isAMDGCN(const llvm::Triple &TT) {
179     return TT.getArch() == llvm::Triple::amdgcn;
180   }
181
182 public:
183   AMDGPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
184
185   void setAddressSpaceMap(bool DefaultIsPrivate);
186
187   void adjust(LangOptions &Opts) override;
188
189   uint64_t getPointerWidthV(unsigned AddrSpace) const override {
190     if (GPU.Kind <= GK_R600_LAST)
191       return 32;
192     if (AddrSpace == Private || AddrSpace == Local)
193       return 32;
194     return 64;
195   }
196
197   uint64_t getPointerAlignV(unsigned AddrSpace) const override {
198     return getPointerWidthV(AddrSpace);
199   }
200
201   uint64_t getMaxPointerWidth() const override {
202     return getTriple().getArch() == llvm::Triple::amdgcn ? 64 : 32;
203   }
204
205   const char *getClobbers() const override { return ""; }
206
207   ArrayRef<const char *> getGCCRegNames() const override;
208
209   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
210     return None;
211   }
212
213   /// Accepted register names: (n, m is unsigned integer, n < m)
214   /// v
215   /// s
216   /// {vn}, {v[n]}
217   /// {sn}, {s[n]}
218   /// {S} , where S is a special register name
219   ////{v[n:m]}
220   /// {s[n:m]}
221   bool validateAsmConstraint(const char *&Name,
222                              TargetInfo::ConstraintInfo &Info) const override {
223     static const ::llvm::StringSet<> SpecialRegs({
224         "exec", "vcc", "flat_scratch", "m0", "scc", "tba", "tma",
225         "flat_scratch_lo", "flat_scratch_hi", "vcc_lo", "vcc_hi", "exec_lo",
226         "exec_hi", "tma_lo", "tma_hi", "tba_lo", "tba_hi",
227     });
228
229     StringRef S(Name);
230     bool HasLeftParen = false;
231     if (S.front() == '{') {
232       HasLeftParen = true;
233       S = S.drop_front();
234     }
235     if (S.empty())
236       return false;
237     if (S.front() != 'v' && S.front() != 's') {
238       if (!HasLeftParen)
239         return false;
240       auto E = S.find('}');
241       if (!SpecialRegs.count(S.substr(0, E)))
242         return false;
243       S = S.drop_front(E + 1);
244       if (!S.empty())
245         return false;
246       // Found {S} where S is a special register.
247       Info.setAllowsRegister();
248       Name = S.data() - 1;
249       return true;
250     }
251     S = S.drop_front();
252     if (!HasLeftParen) {
253       if (!S.empty())
254         return false;
255       // Found s or v.
256       Info.setAllowsRegister();
257       Name = S.data() - 1;
258       return true;
259     }
260     bool HasLeftBracket = false;
261     if (!S.empty() && S.front() == '[') {
262       HasLeftBracket = true;
263       S = S.drop_front();
264     }
265     unsigned long long N;
266     if (S.empty() || consumeUnsignedInteger(S, 10, N))
267       return false;
268     if (!S.empty() && S.front() == ':') {
269       if (!HasLeftBracket)
270         return false;
271       S = S.drop_front();
272       unsigned long long M;
273       if (consumeUnsignedInteger(S, 10, M) || N >= M)
274         return false;
275     }
276     if (HasLeftBracket) {
277       if (S.empty() || S.front() != ']')
278         return false;
279       S = S.drop_front();
280     }
281     if (S.empty() || S.front() != '}')
282       return false;
283     S = S.drop_front();
284     if (!S.empty())
285       return false;
286     // Found {vn}, {sn}, {v[n]}, {s[n]}, {v[n:m]}, or {s[n:m]}.
287     Info.setAllowsRegister();
288     Name = S.data() - 1;
289     return true;
290   }
291
292   // \p Constraint will be left pointing at the last character of
293   // the constraint.  In practice, it won't be changed unless the
294   // constraint is longer than one character.
295   std::string convertConstraint(const char *&Constraint) const override {
296     const char *Begin = Constraint;
297     TargetInfo::ConstraintInfo Info("", "");
298     if (validateAsmConstraint(Constraint, Info))
299       return std::string(Begin).substr(0, Constraint - Begin + 1);
300
301     Constraint = Begin;
302     return std::string(1, *Constraint);
303   }
304
305   bool
306   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
307                  StringRef CPU,
308                  const std::vector<std::string> &FeatureVec) const override;
309
310   void adjustTargetOptions(const CodeGenOptions &CGOpts,
311                            TargetOptions &TargetOpts) const override;
312
313   ArrayRef<Builtin::Info> getTargetBuiltins() const override;
314
315   void getTargetDefines(const LangOptions &Opts,
316                         MacroBuilder &Builder) const override;
317
318   BuiltinVaListKind getBuiltinVaListKind() const override {
319     return TargetInfo::CharPtrBuiltinVaList;
320   }
321
322   bool isValidCPUName(StringRef Name) const override {
323     if (getTriple().getArch() == llvm::Triple::amdgcn)
324       return GK_NONE != parseAMDGCNName(Name).Kind;
325     else
326       return GK_NONE != parseR600Name(Name).Kind;
327   }
328
329   void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
330
331   bool setCPU(const std::string &Name) override {
332     if (getTriple().getArch() == llvm::Triple::amdgcn)
333       GPU = parseAMDGCNName(Name);
334     else
335       GPU = parseR600Name(Name);
336
337     return GK_NONE != GPU.Kind;
338   }
339
340   void setSupportedOpenCLOpts() override {
341     auto &Opts = getSupportedOpenCLOpts();
342     Opts.support("cl_clang_storage_class_specifiers");
343     Opts.support("cl_khr_icd");
344
345     if (GPU.HasFP64)
346       Opts.support("cl_khr_fp64");
347     if (GPU.Kind >= GK_CEDAR) {
348       Opts.support("cl_khr_byte_addressable_store");
349       Opts.support("cl_khr_global_int32_base_atomics");
350       Opts.support("cl_khr_global_int32_extended_atomics");
351       Opts.support("cl_khr_local_int32_base_atomics");
352       Opts.support("cl_khr_local_int32_extended_atomics");
353     }
354     if (GPU.Kind >= GK_AMDGCN_FIRST) {
355       Opts.support("cl_khr_fp16");
356       Opts.support("cl_khr_int64_base_atomics");
357       Opts.support("cl_khr_int64_extended_atomics");
358       Opts.support("cl_khr_mipmap_image");
359       Opts.support("cl_khr_subgroups");
360       Opts.support("cl_khr_3d_image_writes");
361       Opts.support("cl_amd_media_ops");
362       Opts.support("cl_amd_media_ops2");
363     }
364   }
365
366   LangAS getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const override {
367     switch (TK) {
368     case OCLTK_Image:
369       return LangAS::opencl_constant;
370
371     case OCLTK_ClkEvent:
372     case OCLTK_Queue:
373     case OCLTK_ReserveID:
374       return LangAS::opencl_global;
375
376     default:
377       return TargetInfo::getOpenCLTypeAddrSpace(TK);
378     }
379   }
380
381   llvm::Optional<LangAS> getConstantAddressSpace() const override {
382     return getLangASFromTargetAS(Constant);
383   }
384
385   /// \returns Target specific vtbl ptr address space.
386   unsigned getVtblPtrAddressSpace() const override {
387     return static_cast<unsigned>(Constant);
388   }
389
390   /// \returns If a target requires an address within a target specific address
391   /// space \p AddressSpace to be converted in order to be used, then return the
392   /// corresponding target specific DWARF address space.
393   ///
394   /// \returns Otherwise return None and no conversion will be emitted in the
395   /// DWARF.
396   Optional<unsigned>
397   getDWARFAddressSpace(unsigned AddressSpace) const override {
398     const unsigned DWARF_Private = 1;
399     const unsigned DWARF_Local = 2;
400     if (AddressSpace == Private) {
401       return DWARF_Private;
402     } else if (AddressSpace == Local) {
403       return DWARF_Local;
404     } else {
405       return None;
406     }
407   }
408
409   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
410     switch (CC) {
411     default:
412       return CCCR_Warning;
413     case CC_C:
414     case CC_OpenCLKernel:
415       return CCCR_OK;
416     }
417   }
418
419   // In amdgcn target the null pointer in global, constant, and generic
420   // address space has value 0 but in private and local address space has
421   // value ~0.
422   uint64_t getNullPointerValue(LangAS AS) const override {
423     return AS == LangAS::opencl_local ? ~0 : 0;
424   }
425 };
426
427 } // namespace targets
428 } // namespace clang
429
430 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_AMDGPU_H