blob: ae19a0dc5481afe9ed43eb65b16ebb4326c5e80e [file] [log] [blame]
Erich Keaneebba5922017-07-21 22:37:03 +00001//===--- 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
Sven van Haastregtefb4d4c2017-08-15 09:38:18 +000017#include "clang/AST/Type.h"
Erich Keaneebba5922017-07-21 22:37:03 +000018#include "clang/Basic/TargetInfo.h"
19#include "clang/Basic/TargetOptions.h"
20#include "llvm/ADT/Triple.h"
21#include "llvm/Support/Compiler.h"
22
23namespace clang {
24namespace targets {
25
26class 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
85public:
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
114 ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
115 return None;
116 }
117
118 bool validateAsmConstraint(const char *&Name,
119 TargetInfo::ConstraintInfo &Info) const override {
120 switch (*Name) {
121 default:
122 break;
123 case 'v': // vgpr
124 case 's': // sgpr
125 Info.setAllowsRegister();
126 return true;
127 }
128 return false;
129 }
130
131 bool
132 initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
133 StringRef CPU,
134 const std::vector<std::string> &FeatureVec) const override;
135
136 void adjustTargetOptions(const CodeGenOptions &CGOpts,
137 TargetOptions &TargetOpts) const override;
138
139 ArrayRef<Builtin::Info> getTargetBuiltins() const override;
140
141 void getTargetDefines(const LangOptions &Opts,
142 MacroBuilder &Builder) const override;
143
144 BuiltinVaListKind getBuiltinVaListKind() const override {
145 return TargetInfo::CharPtrBuiltinVaList;
146 }
147
148 static GPUKind parseR600Name(StringRef Name);
149
150 static GPUKind parseAMDGCNName(StringRef Name);
151
152 bool isValidCPUName(StringRef Name) const override {
153 if (getTriple().getArch() == llvm::Triple::amdgcn)
154 return GK_NONE != parseAMDGCNName(Name);
155 else
156 return GK_NONE != parseR600Name(Name);
157 }
158
159 bool setCPU(const std::string &Name) override {
160 if (getTriple().getArch() == llvm::Triple::amdgcn)
161 GPU = parseAMDGCNName(Name);
162 else
163 GPU = parseR600Name(Name);
164
165 return GPU != GK_NONE;
166 }
167
168 void setSupportedOpenCLOpts() override {
169 auto &Opts = getSupportedOpenCLOpts();
170 Opts.support("cl_clang_storage_class_specifiers");
171 Opts.support("cl_khr_icd");
172
173 if (hasFP64)
174 Opts.support("cl_khr_fp64");
175 if (GPU >= GK_EVERGREEN) {
176 Opts.support("cl_khr_byte_addressable_store");
177 Opts.support("cl_khr_global_int32_base_atomics");
178 Opts.support("cl_khr_global_int32_extended_atomics");
179 Opts.support("cl_khr_local_int32_base_atomics");
180 Opts.support("cl_khr_local_int32_extended_atomics");
181 }
182 if (GPU >= GK_GFX6) {
183 Opts.support("cl_khr_fp16");
184 Opts.support("cl_khr_int64_base_atomics");
185 Opts.support("cl_khr_int64_extended_atomics");
186 Opts.support("cl_khr_mipmap_image");
187 Opts.support("cl_khr_subgroups");
188 Opts.support("cl_khr_3d_image_writes");
189 Opts.support("cl_amd_media_ops");
190 Opts.support("cl_amd_media_ops2");
191 }
192 }
193
Sven van Haastregtefb4d4c2017-08-15 09:38:18 +0000194 LangAS::ID getOpenCLTypeAddrSpace(const Type *T) const override {
195 auto BT = dyn_cast<BuiltinType>(T);
196
197 if (!BT)
198 return TargetInfo::getOpenCLTypeAddrSpace(T);
199
200 switch (BT->getKind()) {
201#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
202 case BuiltinType::Id: \
Erich Keaneebba5922017-07-21 22:37:03 +0000203 return LangAS::opencl_constant;
Sven van Haastregtefb4d4c2017-08-15 09:38:18 +0000204#include "clang/Basic/OpenCLImageTypes.def"
Yaxun Liue3779352017-09-13 18:50:42 +0000205 case BuiltinType::OCLClkEvent:
206 case BuiltinType::OCLQueue:
207 case BuiltinType::OCLReserveID:
208 return LangAS::opencl_global;
Sven van Haastregtefb4d4c2017-08-15 09:38:18 +0000209
210 default:
211 return TargetInfo::getOpenCLTypeAddrSpace(T);
212 }
Erich Keaneebba5922017-07-21 22:37:03 +0000213 }
214
215 llvm::Optional<unsigned> getConstantAddressSpace() const override {
216 return LangAS::FirstTargetAddressSpace + AS.Constant;
217 }
218
219 /// \returns Target specific vtbl ptr address space.
220 unsigned getVtblPtrAddressSpace() const override { return AS.Constant; }
221
222 /// \returns If a target requires an address within a target specific address
223 /// space \p AddressSpace to be converted in order to be used, then return the
224 /// corresponding target specific DWARF address space.
225 ///
226 /// \returns Otherwise return None and no conversion will be emitted in the
227 /// DWARF.
228 Optional<unsigned>
229 getDWARFAddressSpace(unsigned AddressSpace) const override {
230 const unsigned DWARF_Private = 1;
231 const unsigned DWARF_Local = 2;
232 if (AddressSpace == AS.Private) {
233 return DWARF_Private;
234 } else if (AddressSpace == AS.Local) {
235 return DWARF_Local;
236 } else {
237 return None;
238 }
239 }
240
241 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
242 switch (CC) {
243 default:
244 return CCCR_Warning;
245 case CC_C:
246 case CC_OpenCLKernel:
247 return CCCR_OK;
248 }
249 }
250
251 // In amdgcn target the null pointer in global, constant, and generic
252 // address space has value 0 but in private and local address space has
253 // value ~0.
254 uint64_t getNullPointerValue(unsigned AS) const override {
255 return AS == LangAS::opencl_local ? ~0 : 0;
256 }
257};
258
259} // namespace targets
260} // namespace clang
261
262#endif // LLVM_CLANG_LIB_BASIC_TARGETS_AMDGPU_H