blob: 300a92e4becf4b70bedbf343f74e890dcaf0fee2 [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 Arsenault43e92fe2016-06-24 06:30:11 +000077 bool EnableXNACK;
78 bool DebuggerInsertNops;
79 bool DebuggerReserveRegs;
80
81 // Used as options.
82 bool EnableVGPRSpilling;
Tom Stellarded0ceec2013-10-10 17:11:12 +000083 bool EnableIRStructurizer;
Matt Arsenaultd9a23ab2014-07-13 02:08:26 +000084 bool EnablePromoteAlloca;
Tom Stellard783893a2013-11-18 19:43:33 +000085 bool EnableIfCvt;
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 Arsenaultd782d052014-06-27 17:57:00 +0000221 bool IsIRStructurizerEnabled() const {
222 return EnableIRStructurizer;
223 }
224
Matt Arsenaultd9a23ab2014-07-13 02:08:26 +0000225 bool isPromoteAllocaEnabled() const {
226 return EnablePromoteAlloca;
227 }
228
Matt Arsenaultd782d052014-06-27 17:57:00 +0000229 bool isIfCvtEnabled() const {
230 return EnableIfCvt;
231 }
232
Matt Arsenault706f9302015-07-06 16:01:58 +0000233 bool unsafeDSOffsetFoldingEnabled() const {
234 return EnableUnsafeDSOffsetFolding;
235 }
236
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000237 bool dumpCode() const {
238 return DumpCode;
Matt Arsenaultd782d052014-06-27 17:57:00 +0000239 }
240
Matt Arsenault8a028bf2016-05-16 21:19:59 +0000241 /// Return the amount of LDS that can be used that will not restrict the
242 /// occupancy lower than WaveCount.
243 unsigned getMaxLocalMemSizeWithWaveCount(unsigned WaveCount) const;
244
245 /// Inverse of getMaxLocalMemWithWaveCount. Return the maximum wavecount if
246 /// the given LDS memory size is the only constraint.
247 unsigned getOccupancyWithLocalMemSize(uint32_t Bytes) const;
248
249
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000250 bool hasFP32Denormals() const {
251 return FP32Denormals;
Matt Arsenaultd782d052014-06-27 17:57:00 +0000252 }
Tom Stellard75aadc22012-12-11 21:25:42 +0000253
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000254 bool hasFP64Denormals() const {
255 return FP64Denormals;
Matt Arsenault24ee0782016-02-12 02:40:47 +0000256 }
257
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000258 bool hasFPExceptions() const {
259 return FPExceptions;
Marek Olsak4d00dd22015-03-09 15:48:09 +0000260 }
261
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000262 bool useFlatForGlobal() const {
263 return FlatForGlobal;
Tom Stellardec87f842015-05-25 16:15:54 +0000264 }
265
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000266 bool isXNACKEnabled() const {
267 return EnableXNACK;
268 }
Tom Stellardb8fd6ef2014-12-02 22:00:07 +0000269
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000270 unsigned getMaxWavesPerCU() const {
271 if (getGeneration() >= AMDGPUSubtarget::SOUTHERN_ISLANDS)
272 return 10;
273
274 // FIXME: Not sure what this is for other subtagets.
275 return 8;
276 }
277
278 /// \brief Returns the offset in bytes from the start of the input buffer
279 /// of the first explicit kernel argument.
280 unsigned getExplicitKernelArgOffset() const {
281 return isAmdHsaOS() ? 0 : 36;
282 }
283
284 unsigned getStackAlignment() const {
285 // Scratch is allocated in 256 dword per wave blocks.
286 return 4 * 256 / getWavefrontSize();
287 }
Tom Stellard347ac792015-06-26 21:15:07 +0000288
Craig Topper5656db42014-04-29 07:57:24 +0000289 bool enableMachineScheduler() const override {
Tom Stellard83f0bce2015-01-29 16:55:25 +0000290 return true;
Andrew Trick978674b2013-09-20 05:14:41 +0000291 }
292
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000293 bool enableSubRegLiveness() const override {
294 return true;
295 }
296};
297
298class R600Subtarget final : public AMDGPUSubtarget {
299private:
300 R600InstrInfo InstrInfo;
301 R600FrameLowering FrameLowering;
302 R600TargetLowering TLInfo;
303
304public:
305 R600Subtarget(const Triple &TT, StringRef CPU, StringRef FS,
306 const TargetMachine &TM);
307
308 const R600InstrInfo *getInstrInfo() const override {
309 return &InstrInfo;
310 }
311
312 const R600FrameLowering *getFrameLowering() const override {
313 return &FrameLowering;
314 }
315
316 const R600TargetLowering *getTargetLowering() const override {
317 return &TLInfo;
318 }
319
320 const R600RegisterInfo *getRegisterInfo() const override {
321 return &InstrInfo.getRegisterInfo();
322 }
323
324 bool hasCFAluBug() const {
325 return CFALUBug;
326 }
327
328 bool hasVertexCache() const {
329 return HasVertexCache;
330 }
331
332 short getTexVTXClauseSize() const {
333 return TexVTXClauseSize;
334 }
335
336 unsigned getStackEntrySize() const;
337};
338
339class SISubtarget final : public AMDGPUSubtarget {
340public:
341 enum {
342 FIXED_SGPR_COUNT_FOR_INIT_BUG = 80
343 };
344
345private:
346 SIInstrInfo InstrInfo;
347 SIFrameLowering FrameLowering;
348 SITargetLowering TLInfo;
349 std::unique_ptr<GISelAccessor> GISel;
350
351public:
352 SISubtarget(const Triple &TT, StringRef CPU, StringRef FS,
353 const TargetMachine &TM);
354
355 const SIInstrInfo *getInstrInfo() const override {
356 return &InstrInfo;
357 }
358
359 const SIFrameLowering *getFrameLowering() const override {
360 return &FrameLowering;
361 }
362
363 const SITargetLowering *getTargetLowering() const override {
364 return &TLInfo;
365 }
366
367 const CallLowering *getCallLowering() const override {
368 assert(GISel && "Access to GlobalISel APIs not set");
369 return GISel->getCallLowering();
370 }
371
372 const SIRegisterInfo *getRegisterInfo() const override {
373 return &InstrInfo.getRegisterInfo();
374 }
375
376 void setGISelAccessor(GISelAccessor &GISel) {
377 this->GISel.reset(&GISel);
378 }
379
Tom Stellard83f0bce2015-01-29 16:55:25 +0000380 void overrideSchedPolicy(MachineSchedPolicy &Policy,
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000381 MachineInstr *Begin, MachineInstr *End,
Tom Stellard83f0bce2015-01-29 16:55:25 +0000382 unsigned NumRegionInstrs) const override;
383
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000384 bool isVGPRSpillingEnabled(const Function& F) const;
385
386 unsigned getAmdKernelCodeChipID() const;
387
388 AMDGPU::IsaVersion getIsaVersion() const;
389
390 unsigned getMaxNumUserSGPRs() const {
391 return 16;
392 }
393
394 bool hasFlatAddressSpace() const {
395 return FlatAddressSpace;
396 }
397
398 bool hasSMemRealTime() const {
399 return HasSMemRealTime;
400 }
401
402 bool has16BitInsts() const {
403 return Has16BitInsts;
Matt Arsenaultd782d052014-06-27 17:57:00 +0000404 }
Tom Stellard75aadc22012-12-11 21:25:42 +0000405
Tom Stellardde008d32016-01-21 04:28:34 +0000406 bool enableSIScheduler() const {
407 return EnableSIScheduler;
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
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000418 bool loadStoreOptEnabled() const {
419 return EnableLoadStoreOpt;
Nicolai Haehnle5b504972016-01-04 23:35:53 +0000420 }
421
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000422 bool hasSGPRInitBug() const {
423 return SGPRInitBug;
Matt Arsenault41003af2015-11-30 21:16:07 +0000424 }
Tom Stellard75aadc22012-12-11 21:25:42 +0000425};
426
Matt Arsenault43e92fe2016-06-24 06:30:11 +0000427
428inline const AMDGPUInstrInfo *AMDGPUSubtarget::getInstrInfo() const {
429 if (getGeneration() >= SOUTHERN_ISLANDS)
430 return static_cast<const SISubtarget *>(this)->getInstrInfo();
431
432 return static_cast<const R600Subtarget *>(this)->getInstrInfo();
433}
434
435inline const AMDGPUFrameLowering *AMDGPUSubtarget::getFrameLowering() const {
436 if (getGeneration() >= SOUTHERN_ISLANDS)
437 return static_cast<const SISubtarget *>(this)->getFrameLowering();
438
439 return static_cast<const R600Subtarget *>(this)->getFrameLowering();
440}
441
442inline const AMDGPUTargetLowering *AMDGPUSubtarget::getTargetLowering() const {
443 if (getGeneration() >= SOUTHERN_ISLANDS)
444 return static_cast<const SISubtarget *>(this)->getTargetLowering();
445
446 return static_cast<const R600Subtarget *>(this)->getTargetLowering();
447}
448
449inline const AMDGPURegisterInfo *AMDGPUSubtarget::getRegisterInfo() const {
450 if (getGeneration() >= SOUTHERN_ISLANDS)
451 return static_cast<const SISubtarget *>(this)->getRegisterInfo();
452
453 return static_cast<const R600Subtarget *>(this)->getRegisterInfo();
454}
455
Tom Stellard75aadc22012-12-11 21:25:42 +0000456} // End namespace llvm
457
Benjamin Kramera7c40ef2014-08-13 16:26:38 +0000458#endif