clang  7.0.0svn
AMDGPU.h
Go to the documentation of this file.
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"
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  };
66 
67  struct GPUInfo {
68  llvm::StringLiteral Name;
69  llvm::StringLiteral CanonicalName;
70  AMDGPUTargetInfo::GPUKind Kind;
71  };
72 
73  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},
103  };
104  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},
135  };
136 
137  bool hasFP64 : 1;
138  bool hasFMAF : 1;
139  bool hasLDEXPF : 1;
140  const AddrSpace AS;
141 
142  static bool hasFullSpeedFMAF32(StringRef GPUName) {
143  return parseAMDGCNName(GPUName).Kind >= GK_GFX9;
144  }
145 
146  static bool isAMDGCN(const llvm::Triple &TT) {
147  return TT.getArch() == llvm::Triple::amdgcn;
148  }
149 
150  static bool isGenericZero(const llvm::Triple &TT) { return true; }
151 
152 public:
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 {
160  if (GPU.Kind <= GK_CAYMAN)
161  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 
182  return None;
183  }
184 
185  /// 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]}
193  bool validateAsmConstraint(const char *&Name,
194  TargetInfo::ConstraintInfo &Info) const override {
195  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.
219  Info.setAllowsRegister();
220  Name = S.data() - 1;
221  return true;
222  }
223  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;
262  }
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 
279  }
280 
281  static GPUInfo parseR600Name(StringRef Name);
282 
283  static GPUInfo parseAMDGCNName(StringRef Name);
284 
285  bool isValidCPUName(StringRef Name) const override {
286  if (getTriple().getArch() == llvm::Triple::amdgcn)
287  return GK_NONE != parseAMDGCNName(Name).Kind;
288  else
289  return GK_NONE != parseR600Name(Name).Kind;
290  }
291 
292  void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
293 
294  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 
300  return GPU.Kind != GK_NONE;
301  }
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");
310  if (GPU.Kind >= GK_EVERGREEN) {
311  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  }
317  if (GPU.Kind >= GK_GFX6) {
318  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 
330  switch (TK) {
331  case OCLTK_Image:
333 
334  case OCLTK_ClkEvent:
335  case OCLTK_Queue:
336  case OCLTK_ReserveID:
337  return LangAS::opencl_global;
338 
339  default:
341  }
342  }
343 
345  return getLangASFromTargetAS(AS.Constant);
346  }
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.
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 
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.
383  uint64_t getNullPointerValue(LangAS AS) const override {
384  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
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override
Determines whether a given calling convention is valid for the target.
Definition: AMDGPU.h:370
ArrayRef< TargetInfo::GCCRegAlias > getGCCRegAliases() const override
Definition: AMDGPU.h:181
uint64_t getPointerWidthV(unsigned AddrSpace) const override
Definition: AMDGPU.h:159
void setSupportedOpenCLOpts() override
Set supported OpenCL extensions and optional core features.
Definition: AMDGPU.h:303
static const Builtin::Info BuiltinInfo[]
Definition: Builtins.cpp:21
virtual LangAS getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const
Get address space for OpenCL type.
Definition: TargetInfo.cpp:359
LangAS getLangASFromTargetAS(unsigned TargetAS)
Definition: AddressSpaces.h:67
Options for controlling the target.
Definition: TargetOptions.h:26
LangAS
Defines the address space values used by the address space qualifier of QualType. ...
Definition: AddressSpaces.h:26
Optional< unsigned > getDWARFAddressSpace(unsigned AddressSpace) const override
Definition: AMDGPU.h:358
uint64_t getPointerAlignV(unsigned AddrSpace) const override
Definition: AMDGPU.h:169
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:50
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:149
LangAS getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const override
Get address space for OpenCL type.
Definition: AMDGPU.h:329
uint64_t getNullPointerValue(LangAS AS) const override
Get integer value for null pointer.
Definition: AMDGPU.h:383
static const char *const GCCRegNames[]
Definition: X86.cpp:44
bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &Info) const override
Accepted register names: (n, m is unsigned integer, n < m) v s {vn}, {v[n]} {sn}, {s[n]} {S} ...
Definition: AMDGPU.h:193
Exposes information about the current target.
Definition: TargetInfo.h:54
unsigned getVtblPtrAddressSpace() const override
Definition: AMDGPU.h:349
bool setCPU(const std::string &Name) override
Target the specified CPU.
Definition: AMDGPU.h:294
CallingConv
CallingConv - Specifies the calling convention that a function uses.
Definition: Specifiers.h:233
const char * getClobbers() const override
Returns a string of target-specific clobbers, in LLVM format.
Definition: AMDGPU.h:177
Kind
BuiltinVaListKind getBuiltinVaListKind() const override
Returns the kind of __builtin_va_list type that should be used with this target.
Definition: AMDGPU.h:277
Defines the clang::TargetOptions class.
llvm::Optional< LangAS > getConstantAddressSpace() const override
Return an AST address space which can be used opportunistically for constant global memory...
Definition: AMDGPU.h:344
bool isValidCPUName(StringRef Name) const override
brief Determine whether this TargetInfo supports the given CPU name.
Definition: AMDGPU.h:285
Dataflow Directional Tag Classes.
typedef char* __builtin_va_list;
Definition: TargetInfo.h:154
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
BuiltinVaListKind
The different kinds of __builtin_va_list types defined by the target implementation.
Definition: TargetInfo.h:152
Defines the clang::TargetInfo interface.
uint64_t getMaxPointerWidth() const override
Return the maximum width of pointers on this target.
Definition: AMDGPU.h:173