clang  6.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  } 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 
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 
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 
261  switch (TK) {
262  case OCLTK_Image:
264 
265  case OCLTK_ClkEvent:
266  case OCLTK_Queue:
267  case OCLTK_ReserveID:
268  return LangAS::opencl_global;
269 
270  default:
272  }
273  }
274 
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.
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 
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
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override
Determines whether a given calling convention is valid for the target.
Definition: AMDGPU.h:301
ArrayRef< TargetInfo::GCCRegAlias > getGCCRegAliases() const override
Definition: AMDGPU.h:114
uint64_t getPointerWidthV(unsigned AddrSpace) const override
Definition: AMDGPU.h:92
void setSupportedOpenCLOpts() override
Set supported OpenCL extensions and optional core features.
Definition: AMDGPU.h:234
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:289
uint64_t getPointerAlignV(unsigned AddrSpace) const override
Definition: AMDGPU.h:102
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:48
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:147
LangAS getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const override
Get address space for OpenCL type.
Definition: AMDGPU.h:260
uint64_t getNullPointerValue(LangAS AS) const override
Get integer value for null pointer.
Definition: AMDGPU.h:314
static const char *const GCCRegNames[]
Definition: X86.cpp:42
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:126
Exposes information about the current target.
Definition: TargetInfo.h:54
unsigned getVtblPtrAddressSpace() const override
Definition: AMDGPU.h:280
bool setCPU(const std::string &Name) override
Target the specified CPU.
Definition: AMDGPU.h:225
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:110
BuiltinVaListKind getBuiltinVaListKind() const override
Returns the kind of __builtin_va_list type that should be used with this target.
Definition: AMDGPU.h:210
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:275
bool isValidCPUName(StringRef Name) const override
brief Determine whether this TargetInfo supports the given CPU name.
Definition: AMDGPU.h:218
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:106