1 //===--- AMDGPU.h - Declare AMDGPU target feature support -------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file declares AMDGPU TargetInfo objects.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_AMDGPU_H
15 #define LLVM_CLANG_LIB_BASIC_TARGETS_AMDGPU_H
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"
26 class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo {
28 static const Builtin::Info BuiltinInfo[];
29 static const char *const GCCRegNames[];
31 struct LLVM_LIBRARY_VISIBILITY AddrSpace {
32 unsigned Generic, Global, Local, Constant, Private;
33 AddrSpace(bool IsGenericZero_ = false) {
50 /// \brief The GPU profiles supported by the AMDGPU target.
58 GK_EVERGREEN_DOUBLE_OPS,
72 static bool hasFullSpeedFMAF32(StringRef GPUName) {
73 return parseAMDGCNName(GPUName) >= GK_GFX9;
76 static bool isAMDGCN(const llvm::Triple &TT) {
77 return TT.getArch() == llvm::Triple::amdgcn;
80 static bool isGenericZero(const llvm::Triple &TT) {
81 return TT.getEnvironmentName() == "amdgiz" ||
82 TT.getEnvironmentName() == "amdgizcl";
86 AMDGPUTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts);
88 void setAddressSpaceMap(bool DefaultIsPrivate);
90 void adjust(LangOptions &Opts) override;
92 uint64_t getPointerWidthV(unsigned AddrSpace) const override {
96 if (AddrSpace == AS.Private || AddrSpace == AS.Local) {
102 uint64_t getPointerAlignV(unsigned AddrSpace) const override {
103 return getPointerWidthV(AddrSpace);
106 uint64_t getMaxPointerWidth() const override {
107 return getTriple().getArch() == llvm::Triple::amdgcn ? 64 : 32;
110 const char *getClobbers() const override { return ""; }
112 ArrayRef<const char *> getGCCRegNames() const override;
114 ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
118 /// Accepted register names: (n, m is unsigned integer, n < m)
123 /// {S} , where S is a special register name
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",
135 bool HasLeftParen = false;
136 if (S.front() == '{') {
142 if (S.front() != 'v' && S.front() != 's') {
145 auto E = S.find('}');
146 if (!SpecialRegs.count(S.substr(0, E)))
148 S = S.drop_front(E + 1);
151 // Found {S} where S is a special register.
152 Info.setAllowsRegister();
161 Info.setAllowsRegister();
165 bool HasLeftBracket = false;
166 if (!S.empty() && S.front() == '[') {
167 HasLeftBracket = true;
170 unsigned long long N;
171 if (S.empty() || consumeUnsignedInteger(S, 10, N))
173 if (!S.empty() && S.front() == ':') {
177 unsigned long long M;
178 if (consumeUnsignedInteger(S, 10, M) || N >= M)
181 if (HasLeftBracket) {
182 if (S.empty() || S.front() != ']')
186 if (S.empty() || S.front() != '}')
191 // Found {vn}, {sn}, {v[n]}, {s[n]}, {v[n:m]}, or {s[n:m]}.
192 Info.setAllowsRegister();
198 initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
200 const std::vector<std::string> &FeatureVec) const override;
202 void adjustTargetOptions(const CodeGenOptions &CGOpts,
203 TargetOptions &TargetOpts) const override;
205 ArrayRef<Builtin::Info> getTargetBuiltins() const override;
207 void getTargetDefines(const LangOptions &Opts,
208 MacroBuilder &Builder) const override;
210 BuiltinVaListKind getBuiltinVaListKind() const override {
211 return TargetInfo::CharPtrBuiltinVaList;
214 static GPUKind parseR600Name(StringRef Name);
216 static GPUKind parseAMDGCNName(StringRef Name);
218 bool isValidCPUName(StringRef Name) const override {
219 if (getTriple().getArch() == llvm::Triple::amdgcn)
220 return GK_NONE != parseAMDGCNName(Name);
222 return GK_NONE != parseR600Name(Name);
225 bool setCPU(const std::string &Name) override {
226 if (getTriple().getArch() == llvm::Triple::amdgcn)
227 GPU = parseAMDGCNName(Name);
229 GPU = parseR600Name(Name);
231 return GPU != GK_NONE;
234 void setSupportedOpenCLOpts() override {
235 auto &Opts = getSupportedOpenCLOpts();
236 Opts.support("cl_clang_storage_class_specifiers");
237 Opts.support("cl_khr_icd");
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");
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");
260 LangAS getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const override {
263 return LangAS::opencl_constant;
267 case OCLTK_ReserveID:
268 return LangAS::opencl_global;
271 return TargetInfo::getOpenCLTypeAddrSpace(TK);
275 llvm::Optional<LangAS> getConstantAddressSpace() const override {
276 return getLangASFromTargetAS(AS.Constant);
279 /// \returns Target specific vtbl ptr address space.
280 unsigned getVtblPtrAddressSpace() const override { return AS.Constant; }
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.
286 /// \returns Otherwise return None and no conversion will be emitted in the
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) {
301 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
306 case CC_OpenCLKernel:
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
314 uint64_t getNullPointerValue(LangAS AS) const override {
315 return AS == LangAS::opencl_local ? ~0 : 0;
319 } // namespace targets
322 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_AMDGPU_H