clang  9.0.0svn
AMDGPU.h
Go to the documentation of this file.
1 //===--- AMDGPU.h - Declare AMDGPU target feature support -------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file declares AMDGPU TargetInfo objects.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_AMDGPU_H
14 #define LLVM_CLANG_LIB_BASIC_TARGETS_AMDGPU_H
15 
16 #include "clang/Basic/TargetInfo.h"
18 #include "llvm/ADT/StringSet.h"
19 #include "llvm/ADT/Triple.h"
20 #include "llvm/Support/Compiler.h"
21 #include "llvm/Support/TargetParser.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  llvm::AMDGPU::GPUKind GPUKind;
42  unsigned GPUFeatures;
43 
44 
45  bool hasFP64() const {
46  return getTriple().getArch() == llvm::Triple::amdgcn ||
47  !!(GPUFeatures & llvm::AMDGPU::FEATURE_FP64);
48  }
49 
50  /// Has fast fma f32
51  bool hasFastFMAF() const {
52  return !!(GPUFeatures & llvm::AMDGPU::FEATURE_FAST_FMA_F32);
53  }
54 
55  /// Has fast fma f64
56  bool hasFastFMA() const {
57  return getTriple().getArch() == llvm::Triple::amdgcn;
58  }
59 
60  bool hasFMAF() const {
61  return getTriple().getArch() == llvm::Triple::amdgcn ||
62  !!(GPUFeatures & llvm::AMDGPU::FEATURE_FMA);
63  }
64 
65  bool hasFullRateDenormalsF32() const {
66  return !!(GPUFeatures & llvm::AMDGPU::FEATURE_FAST_DENORMAL_F32);
67  }
68 
69  bool hasLDEXPF() const {
70  return getTriple().getArch() == llvm::Triple::amdgcn ||
71  !!(GPUFeatures & llvm::AMDGPU::FEATURE_LDEXP);
72  }
73 
74  static bool isAMDGCN(const llvm::Triple &TT) {
75  return TT.getArch() == llvm::Triple::amdgcn;
76  }
77 
78  static bool isR600(const llvm::Triple &TT) {
79  return TT.getArch() == llvm::Triple::r600;
80  }
81 
82 public:
83  AMDGPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
84 
85  void setAddressSpaceMap(bool DefaultIsPrivate);
86 
87  void adjust(LangOptions &Opts) override;
88 
89  uint64_t getPointerWidthV(unsigned AddrSpace) const override {
90  if (isR600(getTriple()))
91  return 32;
92 
93  if (AddrSpace == Private || AddrSpace == Local)
94  return 32;
95 
96  return 64;
97  }
98 
99  uint64_t getPointerAlignV(unsigned AddrSpace) const override {
100  return getPointerWidthV(AddrSpace);
101  }
102 
103  uint64_t getMaxPointerWidth() const override {
104  return getTriple().getArch() == llvm::Triple::amdgcn ? 64 : 32;
105  }
106 
107  const char *getClobbers() const override { return ""; }
108 
109  ArrayRef<const char *> getGCCRegNames() const override;
110 
112  return None;
113  }
114 
115  /// Accepted register names: (n, m is unsigned integer, n < m)
116  /// v
117  /// s
118  /// {vn}, {v[n]}
119  /// {sn}, {s[n]}
120  /// {S} , where S is a special register name
121  ////{v[n:m]}
122  /// {s[n:m]}
123  bool validateAsmConstraint(const char *&Name,
124  TargetInfo::ConstraintInfo &Info) const override {
125  static const ::llvm::StringSet<> SpecialRegs({
126  "exec", "vcc", "flat_scratch", "m0", "scc", "tba", "tma",
127  "flat_scratch_lo", "flat_scratch_hi", "vcc_lo", "vcc_hi", "exec_lo",
128  "exec_hi", "tma_lo", "tma_hi", "tba_lo", "tba_hi",
129  });
130 
131  StringRef S(Name);
132  bool HasLeftParen = false;
133  if (S.front() == '{') {
134  HasLeftParen = true;
135  S = S.drop_front();
136  }
137  if (S.empty())
138  return false;
139  if (S.front() != 'v' && S.front() != 's') {
140  if (!HasLeftParen)
141  return false;
142  auto E = S.find('}');
143  if (!SpecialRegs.count(S.substr(0, E)))
144  return false;
145  S = S.drop_front(E + 1);
146  if (!S.empty())
147  return false;
148  // Found {S} where S is a special register.
149  Info.setAllowsRegister();
150  Name = S.data() - 1;
151  return true;
152  }
153  S = S.drop_front();
154  if (!HasLeftParen) {
155  if (!S.empty())
156  return false;
157  // Found s or v.
158  Info.setAllowsRegister();
159  Name = S.data() - 1;
160  return true;
161  }
162  bool HasLeftBracket = false;
163  if (!S.empty() && S.front() == '[') {
164  HasLeftBracket = true;
165  S = S.drop_front();
166  }
167  unsigned long long N;
168  if (S.empty() || consumeUnsignedInteger(S, 10, N))
169  return false;
170  if (!S.empty() && S.front() == ':') {
171  if (!HasLeftBracket)
172  return false;
173  S = S.drop_front();
174  unsigned long long M;
175  if (consumeUnsignedInteger(S, 10, M) || N >= M)
176  return false;
177  }
178  if (HasLeftBracket) {
179  if (S.empty() || S.front() != ']')
180  return false;
181  S = S.drop_front();
182  }
183  if (S.empty() || S.front() != '}')
184  return false;
185  S = S.drop_front();
186  if (!S.empty())
187  return false;
188  // Found {vn}, {sn}, {v[n]}, {s[n]}, {v[n:m]}, or {s[n:m]}.
189  Info.setAllowsRegister();
190  Name = S.data() - 1;
191  return true;
192  }
193 
194  // \p Constraint will be left pointing at the last character of
195  // the constraint. In practice, it won't be changed unless the
196  // constraint is longer than one character.
197  std::string convertConstraint(const char *&Constraint) const override {
198  const char *Begin = Constraint;
199  TargetInfo::ConstraintInfo Info("", "");
200  if (validateAsmConstraint(Constraint, Info))
201  return std::string(Begin).substr(0, Constraint - Begin + 1);
202 
203  Constraint = Begin;
204  return std::string(1, *Constraint);
205  }
206 
207  bool
208  initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
209  StringRef CPU,
210  const std::vector<std::string> &FeatureVec) const override;
211 
212  void adjustTargetOptions(const CodeGenOptions &CGOpts,
213  TargetOptions &TargetOpts) const override;
214 
215  ArrayRef<Builtin::Info> getTargetBuiltins() const override;
216 
217  void getTargetDefines(const LangOptions &Opts,
218  MacroBuilder &Builder) const override;
219 
222  }
223 
224  bool isValidCPUName(StringRef Name) const override {
225  if (getTriple().getArch() == llvm::Triple::amdgcn)
226  return llvm::AMDGPU::parseArchAMDGCN(Name) != llvm::AMDGPU::GK_NONE;
227  return llvm::AMDGPU::parseArchR600(Name) != llvm::AMDGPU::GK_NONE;
228  }
229 
230  void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
231 
232  bool setCPU(const std::string &Name) override {
233  if (getTriple().getArch() == llvm::Triple::amdgcn) {
234  GPUKind = llvm::AMDGPU::parseArchAMDGCN(Name);
235  GPUFeatures = llvm::AMDGPU::getArchAttrAMDGCN(GPUKind);
236  } else {
237  GPUKind = llvm::AMDGPU::parseArchR600(Name);
238  GPUFeatures = llvm::AMDGPU::getArchAttrR600(GPUKind);
239  }
240 
241  return GPUKind != llvm::AMDGPU::GK_NONE;
242  }
243 
244  void setSupportedOpenCLOpts() override {
245  auto &Opts = getSupportedOpenCLOpts();
246  Opts.support("cl_clang_storage_class_specifiers");
247  Opts.support("cl_khr_icd");
248 
249  bool IsAMDGCN = isAMDGCN(getTriple());
250 
251  if (hasFP64())
252  Opts.support("cl_khr_fp64");
253 
254  if (IsAMDGCN || GPUKind >= llvm::AMDGPU::GK_CEDAR) {
255  Opts.support("cl_khr_byte_addressable_store");
256  Opts.support("cl_khr_global_int32_base_atomics");
257  Opts.support("cl_khr_global_int32_extended_atomics");
258  Opts.support("cl_khr_local_int32_base_atomics");
259  Opts.support("cl_khr_local_int32_extended_atomics");
260  }
261 
262  if (IsAMDGCN) {
263  Opts.support("cl_khr_fp16");
264  Opts.support("cl_khr_int64_base_atomics");
265  Opts.support("cl_khr_int64_extended_atomics");
266  Opts.support("cl_khr_mipmap_image");
267  Opts.support("cl_khr_subgroups");
268  Opts.support("cl_khr_3d_image_writes");
269  Opts.support("cl_amd_media_ops");
270  Opts.support("cl_amd_media_ops2");
271  }
272  }
273 
275  switch (TK) {
276  case OCLTK_Image:
278 
279  case OCLTK_ClkEvent:
280  case OCLTK_Queue:
281  case OCLTK_ReserveID:
282  return LangAS::opencl_global;
283 
284  default:
286  }
287  }
288 
289  LangAS getOpenCLBuiltinAddressSpace(unsigned AS) const override {
290  switch (AS) {
291  case 0:
292  return LangAS::opencl_generic;
293  case 1:
294  return LangAS::opencl_global;
295  case 3:
296  return LangAS::opencl_local;
297  case 4:
299  case 5:
300  return LangAS::opencl_private;
301  default:
302  return getLangASFromTargetAS(AS);
303  }
304  }
305 
306  LangAS getCUDABuiltinAddressSpace(unsigned AS) const override {
307  return LangAS::Default;
308  }
309 
311  return getLangASFromTargetAS(Constant);
312  }
313 
314  /// \returns Target specific vtbl ptr address space.
315  unsigned getVtblPtrAddressSpace() const override {
316  return static_cast<unsigned>(Constant);
317  }
318 
319  /// \returns If a target requires an address within a target specific address
320  /// space \p AddressSpace to be converted in order to be used, then return the
321  /// corresponding target specific DWARF address space.
322  ///
323  /// \returns Otherwise return None and no conversion will be emitted in the
324  /// DWARF.
326  getDWARFAddressSpace(unsigned AddressSpace) const override {
327  const unsigned DWARF_Private = 1;
328  const unsigned DWARF_Local = 2;
329  if (AddressSpace == Private) {
330  return DWARF_Private;
331  } else if (AddressSpace == Local) {
332  return DWARF_Local;
333  } else {
334  return None;
335  }
336  }
337 
339  switch (CC) {
340  default:
341  return CCCR_Warning;
342  case CC_C:
343  case CC_OpenCLKernel:
344  return CCCR_OK;
345  }
346  }
347 
348  // In amdgcn target the null pointer in global, constant, and generic
349  // address space has value 0 but in private and local address space has
350  // value ~0.
351  uint64_t getNullPointerValue(LangAS AS) const override {
352  return AS == LangAS::opencl_local ? ~0 : 0;
353  }
354 
355  void setAuxTarget(const TargetInfo *Aux) override;
356 };
357 
358 } // namespace targets
359 } // namespace clang
360 
361 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_AMDGPU_H
std::string convertConstraint(const char *&Constraint) const override
Definition: AMDGPU.h:197
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override
Determines whether a given calling convention is valid for the target.
Definition: AMDGPU.h:338
ArrayRef< TargetInfo::GCCRegAlias > getGCCRegAliases() const override
Definition: AMDGPU.h:111
uint64_t getPointerWidthV(unsigned AddrSpace) const override
Definition: AMDGPU.h:89
void setSupportedOpenCLOpts() override
Set supported OpenCL extensions and optional core features.
Definition: AMDGPU.h:244
static const Builtin::Info BuiltinInfo[]
Definition: Builtins.cpp:20
virtual LangAS getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const
Get address space for OpenCL type.
Definition: TargetInfo.cpp:405
LangAS getLangASFromTargetAS(unsigned TargetAS)
Definition: AddressSpaces.h:66
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:25
Optional< unsigned > getDWARFAddressSpace(unsigned AddressSpace) const override
Definition: AMDGPU.h:326
uint64_t getPointerAlignV(unsigned AddrSpace) const override
Definition: AMDGPU.h:99
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:49
LangAS getCUDABuiltinAddressSpace(unsigned AS) const override
Map from the address space field in builtin description strings to the language address space...
Definition: AMDGPU.h:306
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:148
LangAS getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const override
Get address space for OpenCL type.
Definition: AMDGPU.h:274
uint64_t getNullPointerValue(LangAS AS) const override
Get integer value for null pointer.
Definition: AMDGPU.h:351
static const char *const GCCRegNames[]
Definition: X86.cpp:43
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:123
Exposes information about the current target.
Definition: TargetInfo.h:161
unsigned getVtblPtrAddressSpace() const override
Definition: AMDGPU.h:315
bool setCPU(const std::string &Name) override
Target the specified CPU.
Definition: AMDGPU.h:232
SourceLocation Begin
CallingConv
CallingConv - Specifies the calling convention that a function uses.
Definition: Specifiers.h:235
const char * getClobbers() const override
Returns a string of target-specific clobbers, in LLVM format.
Definition: AMDGPU.h:107
BuiltinVaListKind getBuiltinVaListKind() const override
Returns the kind of __builtin_va_list type that should be used with this target.
Definition: AMDGPU.h:220
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:310
bool isValidCPUName(StringRef Name) const override
brief Determine whether this TargetInfo supports the given CPU name.
Definition: AMDGPU.h:224
Dataflow Directional Tag Classes.
typedef char* __builtin_va_list;
Definition: TargetInfo.h:225
unsigned[(unsigned) LangAS::FirstTargetAddressSpace] LangASMap
The type of a lookup table which maps from language-specific address spaces to target-specific ones...
Definition: AddressSpaces.h:53
LangAS getOpenCLBuiltinAddressSpace(unsigned AS) const override
Map from the address space field in builtin description strings to the language address space...
Definition: AMDGPU.h:289
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:223
Defines the clang::TargetInfo interface.
uint64_t getMaxPointerWidth() const override
Return the maximum width of pointers on this target.
Definition: AMDGPU.h:103