blob: 3fe61aa449e0988eb01a2621e55016e550e4c10b [file] [log] [blame]
Matt Arsenault0c90e952015-11-06 18:17:45 +00001//=====-- AMDGPUSubtarget.h - Define Subtarget for AMDGPU ------*- C++ -*-====//
Tom Stellard75aadc22012-12-11 21:25:42 +00002//
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/// \file
11/// \brief AMDGPU specific subclass of TargetSubtarget.
12//
13//===----------------------------------------------------------------------===//
14
Matt Arsenault0c90e952015-11-06 18:17:45 +000015#ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUSUBTARGET_H
16#define LLVM_LIB_TARGET_AMDGPU_AMDGPUSUBTARGET_H
Matt Arsenaultf59e5382015-11-06 18:23:00 +000017
Tom Stellarda6c6e1b2013-06-07 20:37:48 +000018#include "AMDGPU.h"
Matt Arsenault43e92fe2016-06-24 06:30:11 +000019#include "R600InstrInfo.h"
20#include "R600ISelLowering.h"
21#include "R600FrameLowering.h"
22#include "SIInstrInfo.h"
23#include "SIISelLowering.h"
24#include "SIFrameLowering.h"
Tom Stellard347ac792015-06-26 21:15:07 +000025#include "Utils/AMDGPUBaseInfo.h"
Tom Stellard000c5af2016-04-14 19:09:28 +000026#include "llvm/CodeGen/GlobalISel/GISelAccessor.h"
Tom Stellard75aadc22012-12-11 21:25:42 +000027#include "llvm/Target/TargetSubtargetInfo.h"
28
29#define GET_SUBTARGETINFO_HEADER
30#include "AMDGPUGenSubtargetInfo.inc"
31
Tom Stellard75aadc22012-12-11 21:25:42 +000032namespace llvm {
33
Tom Stellarde99fb652015-01-20 19:33:04 +000034class SIMachineFunctionInfo;
Matt Arsenault43e92fe2016-06-24 06:30:11 +000035class StringRef;
Tom Stellarde99fb652015-01-20 19:33:04 +000036
Tom Stellard75aadc22012-12-11 21:25:42 +000037class AMDGPUSubtarget : public AMDGPUGenSubtargetInfo {
Tom Stellarda6c6e1b2013-06-07 20:37:48 +000038public:
39 enum Generation {
40 R600 = 0,
41 R700,
42 EVERGREEN,
43 NORTHERN_ISLANDS,
Tom Stellard6e1ee472013-10-29 16:37:28 +000044 SOUTHERN_ISLANDS,
Marek Olsak5df00d62014-12-07 12:18:57 +000045 SEA_ISLANDS,
46 VOLCANIC_ISLANDS,
Tom Stellarda6c6e1b2013-06-07 20:37:48 +000047 };
48
Marek Olsak4d00dd22015-03-09 15:48:09 +000049 enum {
Tom Stellard347ac792015-06-26 21:15:07 +000050 ISAVersion0_0_0,
51 ISAVersion7_0_0,
52 ISAVersion7_0_1,
53 ISAVersion8_0_0,
Changpeng Fangc16be002016-01-13 20:39:25 +000054 ISAVersion8_0_1,
55 ISAVersion8_0_3
Tom Stellard347ac792015-06-26 21:15:07 +000056 };
57
Matt Arsenault43e92fe2016-06-24 06:30:11 +000058protected:
59 // Basic subtarget description.
60 Triple TargetTriple;
Matt Arsenaultd782d052014-06-27 17:57:00 +000061 Generation Gen;
Matt Arsenault43e92fe2016-06-24 06:30:11 +000062 unsigned IsaVersion;
63 unsigned WavefrontSize;
64 int LocalMemorySize;
65 int LDSBankCount;
66 unsigned MaxPrivateElementSize;
67
68 // Possibly statically set by tablegen, but may want to be overridden.
Matt Arsenaultb035a572015-01-29 19:34:25 +000069 bool FastFMAF32;
Matt Arsenaulte83690c2016-01-18 21:13:50 +000070 bool HalfRate64Ops;
Matt Arsenault43e92fe2016-06-24 06:30:11 +000071
72 // Dynamially set bits that enable features.
73 bool FP32Denormals;
74 bool FP64Denormals;
75 bool FPExceptions;
Changpeng Fangb41574a2015-12-22 20:55:23 +000076 bool FlatForGlobal;
Matt Arsenault7f681ac2016-07-01 23:03:44 +000077 bool UnalignedBufferAccess;
Matt Arsenault43e92fe2016-06-24 06:30:11 +000078 bool EnableXNACK;
79 bool DebuggerInsertNops;
80 bool DebuggerReserveRegs;
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +000081 bool DebuggerEmitPrologue;
Matt Arsenault43e92fe2016-06-24 06:30:11 +000082
83 // Used as options.
84 bool EnableVGPRSpilling;
Matt Arsenaultd9a23ab2014-07-13 02:08:26 +000085 bool EnablePromoteAlloca;
Matt Arsenault41033282014-10-10 22:01:59 +000086 bool EnableLoadStoreOpt;
Matt Arsenault706f9302015-07-06 16:01:58 +000087 bool EnableUnsafeDSOffsetFolding;
Matt Arsenault43e92fe2016-06-24 06:30:11 +000088 bool EnableSIScheduler;
89 bool DumpCode;
90
91 // Subtarget statically properties set by tablegen
92 bool FP64;
Tom Stellardd7e6f132015-04-08 01:09:26 +000093 bool IsGCN;
94 bool GCN1Encoding;
95 bool GCN3Encoding;
Tom Stellardd1f0f022015-04-23 19:33:54 +000096 bool CIInsts;
Matt Arsenault43e92fe2016-06-24 06:30:11 +000097 bool SGPRInitBug;
Matt Arsenault9d82ee72016-02-27 08:53:55 +000098 bool HasSMemRealTime;
99 bool Has16BitInsts;
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000100 bool FlatAddressSpace;
101 bool R600ALUInst;
102 bool CaymanISA;
103 bool CFALUBug;
104 bool HasVertexCache;
105 short TexVTXClauseSize;
Tom Stellard75aadc22012-12-11 21:25:42 +0000106
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000107 // Dummy feature to use for assembler in tablegen.
108 bool FeatureDisable;
109
Tom Stellard75aadc22012-12-11 21:25:42 +0000110 InstrItineraryData InstrItins;
111
112public:
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000113 AMDGPUSubtarget(const Triple &TT, StringRef GPU, StringRef FS,
114 const TargetMachine &TM);
115 virtual ~AMDGPUSubtarget();
Daniel Sandersa73f1fd2015-06-10 12:11:26 +0000116 AMDGPUSubtarget &initializeSubtargetDependencies(const Triple &TT,
117 StringRef GPU, StringRef FS);
Tom Stellard75aadc22012-12-11 21:25:42 +0000118
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000119 const AMDGPUInstrInfo *getInstrInfo() const override;
120 const AMDGPUFrameLowering *getFrameLowering() const override;
121 const AMDGPUTargetLowering *getTargetLowering() const override;
122 const AMDGPURegisterInfo *getRegisterInfo() const override;
Tom Stellard000c5af2016-04-14 19:09:28 +0000123
Eric Christopherd9134482014-08-04 21:25:23 +0000124 const InstrItineraryData *getInstrItineraryData() const override {
125 return &InstrItins;
126 }
Matt Arsenaultd782d052014-06-27 17:57:00 +0000127
Craig Topperee7b0f32014-04-30 05:53:27 +0000128 void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
Tom Stellard75aadc22012-12-11 21:25:42 +0000129
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000130 bool isAmdHsaOS() const {
131 return TargetTriple.getOS() == Triple::AMDHSA;
Matt Arsenaultd782d052014-06-27 17:57:00 +0000132 }
133
134 Generation getGeneration() const {
135 return Gen;
136 }
137
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000138 unsigned getWavefrontSize() const {
139 return WavefrontSize;
140 }
141
142 int getLocalMemorySize() const {
143 return LocalMemorySize;
144 }
145
146 int getLDSBankCount() const {
147 return LDSBankCount;
148 }
149
150 unsigned getMaxPrivateElementSize() const {
151 return MaxPrivateElementSize;
152 }
153
Matt Arsenaultd782d052014-06-27 17:57:00 +0000154 bool hasHWFP64() const {
155 return FP64;
156 }
157
Matt Arsenaultb035a572015-01-29 19:34:25 +0000158 bool hasFastFMAF32() const {
159 return FastFMAF32;
160 }
161
Matt Arsenaulte83690c2016-01-18 21:13:50 +0000162 bool hasHalfRate64Ops() const {
163 return HalfRate64Ops;
164 }
165
Matt Arsenault88701812016-06-09 23:42:48 +0000166 bool hasAddr64() const {
167 return (getGeneration() < VOLCANIC_ISLANDS);
168 }
169
Matt Arsenaultfae02982014-03-17 18:58:11 +0000170 bool hasBFE() const {
171 return (getGeneration() >= EVERGREEN);
172 }
173
Matt Arsenault6e439652014-06-10 19:00:20 +0000174 bool hasBFI() const {
175 return (getGeneration() >= EVERGREEN);
176 }
177
Matt Arsenaultfae02982014-03-17 18:58:11 +0000178 bool hasBFM() const {
179 return hasBFE();
180 }
181
Matt Arsenault60425062014-06-10 19:18:28 +0000182 bool hasBCNT(unsigned Size) const {
183 if (Size == 32)
184 return (getGeneration() >= EVERGREEN);
185
Matt Arsenault3dd43fc2014-07-18 06:07:13 +0000186 if (Size == 64)
187 return (getGeneration() >= SOUTHERN_ISLANDS);
188
189 return false;
Matt Arsenault60425062014-06-10 19:18:28 +0000190 }
191
Tom Stellard50122a52014-04-07 19:45:41 +0000192 bool hasMulU24() const {
193 return (getGeneration() >= EVERGREEN);
194 }
195
196 bool hasMulI24() const {
197 return (getGeneration() >= SOUTHERN_ISLANDS ||
198 hasCaymanISA());
199 }
200
Jan Vesely6ddb8dd2014-07-15 15:51:09 +0000201 bool hasFFBL() const {
202 return (getGeneration() >= EVERGREEN);
203 }
204
205 bool hasFFBH() const {
206 return (getGeneration() >= EVERGREEN);
207 }
208
Jan Vesely808fff52015-04-30 17:15:56 +0000209 bool hasCARRY() const {
210 return (getGeneration() >= EVERGREEN);
211 }
212
213 bool hasBORROW() const {
214 return (getGeneration() >= EVERGREEN);
215 }
216
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000217 bool hasCaymanISA() const {
218 return CaymanISA;
219 }
220
Matt Arsenaultd9a23ab2014-07-13 02:08:26 +0000221 bool isPromoteAllocaEnabled() const {
222 return EnablePromoteAlloca;
223 }
224
Matt Arsenault706f9302015-07-06 16:01:58 +0000225 bool unsafeDSOffsetFoldingEnabled() const {
226 return EnableUnsafeDSOffsetFolding;
227 }
228
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000229 bool dumpCode() const {
230 return DumpCode;
Matt Arsenaultd782d052014-06-27 17:57:00 +0000231 }
232
Matt Arsenault8a028bf2016-05-16 21:19:59 +0000233 /// Return the amount of LDS that can be used that will not restrict the
234 /// occupancy lower than WaveCount.
235 unsigned getMaxLocalMemSizeWithWaveCount(unsigned WaveCount) const;
236
237 /// Inverse of getMaxLocalMemWithWaveCount. Return the maximum wavecount if
238 /// the given LDS memory size is the only constraint.
239 unsigned getOccupancyWithLocalMemSize(uint32_t Bytes) const;
240
241
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000242 bool hasFP32Denormals() const {
243 return FP32Denormals;
Matt Arsenaultd782d052014-06-27 17:57:00 +0000244 }
Tom Stellard75aadc22012-12-11 21:25:42 +0000245
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000246 bool hasFP64Denormals() const {
247 return FP64Denormals;
Matt Arsenault24ee0782016-02-12 02:40:47 +0000248 }
249
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000250 bool hasFPExceptions() const {
251 return FPExceptions;
Marek Olsak4d00dd22015-03-09 15:48:09 +0000252 }
253
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000254 bool useFlatForGlobal() const {
255 return FlatForGlobal;
Tom Stellardec87f842015-05-25 16:15:54 +0000256 }
257
Matt Arsenault7f681ac2016-07-01 23:03:44 +0000258 bool hasUnalignedBufferAccess() const {
259 return UnalignedBufferAccess;
260 }
261
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000262 bool isXNACKEnabled() const {
263 return EnableXNACK;
264 }
Tom Stellardb8fd6ef2014-12-02 22:00:07 +0000265
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000266 unsigned getMaxWavesPerCU() const {
267 if (getGeneration() >= AMDGPUSubtarget::SOUTHERN_ISLANDS)
268 return 10;
269
270 // FIXME: Not sure what this is for other subtagets.
271 return 8;
272 }
273
274 /// \brief Returns the offset in bytes from the start of the input buffer
275 /// of the first explicit kernel argument.
276 unsigned getExplicitKernelArgOffset() const {
277 return isAmdHsaOS() ? 0 : 36;
278 }
279
280 unsigned getStackAlignment() const {
281 // Scratch is allocated in 256 dword per wave blocks.
282 return 4 * 256 / getWavefrontSize();
283 }
Tom Stellard347ac792015-06-26 21:15:07 +0000284
Craig Topper5656db42014-04-29 07:57:24 +0000285 bool enableMachineScheduler() const override {
Tom Stellard83f0bce2015-01-29 16:55:25 +0000286 return true;
Andrew Trick978674b2013-09-20 05:14:41 +0000287 }
288
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000289 bool enableSubRegLiveness() const override {
290 return true;
291 }
292};
293
294class R600Subtarget final : public AMDGPUSubtarget {
295private:
296 R600InstrInfo InstrInfo;
297 R600FrameLowering FrameLowering;
298 R600TargetLowering TLInfo;
299
300public:
301 R600Subtarget(const Triple &TT, StringRef CPU, StringRef FS,
302 const TargetMachine &TM);
303
304 const R600InstrInfo *getInstrInfo() const override {
305 return &InstrInfo;
306 }
307
308 const R600FrameLowering *getFrameLowering() const override {
309 return &FrameLowering;
310 }
311
312 const R600TargetLowering *getTargetLowering() const override {
313 return &TLInfo;
314 }
315
316 const R600RegisterInfo *getRegisterInfo() const override {
317 return &InstrInfo.getRegisterInfo();
318 }
319
320 bool hasCFAluBug() const {
321 return CFALUBug;
322 }
323
324 bool hasVertexCache() const {
325 return HasVertexCache;
326 }
327
328 short getTexVTXClauseSize() const {
329 return TexVTXClauseSize;
330 }
331
332 unsigned getStackEntrySize() const;
333};
334
335class SISubtarget final : public AMDGPUSubtarget {
336public:
337 enum {
338 FIXED_SGPR_COUNT_FOR_INIT_BUG = 80
339 };
340
341private:
342 SIInstrInfo InstrInfo;
343 SIFrameLowering FrameLowering;
344 SITargetLowering TLInfo;
345 std::unique_ptr<GISelAccessor> GISel;
346
347public:
348 SISubtarget(const Triple &TT, StringRef CPU, StringRef FS,
349 const TargetMachine &TM);
350
351 const SIInstrInfo *getInstrInfo() const override {
352 return &InstrInfo;
353 }
354
355 const SIFrameLowering *getFrameLowering() const override {
356 return &FrameLowering;
357 }
358
359 const SITargetLowering *getTargetLowering() const override {
360 return &TLInfo;
361 }
362
363 const CallLowering *getCallLowering() const override {
364 assert(GISel && "Access to GlobalISel APIs not set");
365 return GISel->getCallLowering();
366 }
367
368 const SIRegisterInfo *getRegisterInfo() const override {
369 return &InstrInfo.getRegisterInfo();
370 }
371
372 void setGISelAccessor(GISelAccessor &GISel) {
373 this->GISel.reset(&GISel);
374 }
375
Tom Stellard83f0bce2015-01-29 16:55:25 +0000376 void overrideSchedPolicy(MachineSchedPolicy &Policy,
Tom Stellard83f0bce2015-01-29 16:55:25 +0000377 unsigned NumRegionInstrs) const override;
378
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000379 bool isVGPRSpillingEnabled(const Function& F) const;
380
381 unsigned getAmdKernelCodeChipID() const;
382
383 AMDGPU::IsaVersion getIsaVersion() const;
384
385 unsigned getMaxNumUserSGPRs() const {
386 return 16;
387 }
388
389 bool hasFlatAddressSpace() const {
390 return FlatAddressSpace;
391 }
392
393 bool hasSMemRealTime() const {
394 return HasSMemRealTime;
395 }
396
397 bool has16BitInsts() const {
398 return Has16BitInsts;
Matt Arsenaultd782d052014-06-27 17:57:00 +0000399 }
Tom Stellard75aadc22012-12-11 21:25:42 +0000400
Tom Stellardde008d32016-01-21 04:28:34 +0000401 bool enableSIScheduler() const {
402 return EnableSIScheduler;
403 }
404
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000405 bool debuggerSupported() const {
406 return debuggerInsertNops() && debuggerReserveRegs() &&
407 debuggerEmitPrologue();
408 }
409
Konstantin Zhuravlyov8c273ad2016-04-18 16:28:23 +0000410 bool debuggerInsertNops() const {
411 return DebuggerInsertNops;
412 }
413
Konstantin Zhuravlyov29ddd2b2016-05-24 18:37:18 +0000414 bool debuggerReserveRegs() const {
415 return DebuggerReserveRegs;
Konstantin Zhuravlyov1d99c4d2016-04-26 15:43:14 +0000416 }
417
Konstantin Zhuravlyovf2f3d142016-06-25 03:11:28 +0000418 bool debuggerEmitPrologue() const {
419 return DebuggerEmitPrologue;
420 }
421
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000422 bool loadStoreOptEnabled() const {
423 return EnableLoadStoreOpt;
Nicolai Haehnle5b504972016-01-04 23:35:53 +0000424 }
425
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000426 bool hasSGPRInitBug() const {
427 return SGPRInitBug;
Matt Arsenault41003af2015-11-30 21:16:07 +0000428 }
Tom Stellard75aadc22012-12-11 21:25:42 +0000429};
430
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000431
432inline const AMDGPUInstrInfo *AMDGPUSubtarget::getInstrInfo() const {
433 if (getGeneration() >= SOUTHERN_ISLANDS)
434 return static_cast<const SISubtarget *>(this)->getInstrInfo();
435
436 return static_cast<const R600Subtarget *>(this)->getInstrInfo();
437}
438
439inline const AMDGPUFrameLowering *AMDGPUSubtarget::getFrameLowering() const {
440 if (getGeneration() >= SOUTHERN_ISLANDS)
441 return static_cast<const SISubtarget *>(this)->getFrameLowering();
442
443 return static_cast<const R600Subtarget *>(this)->getFrameLowering();
444}
445
446inline const AMDGPUTargetLowering *AMDGPUSubtarget::getTargetLowering() const {
447 if (getGeneration() >= SOUTHERN_ISLANDS)
448 return static_cast<const SISubtarget *>(this)->getTargetLowering();
449
450 return static_cast<const R600Subtarget *>(this)->getTargetLowering();
451}
452
453inline const AMDGPURegisterInfo *AMDGPUSubtarget::getRegisterInfo() const {
454 if (getGeneration() >= SOUTHERN_ISLANDS)
455 return static_cast<const SISubtarget *>(this)->getRegisterInfo();
456
457 return static_cast<const R600Subtarget *>(this)->getRegisterInfo();
458}
459
Tom Stellard75aadc22012-12-11 21:25:42 +0000460} // End namespace llvm
461
Benjamin Kramera7c40ef2014-08-13 16:26:38 +0000462#endif