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