]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/Basic/Targets/AMDGPU.h
Update to bmake-201802222
[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   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
65   } GPU;
66
67   bool hasFP64 : 1;
68   bool hasFMAF : 1;
69   bool hasLDEXPF : 1;
70   const AddrSpace AS;
71
72   static bool hasFullSpeedFMAF32(StringRef GPUName) {
73     return parseAMDGCNName(GPUName) >= GK_GFX9;
74   }
75
76   static bool isAMDGCN(const llvm::Triple &TT) {
77     return TT.getArch() == llvm::Triple::amdgcn;
78   }
79
80   static bool isGenericZero(const llvm::Triple &TT) {
81     return TT.getEnvironmentName() == "amdgiz" ||
82            TT.getEnvironmentName() == "amdgizcl";
83   }
84
85 public:
86   AMDGPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
87
88   void setAddressSpaceMap(bool DefaultIsPrivate);
89
90   void adjust(LangOptions &Opts) override;
91
92   uint64_t getPointerWidthV(unsigned AddrSpace) const override {
93     if (GPU <= GK_CAYMAN)
94       return 32;
95
96     if (AddrSpace == AS.Private || AddrSpace == AS.Local) {
97       return 32;
98     }
99     return 64;
100   }
101
102   uint64_t getPointerAlignV(unsigned AddrSpace) const override {
103     return getPointerWidthV(AddrSpace);
104   }
105
106   uint64_t getMaxPointerWidth() const override {
107     return getTriple().getArch() == llvm::Triple::amdgcn ? 64 : 32;
108   }
109
110   const char *getClobbers() const override { return ""; }
111
112   ArrayRef<const char *> getGCCRegNames() const override;
113
114   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
115     return None;
116   }
117
118   /// Accepted register names: (n, m is unsigned integer, n < m)
119   /// v
120   /// s
121   /// {vn}, {v[n]}
122   /// {sn}, {s[n]}
123   /// {S} , where S is a special register name
124   ////{v[n:m]}
125   /// {s[n:m]}
126   bool validateAsmConstraint(const char *&Name,
127                              TargetInfo::ConstraintInfo &Info) const override {
128     static const ::llvm::StringSet<> SpecialRegs({
129         "exec", "vcc", "flat_scratch", "m0", "scc", "tba", "tma",
130         "flat_scratch_lo", "flat_scratch_hi", "vcc_lo", "vcc_hi", "exec_lo",
131         "exec_hi", "tma_lo", "tma_hi", "tba_lo", "tba_hi",
132     });
133
134     StringRef S(Name);
135     bool HasLeftParen = false;
136     if (S.front() == '{') {
137       HasLeftParen = true;
138       S = S.drop_front();
139     }
140     if (S.empty())
141       return false;
142     if (S.front() != 'v' && S.front() != 's') {
143       if (!HasLeftParen)
144         return false;
145       auto E = S.find('}');
146       if (!SpecialRegs.count(S.substr(0, E)))
147         return false;
148       S = S.drop_front(E + 1);
149       if (!S.empty())
150         return false;
151       // Found {S} where S is a special register.
152       Info.setAllowsRegister();
153       Name = S.data() - 1;
154       return true;
155     }
156     S = S.drop_front();
157     if (!HasLeftParen) {
158       if (!S.empty())
159         return false;
160       // Found s or v.
161       Info.setAllowsRegister();
162       Name = S.data() - 1;
163       return true;
164     }
165     bool HasLeftBracket = false;
166     if (!S.empty() && S.front() == '[') {
167       HasLeftBracket = true;
168       S = S.drop_front();
169     }
170     unsigned long long N;
171     if (S.empty() || consumeUnsignedInteger(S, 10, N))
172       return false;
173     if (!S.empty() && S.front() == ':') {
174       if (!HasLeftBracket)
175         return false;
176       S = S.drop_front();
177       unsigned long long M;
178       if (consumeUnsignedInteger(S, 10, M) || N >= M)
179         return false;
180     }
181     if (HasLeftBracket) {
182       if (S.empty() || S.front() != ']')
183         return false;
184       S = S.drop_front();
185     }
186     if (S.empty() || S.front() != '}')
187       return false;
188     S = S.drop_front();
189     if (!S.empty())
190       return false;
191     // Found {vn}, {sn}, {v[n]}, {s[n]}, {v[n:m]}, or {s[n:m]}.
192     Info.setAllowsRegister();
193     Name = S.data() - 1;
194     return true;
195   }
196
197   bool
198   initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
199                  StringRef CPU,
200                  const std::vector<std::string> &FeatureVec) const override;
201
202   void adjustTargetOptions(const CodeGenOptions &CGOpts,
203                            TargetOptions &TargetOpts) const override;
204
205   ArrayRef<Builtin::Info> getTargetBuiltins() const override;
206
207   void getTargetDefines(const LangOptions &Opts,
208                         MacroBuilder &Builder) const override;
209
210   BuiltinVaListKind getBuiltinVaListKind() const override {
211     return TargetInfo::CharPtrBuiltinVaList;
212   }
213
214   static GPUKind parseR600Name(StringRef Name);
215
216   static GPUKind parseAMDGCNName(StringRef Name);
217
218   bool isValidCPUName(StringRef Name) const override {
219     if (getTriple().getArch() == llvm::Triple::amdgcn)
220       return GK_NONE != parseAMDGCNName(Name);
221     else
222       return GK_NONE != parseR600Name(Name);
223   }
224
225   bool setCPU(const std::string &Name) override {
226     if (getTriple().getArch() == llvm::Triple::amdgcn)
227       GPU = parseAMDGCNName(Name);
228     else
229       GPU = parseR600Name(Name);
230
231     return GPU != GK_NONE;
232   }
233
234   void setSupportedOpenCLOpts() override {
235     auto &Opts = getSupportedOpenCLOpts();
236     Opts.support("cl_clang_storage_class_specifiers");
237     Opts.support("cl_khr_icd");
238
239     if (hasFP64)
240       Opts.support("cl_khr_fp64");
241     if (GPU >= GK_EVERGREEN) {
242       Opts.support("cl_khr_byte_addressable_store");
243       Opts.support("cl_khr_global_int32_base_atomics");
244       Opts.support("cl_khr_global_int32_extended_atomics");
245       Opts.support("cl_khr_local_int32_base_atomics");
246       Opts.support("cl_khr_local_int32_extended_atomics");
247     }
248     if (GPU >= GK_GFX6) {
249       Opts.support("cl_khr_fp16");
250       Opts.support("cl_khr_int64_base_atomics");
251       Opts.support("cl_khr_int64_extended_atomics");
252       Opts.support("cl_khr_mipmap_image");
253       Opts.support("cl_khr_subgroups");
254       Opts.support("cl_khr_3d_image_writes");
255       Opts.support("cl_amd_media_ops");
256       Opts.support("cl_amd_media_ops2");
257     }
258   }
259
260   LangAS getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const override {
261     switch (TK) {
262     case OCLTK_Image:
263       return LangAS::opencl_constant;
264
265     case OCLTK_ClkEvent:
266     case OCLTK_Queue:
267     case OCLTK_ReserveID:
268       return LangAS::opencl_global;
269
270     default:
271       return TargetInfo::getOpenCLTypeAddrSpace(TK);
272     }
273   }
274
275   llvm::Optional<LangAS> getConstantAddressSpace() const override {
276     return getLangASFromTargetAS(AS.Constant);
277   }
278
279   /// \returns Target specific vtbl ptr address space.
280   unsigned getVtblPtrAddressSpace() const override { return AS.Constant; }
281
282   /// \returns If a target requires an address within a target specific address
283   /// space \p AddressSpace to be converted in order to be used, then return the
284   /// corresponding target specific DWARF address space.
285   ///
286   /// \returns Otherwise return None and no conversion will be emitted in the
287   /// DWARF.
288   Optional<unsigned>
289   getDWARFAddressSpace(unsigned AddressSpace) const override {
290     const unsigned DWARF_Private = 1;
291     const unsigned DWARF_Local = 2;
292     if (AddressSpace == AS.Private) {
293       return DWARF_Private;
294     } else if (AddressSpace == AS.Local) {
295       return DWARF_Local;
296     } else {
297       return None;
298     }
299   }
300
301   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
302     switch (CC) {
303     default:
304       return CCCR_Warning;
305     case CC_C:
306     case CC_OpenCLKernel:
307       return CCCR_OK;
308     }
309   }
310
311   // In amdgcn target the null pointer in global, constant, and generic
312   // address space has value 0 but in private and local address space has
313   // value ~0.
314   uint64_t getNullPointerValue(LangAS AS) const override {
315     return AS == LangAS::opencl_local ? ~0 : 0;
316   }
317 };
318
319 } // namespace targets
320 } // namespace clang
321
322 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_AMDGPU_H