blob: b6b9aa2f1244cbb1f2cd69f50dbc60ec41c3b3a2 [file] [log] [blame]
Erich Keaneebba5922017-07-21 22:37:03 +00001//===--- AMDGPU.cpp - Implement AMDGPU target feature support -------------===//
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 implements AMDGPU TargetInfo objects.
11//
12//===----------------------------------------------------------------------===//
13
14#include "AMDGPU.h"
15#include "clang/Basic/Builtins.h"
16#include "clang/Basic/LangOptions.h"
17#include "clang/Basic/MacroBuilder.h"
18#include "clang/Basic/TargetBuiltins.h"
19#include "clang/Frontend/CodeGenOptions.h"
20#include "llvm/ADT/StringSwitch.h"
21
22using namespace clang;
23using namespace clang::targets;
24
25namespace clang {
26namespace targets {
27
28// If you edit the description strings, make sure you update
29// getPointerWidthV().
30
31static const char *const DataLayoutStringR600 =
32 "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128"
Matt Arsenaultb130ea52018-03-27 19:26:51 +000033 "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5";
Erich Keaneebba5922017-07-21 22:37:03 +000034
Yaxun Liu1578a0a2018-03-05 17:50:10 +000035static const char *const DataLayoutStringAMDGCN =
Yaxun Liu651bd732018-02-13 18:01:21 +000036 "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32"
Erich Keaneebba5922017-07-21 22:37:03 +000037 "-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128"
Matt Arsenaultb130ea52018-03-27 19:26:51 +000038 "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5";
Erich Keaneebba5922017-07-21 22:37:03 +000039
Yaxun Liu1578a0a2018-03-05 17:50:10 +000040const LangASMap AMDGPUTargetInfo::AMDGPUDefIsGenMap = {
41 Generic, // Default
42 Global, // opencl_global
43 Local, // opencl_local
44 Constant, // opencl_constant
45 Private, // opencl_private
46 Generic, // opencl_generic
47 Global, // cuda_device
48 Constant, // cuda_constant
49 Local // cuda_shared
Erich Keaneebba5922017-07-21 22:37:03 +000050};
51
Yaxun Liu1578a0a2018-03-05 17:50:10 +000052const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = {
53 Private, // Default
54 Global, // opencl_global
55 Local, // opencl_local
56 Constant, // opencl_constant
57 Private, // opencl_private
58 Generic, // opencl_generic
59 Global, // cuda_device
60 Constant, // cuda_constant
61 Local // cuda_shared
Erich Keaneebba5922017-07-21 22:37:03 +000062};
63} // namespace targets
64} // namespace clang
65
66const Builtin::Info AMDGPUTargetInfo::BuiltinInfo[] = {
67#define BUILTIN(ID, TYPE, ATTRS) \
68 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
69#define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \
70 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, FEATURE},
71#include "clang/Basic/BuiltinsAMDGPU.def"
72};
73
74const char *const AMDGPUTargetInfo::GCCRegNames[] = {
75 "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8",
76 "v9", "v10", "v11", "v12", "v13", "v14", "v15", "v16", "v17",
77 "v18", "v19", "v20", "v21", "v22", "v23", "v24", "v25", "v26",
78 "v27", "v28", "v29", "v30", "v31", "v32", "v33", "v34", "v35",
79 "v36", "v37", "v38", "v39", "v40", "v41", "v42", "v43", "v44",
80 "v45", "v46", "v47", "v48", "v49", "v50", "v51", "v52", "v53",
81 "v54", "v55", "v56", "v57", "v58", "v59", "v60", "v61", "v62",
82 "v63", "v64", "v65", "v66", "v67", "v68", "v69", "v70", "v71",
83 "v72", "v73", "v74", "v75", "v76", "v77", "v78", "v79", "v80",
84 "v81", "v82", "v83", "v84", "v85", "v86", "v87", "v88", "v89",
85 "v90", "v91", "v92", "v93", "v94", "v95", "v96", "v97", "v98",
86 "v99", "v100", "v101", "v102", "v103", "v104", "v105", "v106", "v107",
87 "v108", "v109", "v110", "v111", "v112", "v113", "v114", "v115", "v116",
88 "v117", "v118", "v119", "v120", "v121", "v122", "v123", "v124", "v125",
89 "v126", "v127", "v128", "v129", "v130", "v131", "v132", "v133", "v134",
90 "v135", "v136", "v137", "v138", "v139", "v140", "v141", "v142", "v143",
91 "v144", "v145", "v146", "v147", "v148", "v149", "v150", "v151", "v152",
92 "v153", "v154", "v155", "v156", "v157", "v158", "v159", "v160", "v161",
93 "v162", "v163", "v164", "v165", "v166", "v167", "v168", "v169", "v170",
94 "v171", "v172", "v173", "v174", "v175", "v176", "v177", "v178", "v179",
95 "v180", "v181", "v182", "v183", "v184", "v185", "v186", "v187", "v188",
96 "v189", "v190", "v191", "v192", "v193", "v194", "v195", "v196", "v197",
97 "v198", "v199", "v200", "v201", "v202", "v203", "v204", "v205", "v206",
98 "v207", "v208", "v209", "v210", "v211", "v212", "v213", "v214", "v215",
99 "v216", "v217", "v218", "v219", "v220", "v221", "v222", "v223", "v224",
100 "v225", "v226", "v227", "v228", "v229", "v230", "v231", "v232", "v233",
101 "v234", "v235", "v236", "v237", "v238", "v239", "v240", "v241", "v242",
102 "v243", "v244", "v245", "v246", "v247", "v248", "v249", "v250", "v251",
103 "v252", "v253", "v254", "v255", "s0", "s1", "s2", "s3", "s4",
104 "s5", "s6", "s7", "s8", "s9", "s10", "s11", "s12", "s13",
105 "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
106 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
107 "s32", "s33", "s34", "s35", "s36", "s37", "s38", "s39", "s40",
108 "s41", "s42", "s43", "s44", "s45", "s46", "s47", "s48", "s49",
109 "s50", "s51", "s52", "s53", "s54", "s55", "s56", "s57", "s58",
110 "s59", "s60", "s61", "s62", "s63", "s64", "s65", "s66", "s67",
111 "s68", "s69", "s70", "s71", "s72", "s73", "s74", "s75", "s76",
112 "s77", "s78", "s79", "s80", "s81", "s82", "s83", "s84", "s85",
113 "s86", "s87", "s88", "s89", "s90", "s91", "s92", "s93", "s94",
114 "s95", "s96", "s97", "s98", "s99", "s100", "s101", "s102", "s103",
115 "s104", "s105", "s106", "s107", "s108", "s109", "s110", "s111", "s112",
116 "s113", "s114", "s115", "s116", "s117", "s118", "s119", "s120", "s121",
117 "s122", "s123", "s124", "s125", "s126", "s127", "exec", "vcc", "scc",
Matt Arsenaulte7da1362018-02-09 16:58:41 +0000118 "m0", "flat_scratch", "exec_lo", "exec_hi", "vcc_lo", "vcc_hi",
Erich Keaneebba5922017-07-21 22:37:03 +0000119 "flat_scratch_lo", "flat_scratch_hi"
120};
121
122ArrayRef<const char *> AMDGPUTargetInfo::getGCCRegNames() const {
123 return llvm::makeArrayRef(GCCRegNames);
124}
125
126bool AMDGPUTargetInfo::initFeatureMap(
127 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
128 const std::vector<std::string> &FeatureVec) const {
129
130 // XXX - What does the member GPU mean if device name string passed here?
Konstantin Zhuravlyovd6b34532018-02-27 21:48:05 +0000131 if (isAMDGCN(getTriple())) {
Erich Keaneebba5922017-07-21 22:37:03 +0000132 if (CPU.empty())
Konstantin Zhuravlyovd6b34532018-02-27 21:48:05 +0000133 CPU = "gfx600";
Erich Keaneebba5922017-07-21 22:37:03 +0000134
Konstantin Zhuravlyovcf717612018-02-15 02:37:04 +0000135 switch (parseAMDGCNName(CPU).Kind) {
Matt Arsenaultd2da3c22018-04-30 19:08:27 +0000136 case GK_GFX906:
137 Features["dl-insts"] = true;
138 LLVM_FALLTHROUGH;
139 case GK_GFX904:
Konstantin Zhuravlyovd6b34532018-02-27 21:48:05 +0000140 case GK_GFX902:
141 case GK_GFX900:
Erich Keaneebba5922017-07-21 22:37:03 +0000142 Features["gfx9-insts"] = true;
143 LLVM_FALLTHROUGH;
Konstantin Zhuravlyovd6b34532018-02-27 21:48:05 +0000144 case GK_GFX810:
145 case GK_GFX803:
146 case GK_GFX802:
147 case GK_GFX801:
Erich Keaneebba5922017-07-21 22:37:03 +0000148 Features["16-bit-insts"] = true;
149 Features["dpp"] = true;
Konstantin Zhuravlyovd6b34532018-02-27 21:48:05 +0000150 Features["s-memrealtime"] = true;
Erich Keaneebba5922017-07-21 22:37:03 +0000151 break;
Konstantin Zhuravlyovd6b34532018-02-27 21:48:05 +0000152 case GK_GFX704:
153 case GK_GFX703:
154 case GK_GFX702:
155 case GK_GFX701:
156 case GK_GFX700:
157 case GK_GFX601:
158 case GK_GFX600:
159 break;
Erich Keaneebba5922017-07-21 22:37:03 +0000160 case GK_NONE:
161 return false;
162 default:
Konstantin Zhuravlyovd6b34532018-02-27 21:48:05 +0000163 llvm_unreachable("Unhandled GPU!");
Erich Keaneebba5922017-07-21 22:37:03 +0000164 }
165 } else {
166 if (CPU.empty())
167 CPU = "r600";
168
Konstantin Zhuravlyovcf717612018-02-15 02:37:04 +0000169 switch (parseR600Name(CPU).Kind) {
Erich Keaneebba5922017-07-21 22:37:03 +0000170 case GK_CAYMAN:
Konstantin Zhuravlyovd6b34532018-02-27 21:48:05 +0000171 case GK_CYPRESS:
172 case GK_RV770:
173 case GK_RV670:
Matt Arsenaulte4f62802017-12-05 03:51:26 +0000174 // TODO: Add fp64 when implemented.
Erich Keaneebba5922017-07-21 22:37:03 +0000175 break;
Konstantin Zhuravlyovd6b34532018-02-27 21:48:05 +0000176 case GK_TURKS:
177 case GK_CAICOS:
178 case GK_BARTS:
179 case GK_SUMO:
180 case GK_REDWOOD:
181 case GK_JUNIPER:
182 case GK_CEDAR:
183 case GK_RV730:
184 case GK_RV710:
185 case GK_RS880:
186 case GK_R630:
187 case GK_R600:
188 break;
Erich Keaneebba5922017-07-21 22:37:03 +0000189 default:
Konstantin Zhuravlyovd6b34532018-02-27 21:48:05 +0000190 llvm_unreachable("Unhandled GPU!");
Erich Keaneebba5922017-07-21 22:37:03 +0000191 }
192 }
193
194 return TargetInfo::initFeatureMap(Features, Diags, CPU, FeatureVec);
195}
196
197void AMDGPUTargetInfo::adjustTargetOptions(const CodeGenOptions &CGOpts,
198 TargetOptions &TargetOpts) const {
199 bool hasFP32Denormals = false;
200 bool hasFP64Denormals = false;
Konstantin Zhuravlyovd6b34532018-02-27 21:48:05 +0000201 GPUInfo CGOptsGPU = parseGPUName(TargetOpts.CPU);
Erich Keaneebba5922017-07-21 22:37:03 +0000202 for (auto &I : TargetOpts.FeaturesAsWritten) {
203 if (I == "+fp32-denormals" || I == "-fp32-denormals")
204 hasFP32Denormals = true;
205 if (I == "+fp64-fp16-denormals" || I == "-fp64-fp16-denormals")
206 hasFP64Denormals = true;
207 }
208 if (!hasFP32Denormals)
209 TargetOpts.Features.push_back(
Konstantin Zhuravlyovd6b34532018-02-27 21:48:05 +0000210 (Twine(CGOptsGPU.HasFastFMAF && !CGOpts.FlushDenorm
Erich Keaneebba5922017-07-21 22:37:03 +0000211 ? '+'
212 : '-') +
213 Twine("fp32-denormals"))
214 .str());
215 // Always do not flush fp64 or fp16 denorms.
Konstantin Zhuravlyovd6b34532018-02-27 21:48:05 +0000216 if (!hasFP64Denormals && CGOptsGPU.HasFP64)
Erich Keaneebba5922017-07-21 22:37:03 +0000217 TargetOpts.Features.push_back("+fp64-fp16-denormals");
218}
219
Richard Smith47c9b5d2018-02-15 01:01:06 +0000220constexpr AMDGPUTargetInfo::GPUInfo AMDGPUTargetInfo::InvalidGPU;
Konstantin Zhuravlyovd6b34532018-02-27 21:48:05 +0000221constexpr AMDGPUTargetInfo::GPUInfo AMDGPUTargetInfo::R600GPUs[];
222constexpr AMDGPUTargetInfo::GPUInfo AMDGPUTargetInfo::AMDGCNGPUs[];
223
Konstantin Zhuravlyovcf717612018-02-15 02:37:04 +0000224AMDGPUTargetInfo::GPUInfo AMDGPUTargetInfo::parseR600Name(StringRef Name) {
Erich Keanee44bdb32018-02-08 23:16:55 +0000225 const auto *Result = llvm::find_if(
Konstantin Zhuravlyovd6b34532018-02-27 21:48:05 +0000226 R600GPUs, [Name](const GPUInfo &GPU) { return GPU.Name == Name; });
Erich Keanee44bdb32018-02-08 23:16:55 +0000227
Konstantin Zhuravlyovd6b34532018-02-27 21:48:05 +0000228 if (Result == std::end(R600GPUs))
Konstantin Zhuravlyovcf717612018-02-15 02:37:04 +0000229 return InvalidGPU;
230 return *Result;
Erich Keaneebba5922017-07-21 22:37:03 +0000231}
232
Konstantin Zhuravlyovcf717612018-02-15 02:37:04 +0000233AMDGPUTargetInfo::GPUInfo AMDGPUTargetInfo::parseAMDGCNName(StringRef Name) {
Konstantin Zhuravlyovd6b34532018-02-27 21:48:05 +0000234 const auto *Result = llvm::find_if(
235 AMDGCNGPUs, [Name](const GPUInfo &GPU) { return GPU.Name == Name; });
Erich Keanee44bdb32018-02-08 23:16:55 +0000236
Konstantin Zhuravlyovd6b34532018-02-27 21:48:05 +0000237 if (Result == std::end(AMDGCNGPUs))
Konstantin Zhuravlyovcf717612018-02-15 02:37:04 +0000238 return InvalidGPU;
239 return *Result;
Erich Keanee44bdb32018-02-08 23:16:55 +0000240}
241
Konstantin Zhuravlyovd6b34532018-02-27 21:48:05 +0000242AMDGPUTargetInfo::GPUInfo AMDGPUTargetInfo::parseGPUName(StringRef Name) const {
243 if (isAMDGCN(getTriple()))
244 return parseAMDGCNName(Name);
245 else
246 return parseR600Name(Name);
247}
248
Erich Keanee44bdb32018-02-08 23:16:55 +0000249void AMDGPUTargetInfo::fillValidCPUList(
250 SmallVectorImpl<StringRef> &Values) const {
Konstantin Zhuravlyovd6b34532018-02-27 21:48:05 +0000251 if (isAMDGCN(getTriple()))
252 llvm::for_each(AMDGCNGPUs, [&Values](const GPUInfo &GPU) {
Konstantin Zhuravlyovcf717612018-02-15 02:37:04 +0000253 Values.emplace_back(GPU.Name);});
Erich Keanee44bdb32018-02-08 23:16:55 +0000254 else
Konstantin Zhuravlyovd6b34532018-02-27 21:48:05 +0000255 llvm::for_each(R600GPUs, [&Values](const GPUInfo &GPU) {
Konstantin Zhuravlyovcf717612018-02-15 02:37:04 +0000256 Values.emplace_back(GPU.Name);});
Erich Keaneebba5922017-07-21 22:37:03 +0000257}
258
259void AMDGPUTargetInfo::setAddressSpaceMap(bool DefaultIsPrivate) {
Yaxun Liu1578a0a2018-03-05 17:50:10 +0000260 AddrSpaceMap = DefaultIsPrivate ? &AMDGPUDefIsPrivMap : &AMDGPUDefIsGenMap;
Erich Keaneebba5922017-07-21 22:37:03 +0000261}
262
263AMDGPUTargetInfo::AMDGPUTargetInfo(const llvm::Triple &Triple,
264 const TargetOptions &Opts)
Yaxun Liu1578a0a2018-03-05 17:50:10 +0000265 : TargetInfo(Triple),
266 GPU(isAMDGCN(Triple) ? AMDGCNGPUs[0] : parseR600Name(Opts.CPU)) {
267 resetDataLayout(isAMDGCN(getTriple()) ? DataLayoutStringAMDGCN
268 : DataLayoutStringR600);
269 assert(DataLayout->getAllocaAddrSpace() == Private);
Erich Keaneebba5922017-07-21 22:37:03 +0000270
271 setAddressSpaceMap(Triple.getOS() == llvm::Triple::Mesa3D ||
Erich Keaneebba5922017-07-21 22:37:03 +0000272 !isAMDGCN(Triple));
273 UseAddrSpaceMapMangling = true;
274
275 // Set pointer width and alignment for target address space 0.
276 PointerWidth = PointerAlign = DataLayout->getPointerSizeInBits();
277 if (getMaxPointerWidth() == 64) {
278 LongWidth = LongAlign = 64;
279 SizeType = UnsignedLong;
280 PtrDiffType = SignedLong;
281 IntPtrType = SignedLong;
282 }
Yaxun Liu39195062017-08-04 18:16:31 +0000283
284 MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
Erich Keaneebba5922017-07-21 22:37:03 +0000285}
286
287void AMDGPUTargetInfo::adjust(LangOptions &Opts) {
288 TargetInfo::adjust(Opts);
Yaxun Liu1578a0a2018-03-05 17:50:10 +0000289 // ToDo: There are still a few places using default address space as private
290 // address space in OpenCL, which needs to be cleaned up, then Opts.OpenCL
291 // can be removed from the following line.
292 setAddressSpaceMap(/*DefaultIsPrivate=*/Opts.OpenCL ||
293 !isAMDGCN(getTriple()));
Erich Keaneebba5922017-07-21 22:37:03 +0000294}
295
296ArrayRef<Builtin::Info> AMDGPUTargetInfo::getTargetBuiltins() const {
297 return llvm::makeArrayRef(BuiltinInfo, clang::AMDGPU::LastTSBuiltin -
298 Builtin::FirstTSBuiltin);
299}
300
301void AMDGPUTargetInfo::getTargetDefines(const LangOptions &Opts,
302 MacroBuilder &Builder) const {
Konstantin Zhuravlyovcf717612018-02-15 02:37:04 +0000303 Builder.defineMacro("__AMD__");
304 Builder.defineMacro("__AMDGPU__");
305
Konstantin Zhuravlyovd6b34532018-02-27 21:48:05 +0000306 if (isAMDGCN(getTriple()))
Erich Keaneebba5922017-07-21 22:37:03 +0000307 Builder.defineMacro("__AMDGCN__");
308 else
309 Builder.defineMacro("__R600__");
310
Konstantin Zhuravlyovcf717612018-02-15 02:37:04 +0000311 if (GPU.Kind != GK_NONE)
312 Builder.defineMacro(Twine("__") + Twine(GPU.CanonicalName) + Twine("__"));
313
Konstantin Zhuravlyovd6b34532018-02-27 21:48:05 +0000314 // TODO: __HAS_FMAF__, __HAS_LDEXPF__, __HAS_FP64__ are deprecated and will be
315 // removed in the near future.
316 if (GPU.HasFMAF)
Erich Keaneebba5922017-07-21 22:37:03 +0000317 Builder.defineMacro("__HAS_FMAF__");
Konstantin Zhuravlyovd6b34532018-02-27 21:48:05 +0000318 if (GPU.HasFastFMAF)
319 Builder.defineMacro("FP_FAST_FMAF");
320 if (GPU.HasLDEXPF)
Erich Keaneebba5922017-07-21 22:37:03 +0000321 Builder.defineMacro("__HAS_LDEXPF__");
Konstantin Zhuravlyovd6b34532018-02-27 21:48:05 +0000322 if (GPU.HasFP64)
Erich Keaneebba5922017-07-21 22:37:03 +0000323 Builder.defineMacro("__HAS_FP64__");
Konstantin Zhuravlyovd6b34532018-02-27 21:48:05 +0000324 if (GPU.HasFastFMA)
325 Builder.defineMacro("FP_FAST_FMA");
Erich Keaneebba5922017-07-21 22:37:03 +0000326}