1//=====-- GCNSubtarget.h - Define GCN Subtarget for AMDGPU ------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//==-----------------------------------------------------------------------===//
8//
9/// \file
10/// AMD GCN specific subclass of TargetSubtarget.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_LIB_TARGET_AMDGPU_GCNSUBTARGET_H
15#define LLVM_LIB_TARGET_AMDGPU_GCNSUBTARGET_H
16
17#include "AMDGPUCallLowering.h"
18#include "AMDGPURegisterBankInfo.h"
19#include "AMDGPUSubtarget.h"
20#include "SIFrameLowering.h"
21#include "SIISelLowering.h"
22#include "SIInstrInfo.h"
23#include "Utils/AMDGPUBaseInfo.h"
24#include "llvm/Support/AMDHSAKernelDescriptor.h"
25#include "llvm/Support/ErrorHandling.h"
26#include <optional>
27
28#define GET_SUBTARGETINFO_HEADER
29#include "AMDGPUGenSubtargetInfo.inc"
30
31namespace llvm {
32
33class GCNTargetMachine;
34
35/// Module flag names controlling out-of-bounds buffer access semantics.
36/// Each flag is an i32 with Module::Max merge behaviour and tri-state values:
37/// 0 = any (absent/default - backend currently treats as strict)
38/// 1 = relaxed
39/// 2 = strict
40namespace AMDGPUOOBMode {
41inline constexpr StringLiteral BufferFlag("amdgpu.buffer.oob.mode");
42inline constexpr StringLiteral TBufferFlag("amdgpu.tbuffer.oob.mode");
43} // namespace AMDGPUOOBMode
44
45class GCNSubtarget final : public AMDGPUGenSubtargetInfo,
46 public AMDGPUSubtarget {
47public:
48 using AMDGPUSubtarget::getMaxWavesPerEU;
49
50 // Following 2 enums are documented at:
51 // - https://llvm.org/docs/AMDGPUUsage.html#trap-handler-abi
52 enum class TrapHandlerAbi {
53 NONE = 0x00,
54 AMDHSA = 0x01,
55 };
56
57 enum class TrapID {
58 LLVMAMDHSATrap = 0x02,
59 LLVMAMDHSADebugTrap = 0x03,
60 };
61
62private:
63 /// SelectionDAGISel related APIs.
64 std::unique_ptr<const SelectionDAGTargetInfo> TSInfo;
65
66 /// GlobalISel related APIs.
67 std::unique_ptr<AMDGPUCallLowering> CallLoweringInfo;
68 std::unique_ptr<InlineAsmLowering> InlineAsmLoweringInfo;
69 std::unique_ptr<InstructionSelector> InstSelector;
70 std::unique_ptr<LegalizerInfo> Legalizer;
71 std::unique_ptr<AMDGPURegisterBankInfo> RegBankInfo;
72
73protected:
74 // Basic subtarget description.
75 AMDGPU::TargetID TargetID;
76 unsigned Gen = INVALID;
77 InstrItineraryData InstrItins;
78 int LDSBankCount = 0;
79 unsigned MaxPrivateElementSize = 0;
80
81 // Instruction cache line size in bytes; set from TableGen subtarget features.
82 unsigned InstCacheLineSize = 0;
83
84 // Data (VMEM) cache line size in bytes; set from TableGen subtarget features.
85 unsigned DataCacheLineSize = 0;
86
87 /// The width, in bits, of the num_records field of a buffer resource (V#),
88 /// set from tablegen subtarget features, 0 is unknown.
89 unsigned BufferResourceNumRecordsWidth = 0;
90
91 // Dynamically set bits that enable features.
92 bool ScalarizeGlobal = false;
93 const bool BufferOOBRelaxed;
94 const bool TBufferOOBRelaxed;
95
96 /// The maximum number of instructions that may be placed within an S_CLAUSE,
97 /// which is one greater than the maximum argument to S_CLAUSE. A value of 0
98 /// indicates a lack of S_CLAUSE support.
99 unsigned MaxHardClauseLength = 0;
100
101#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
102 bool ATTRIBUTE = DEFAULT;
103#include "AMDGPUGenSubtargetInfo.inc"
104
105private:
106 SIInstrInfo InstrInfo;
107 SITargetLowering TLInfo;
108 SIFrameLowering FrameLowering;
109
110 /// Get the register that represents the actual dependency between the
111 /// definition and the use. The definition might only affect a subregister
112 /// that is not actually used. Works for both virtual and physical registers.
113 /// Note: Currently supports VOP3P instructions (without WMMA an SWMMAC).
114 /// Returns the definition register if there is a real dependency and no
115 /// better match is found.
116 Register getRealSchedDependency(const MachineInstr &DefI, int DefOpIdx,
117 const MachineInstr &UseI, int UseOpIdx) const;
118
119public:
120 GCNSubtarget(
121 const Triple &TT, StringRef GPU, StringRef FS, const GCNTargetMachine &TM,
122 bool BufferOOBRelaxed = false, bool TBufferOOBRelaxed = false,
123 AMDGPU::TargetIDSetting XnackSetting = AMDGPU::TargetIDSetting::Any,
124 AMDGPU::TargetIDSetting SramEccSetting = AMDGPU::TargetIDSetting::Any);
125 ~GCNSubtarget() override;
126
127 GCNSubtarget &initializeSubtargetDependencies(const Triple &TT, StringRef GPU,
128 StringRef FS);
129
130 /// Diagnose inconsistent subtarget features before attempting to codegen
131 /// function \p F.
132 void checkSubtargetFeatures(const Function &F) const;
133
134 const SIInstrInfo *getInstrInfo() const override { return &InstrInfo; }
135
136 const SIFrameLowering *getFrameLowering() const override {
137 return &FrameLowering;
138 }
139
140 const SITargetLowering *getTargetLowering() const override { return &TLInfo; }
141
142 const SIRegisterInfo *getRegisterInfo() const override {
143 return &InstrInfo.getRegisterInfo();
144 }
145
146 const SelectionDAGTargetInfo *getSelectionDAGInfo() const override;
147
148 const CallLowering *getCallLowering() const override {
149 return CallLoweringInfo.get();
150 }
151
152 const InlineAsmLowering *getInlineAsmLowering() const override {
153 return InlineAsmLoweringInfo.get();
154 }
155
156 InstructionSelector *getInstructionSelector() const override {
157 return InstSelector.get();
158 }
159
160 const LegalizerInfo *getLegalizerInfo() const override {
161 return Legalizer.get();
162 }
163
164 const AMDGPURegisterBankInfo *getRegBankInfo() const override {
165 return RegBankInfo.get();
166 }
167
168 const AMDGPU::TargetID &getTargetID() const { return TargetID; }
169
170 const InstrItineraryData *getInstrItineraryData() const override {
171 return &InstrItins;
172 }
173
174 void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
175
176 Generation getGeneration() const { return (Generation)Gen; }
177
178 bool isGFX11Plus() const { return getGeneration() >= GFX11; }
179
180#define GET_SUBTARGETINFO_MACRO(ATTRIBUTE, DEFAULT, GETTER) \
181 bool GETTER() const override { return ATTRIBUTE; }
182#include "AMDGPUGenSubtargetInfo.inc"
183
184 unsigned getMaxWaveScratchSize() const {
185 // See COMPUTE_TMPRING_SIZE.WAVESIZE.
186 if (getGeneration() >= GFX12) {
187 // 18-bit field in units of 64-dword.
188 return (64 * 4) * ((1 << 18) - 1);
189 }
190 if (getGeneration() == GFX11) {
191 // 15-bit field in units of 64-dword.
192 return (64 * 4) * ((1 << 15) - 1);
193 }
194 // 13-bit field in units of 256-dword.
195 return (256 * 4) * ((1 << 13) - 1);
196 }
197
198 /// Return the number of high bits known to be zero for a frame index.
199 unsigned getKnownHighZeroBitsForFrameIndex() const {
200 return llvm::countl_zero(Val: getMaxWaveScratchSize()) + getWavefrontSizeLog2();
201 }
202
203 int getLDSBankCount() const { return LDSBankCount; }
204
205 /// Instruction cache line size in bytes (64 for pre-GFX11, 128 for GFX11+).
206 unsigned getInstCacheLineSize() const { return InstCacheLineSize; }
207
208 /// Data (VMEM) cache line size in bytes (128 for gfx12), has no use before
209 /// GFX12.
210 unsigned getDataCacheLineSize() const { return DataCacheLineSize; }
211
212 unsigned getMaxPrivateElementSize(bool ForBufferRSrc = false) const {
213 return (ForBufferRSrc || !hasFlatScratchEnabled()) ? MaxPrivateElementSize
214 : 16;
215 }
216
217 unsigned getConstantBusLimit(unsigned Opcode) const;
218
219 /// Returns if the result of this instruction with a 16-bit result returned in
220 /// a 32-bit register implicitly zeroes the high 16-bits, rather than preserve
221 /// the original value.
222 bool zeroesHigh16BitsOfDest(unsigned Opcode) const;
223
224 bool hasHWFP64() const { return HasFP64; }
225
226 bool hasAddr64() const {
227 return (getGeneration() < AMDGPUSubtarget::VOLCANIC_ISLANDS);
228 }
229
230 bool hasFlat() const {
231 return (getGeneration() > AMDGPUSubtarget::SOUTHERN_ISLANDS);
232 }
233
234 // Return true if the target only has the reverse operand versions of VALU
235 // shift instructions (e.g. v_lshrrev_b32, and no v_lshr_b32).
236 bool hasOnlyRevVALUShifts() const {
237 return getGeneration() >= VOLCANIC_ISLANDS;
238 }
239
240 bool hasFractBug() const { return getGeneration() == SOUTHERN_ISLANDS; }
241
242 bool hasMed3_16() const { return getGeneration() >= AMDGPUSubtarget::GFX9; }
243
244 bool hasMin3Max3_16() const {
245 return getGeneration() >= AMDGPUSubtarget::GFX9;
246 }
247
248 bool hasSwap() const { return HasGFX9Insts; }
249
250 bool hasScalarPackInsts() const { return HasGFX9Insts; }
251
252 bool hasScalarMulHiInsts() const { return HasGFX9Insts; }
253
254 bool hasScalarSubwordLoads() const { return getGeneration() >= GFX12; }
255
256 bool hasAsyncMark() const { return hasVMemToLDSLoad() || HasAsynccnt; }
257
258 TrapHandlerAbi getTrapHandlerAbi() const {
259 return isAmdHsaOS() ? TrapHandlerAbi::AMDHSA : TrapHandlerAbi::NONE;
260 }
261
262 bool supportsGetDoorbellID() const {
263 // The S_GETREG DOORBELL_ID is supported by all GFX9 onward targets.
264 return getGeneration() >= GFX9;
265 }
266
267 /// True if the offset field of DS instructions works as expected. On SI, the
268 /// offset uses a 16-bit adder and does not always wrap properly.
269 bool hasUsableDSOffset() const { return getGeneration() >= SEA_ISLANDS; }
270
271 bool unsafeDSOffsetFoldingEnabled() const {
272 return EnableUnsafeDSOffsetFolding;
273 }
274
275 /// Condition output from div_scale is usable.
276 bool hasUsableDivScaleConditionOutput() const {
277 return getGeneration() != SOUTHERN_ISLANDS;
278 }
279
280 /// Extra wait hazard is needed in some cases before
281 /// s_cbranch_vccnz/s_cbranch_vccz.
282 bool hasReadVCCZBug() const { return getGeneration() <= SEA_ISLANDS; }
283
284 /// Writes to VCC_LO/VCC_HI update the VCCZ flag.
285 bool partialVCCWritesUpdateVCCZ() const { return getGeneration() >= GFX10; }
286
287 /// A read of an SGPR by SMRD instruction requires 4 wait states when the SGPR
288 /// was written by a VALU instruction.
289 bool hasSMRDReadVALUDefHazard() const {
290 return getGeneration() == SOUTHERN_ISLANDS;
291 }
292
293 /// A read of an SGPR by a VMEM instruction requires 5 wait states when the
294 /// SGPR was written by a VALU Instruction.
295 bool hasVMEMReadSGPRVALUDefHazard() const {
296 return getGeneration() >= VOLCANIC_ISLANDS;
297 }
298
299 bool hasRFEHazards() const { return getGeneration() >= VOLCANIC_ISLANDS; }
300
301 /// Number of hazard wait states for s_setreg_b32/s_setreg_imm32_b32.
302 unsigned getSetRegWaitStates() const {
303 return getGeneration() <= SEA_ISLANDS ? 1 : 2;
304 }
305
306 /// Return the amount of LDS that can be used that will not restrict the
307 /// occupancy lower than WaveCount.
308 unsigned getMaxLocalMemSizeWithWaveCount(unsigned WaveCount,
309 const Function &) const;
310
311 bool supportsMinMaxDenormModes() const {
312 return getGeneration() >= AMDGPUSubtarget::GFX9;
313 }
314
315 /// \returns If target supports S_DENORM_MODE.
316 bool hasDenormModeInst() const {
317 return getGeneration() >= AMDGPUSubtarget::GFX10;
318 }
319
320 /// \returns If target supports ds_read/write_b128 and user enables generation
321 /// of ds_read/write_b128.
322 bool useDS128() const { return HasCIInsts && EnableDS128; }
323
324 /// \return If target supports ds_read/write_b96/128.
325 bool hasDS96AndDS128() const { return HasCIInsts; }
326
327 /// Have v_trunc_f64, v_ceil_f64, v_rndne_f64
328 bool haveRoundOpsF64() const { return HasCIInsts; }
329
330 /// \returns If MUBUF instructions always perform range checking, even for
331 /// buffer resources used for private memory access.
332 bool privateMemoryResourceIsRangeChecked() const {
333 return getGeneration() < AMDGPUSubtarget::GFX9;
334 }
335
336 /// \returns If target requires PRT Struct NULL support (zero result registers
337 /// for sparse texture support).
338 bool usePRTStrictNull() const { return EnablePRTStrictNull; }
339
340 bool hasUnalignedBufferAccessEnabled() const {
341 return HasUnalignedBufferAccess && HasUnalignedAccessMode;
342 }
343
344 bool hasUnalignedDSAccessEnabled() const {
345 return HasUnalignedDSAccess && HasUnalignedAccessMode;
346 }
347
348 bool hasUnalignedScratchAccessEnabled() const {
349 return HasUnalignedScratchAccess && HasUnalignedAccessMode;
350 }
351
352 bool isXNACKEnabled() const { return TargetID.isXnackOnOrAny(); }
353
354 bool hasRelaxedBufferOOBMode() const { return BufferOOBRelaxed; }
355 bool hasRelaxedTBufferOOBMode() const { return TBufferOOBRelaxed; }
356
357 /// Return the width, in bits, of the num_records field of a buffer resource
358 /// (V#) on this subtarget, or std::nullopt if not yet known.
359 std::optional<unsigned> getBufferResourceNumRecordsWidth() const {
360 if (BufferResourceNumRecordsWidth == 0)
361 return std::nullopt;
362 return BufferResourceNumRecordsWidth;
363 }
364
365 bool isCuModeEnabled() const { return EnableCuMode; }
366
367 /// \returns Whether a work-group runs on all of the block's SIMDs.
368 bool isFullSIMDMode() const {
369 return (HasGFX1250Insts && getGeneration() < GFX13) || !EnableCuMode;
370 }
371
372 bool isPreciseMemoryEnabled() const { return EnablePreciseMemory; }
373
374 bool hasFlatScrRegister() const { return hasFlatAddressSpace(); }
375
376 // Check if target supports ST addressing mode with FLAT scratch instructions.
377 // The ST addressing mode means no registers are used, either VGPR or SGPR,
378 // but only immediate offset is swizzled and added to the FLAT scratch base.
379 bool hasFlatScratchSTMode() const {
380 return hasFlatScratchInsts() && (hasGFX10_3Insts() || hasGFX940Insts());
381 }
382
383 bool hasFlatScratchSVSMode() const { return HasGFX940Insts || HasGFX11Insts; }
384
385 bool hasFlatScratchEnabled() const {
386 return hasArchitectedFlatScratch() ||
387 (EnableFlatScratch && hasFlatScratchInsts());
388 }
389
390 bool hasGlobalAddTidInsts() const { return HasGFX10_BEncoding; }
391
392 bool hasAtomicCSub() const { return HasGFX10_BEncoding; }
393
394 bool hasExportInsts() const {
395 return !hasGFX940Insts() && !hasGFX1250Insts();
396 }
397
398 bool hasVINTERPEncoding() const {
399 return HasGFX11Insts && !hasGFX1250Insts();
400 }
401
402 bool hasMultiDwordFlatScratchAddressing() const {
403 return getGeneration() >= GFX9;
404 }
405
406 bool hasFlatLgkmVMemCountInOrder() const { return getGeneration() > GFX9; }
407
408 bool hasD16LoadStore() const { return getGeneration() >= GFX9; }
409
410 bool d16PreservesUnusedBits() const {
411 return hasD16LoadStore() && !TargetID.isSramEccOnOrAny();
412 }
413
414 bool hasD16Images() const { return getGeneration() >= VOLCANIC_ISLANDS; }
415
416 /// Return if most LDS instructions have an m0 use that require m0 to be
417 /// initialized.
418 bool ldsRequiresM0Init() const { return getGeneration() < GFX9; }
419
420 // True if the hardware rewinds and replays GWS operations if a wave is
421 // preempted.
422 //
423 // If this is false, a GWS operation requires testing if a nack set the
424 // MEM_VIOL bit, and repeating if so.
425 bool hasGWSAutoReplay() const { return getGeneration() >= GFX9; }
426
427 /// \returns if target has ds_gws_sema_release_all instruction.
428 bool hasGWSSemaReleaseAll() const { return HasCIInsts; }
429
430 bool hasScalarAddSub64() const { return getGeneration() >= GFX12; }
431
432 bool hasScalarSMulU64() const { return getGeneration() >= GFX12; }
433
434 // Covers VS/PS/CS graphics shaders
435 bool isMesaGfxShader(const Function &F) const {
436 return isMesa3DOS() && AMDGPU::isShader(CC: F.getCallingConv());
437 }
438
439 bool hasMad64_32() const { return getGeneration() >= SEA_ISLANDS; }
440
441 bool hasAtomicFaddInsts() const {
442 return HasAtomicFaddRtnInsts || HasAtomicFaddNoRtnInsts;
443 }
444
445 bool vmemWriteNeedsExpWaitcnt() const {
446 return getGeneration() < SEA_ISLANDS;
447 }
448
449 bool hasInstPrefetch() const {
450 return getGeneration() == GFX10 || getGeneration() == GFX11;
451 }
452
453 bool hasPrefetch() const { return HasGFX12Insts; }
454
455 bool hasInstPrefSize() const { return isGFX11Plus(); }
456
457 void getInstPrefSizeArgs(uint32_t &Mask, uint32_t &Shift, uint32_t &Width,
458 uint32_t &CacheLineSize) const {
459 assert(isGFX11Plus());
460 CacheLineSize = getInstCacheLineSize();
461 if (getGeneration() == GFX11) {
462 Mask = amdhsa::COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE;
463 Shift = amdhsa::COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE_SHIFT;
464 Width = amdhsa::COMPUTE_PGM_RSRC3_GFX11_INST_PREF_SIZE_WIDTH;
465 } else {
466 Mask = amdhsa::COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE;
467 Shift = amdhsa::COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE_SHIFT;
468 Width = amdhsa::COMPUTE_PGM_RSRC3_GFX12_PLUS_INST_PREF_SIZE_WIDTH;
469 }
470 }
471
472 // Has s_cmpk_* instructions.
473 bool hasSCmpK() const { return getGeneration() < GFX12; }
474
475 // Scratch is allocated in 256 dword per wave blocks for the entire
476 // wavefront. When viewed from the perspective of an arbitrary workitem, this
477 // is 4-byte aligned.
478 //
479 // Only 4-byte alignment is really needed to access anything. Transformations
480 // on the pointer value itself may rely on the alignment / known low bits of
481 // the pointer. Set this to something above the minimum to avoid needing
482 // dynamic realignment in common cases.
483 Align getStackAlignment() const { return Align(16); }
484
485 bool enableMachineScheduler() const override { return true; }
486
487 bool useAA() const override;
488
489 bool enableSubRegLiveness() const override { return true; }
490
491 void setScalarizeGlobalBehavior(bool b) { ScalarizeGlobal = b; }
492 bool getScalarizeGlobalBehavior() const { return ScalarizeGlobal; }
493
494 // XXX - Why is this here if it isn't in the default pass set?
495 bool enableEarlyIfConversion() const override { return true; }
496
497 void overrideSchedPolicy(MachineSchedPolicy &Policy,
498 const SchedRegion &Region) const override;
499
500 void overridePostRASchedPolicy(MachineSchedPolicy &Policy,
501 const SchedRegion &Region) const override;
502
503 void overridePipelinerPolicy(MachinePipelinerPolicy &Policy) const override;
504
505 void mirFileLoaded(MachineFunction &MF) const override;
506
507 unsigned getMaxNumUserSGPRs() const {
508 return AMDGPU::getMaxNumUserSGPRs(STI: *this);
509 }
510
511 bool useVGPRIndexMode() const;
512
513 bool hasScalarCompareEq64() const {
514 return getGeneration() >= VOLCANIC_ISLANDS;
515 }
516
517 bool hasLDSFPAtomicAddF32() const { return HasGFX8Insts; }
518 bool hasLDSFPAtomicAddF64() const {
519 return HasGFX90AInsts || HasGFX1250Insts;
520 }
521
522 /// \returns true if the subtarget has the v_permlane64_b32 instruction.
523 bool hasPermLane64() const { return getGeneration() >= GFX11; }
524
525 /// \returns true if the subtarget supports the ds_swizzle rotate and FFT
526 /// swizzle modes (GFX9+).
527 bool hasDsSwizzleRotateMode() const { return getGeneration() >= GFX9; }
528
529 bool hasDPPRowShare() const {
530 return HasDPP && (HasGFX90AInsts || getGeneration() >= GFX10);
531 }
532
533 // Has V_PK_MOV_B32 opcode
534 bool hasPkMovB32() const { return HasGFX90AInsts; }
535
536 bool hasBufferTFEFormatD16() const { return !HasGFX90AInsts; }
537
538 bool hasFmaakFmamkF32Insts() const {
539 return getGeneration() >= GFX10 || hasGFX940Insts();
540 }
541
542 bool hasFmaakFmamkF64Insts() const { return hasGFX1250Insts(); }
543
544 bool hasNonNSAEncoding() const { return getGeneration() < GFX12; }
545
546 unsigned getNSAMaxSize(bool HasSampler = false) const {
547 return AMDGPU::getNSAMaxSize(STI: *this, HasSampler);
548 }
549
550 bool hasMadF16() const;
551
552 // Scalar and global loads support scale_offset bit.
553 bool hasScaleOffset() const { return HasGFX1250Insts; }
554
555 // FLAT GLOBAL VOffset is signed
556 bool hasSignedGVSOffset() const { return HasGFX1250Insts; }
557
558 bool loadStoreOptEnabled() const { return EnableLoadStoreOpt; }
559
560 bool hasUserSGPRInit16BugInWave32() const {
561 return HasUserSGPRInit16Bug && isWave32();
562 }
563
564 bool has12DWordStoreHazard() const {
565 return getGeneration() != AMDGPUSubtarget::SOUTHERN_ISLANDS;
566 }
567
568 // \returns true if the subtarget supports DWORDX3 load/store instructions.
569 bool hasDwordx3LoadStores() const { return HasCIInsts; }
570
571 bool hasReadM0MovRelInterpHazard() const {
572 return getGeneration() == AMDGPUSubtarget::GFX9;
573 }
574
575 bool hasReadM0SendMsgHazard() const {
576 return getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS &&
577 getGeneration() <= AMDGPUSubtarget::GFX9;
578 }
579
580 bool hasReadM0LdsDmaHazard() const {
581 return getGeneration() == AMDGPUSubtarget::GFX9;
582 }
583
584 bool hasReadM0LdsDirectHazard() const {
585 return getGeneration() == AMDGPUSubtarget::GFX9;
586 }
587
588 bool hasLDSMisalignedBugInWGPMode() const {
589 return HasLDSMisalignedBug && !EnableCuMode;
590 }
591
592 // Shift amount of a 64 bit shift cannot be a highest allocated register
593 // if also at the end of the allocation block.
594 bool hasShift64HighRegBug() const { return HasGFX90AInsts; }
595
596 // v_dot2c_f32_f16 unconditionally flushes f16 subnormal inputs to zero
597 // regardless of the MODE register, unlike v_fma_mix_f32 which respects it.
598 bool dot2UnconditionalFlush() const {
599 return HasGFX90AInsts && !HasGFX940Insts;
600 }
601
602 // Has one cycle hazard on transcendental instruction feeding a
603 // non transcendental VALU.
604 bool hasTransForwardingHazard() const { return HasGFX940Insts; }
605
606 // Has one cycle hazard on a VALU instruction partially writing dst with
607 // a shift of result bits feeding another VALU instruction.
608 bool hasDstSelForwardingHazard() const { return HasGFX940Insts; }
609
610 // Cannot use op_sel with v_dot instructions.
611 bool hasDOTOpSelHazard() const { return HasGFX940Insts || HasGFX11Insts; }
612
613 // Does not have HW interlocs for VALU writing and then reading SGPRs.
614 bool hasVDecCoExecHazard() const { return HasGFX940Insts; }
615
616 bool hasHardClauses() const { return MaxHardClauseLength > 0; }
617
618 bool hasFPAtomicToDenormModeHazard() const {
619 return getGeneration() == GFX10;
620 }
621
622 bool hasVOP3DPP() const { return getGeneration() >= GFX11; }
623
624 bool hasLdsDirect() const { return getGeneration() >= GFX11; }
625
626 bool hasLdsWaitVMSRC() const { return getGeneration() >= GFX12; }
627
628 bool hasVALUPartialForwardingHazard() const {
629 return getGeneration() == GFX11;
630 }
631
632 /// GFX11 VOPD dest-buffer forwarding can drop the interlock when SRC0 or
633 /// SRC1 X/Y are distinct VGPRs with the same parity.
634 bool hasGFX11VOPDInterlockHazard() const { return getGeneration() == GFX11; }
635
636 bool hasCvtScaleForwardingHazard() const { return HasGFX950Insts; }
637
638 // All GFX9 targets experience a fetch delay when an instruction at the start
639 // of a loop header is split by a 32-byte fetch window boundary, but GFX950
640 // is uniquely sensitive to this: the delay triggers further performance
641 // degradation beyond the fetch latency itself.
642 bool hasLoopHeadInstSplitSensitivity() const { return HasGFX950Insts; }
643
644 bool requiresCodeObjectV6() const { return RequiresCOV6; }
645
646 bool useVGPRBlockOpsForCSR() const { return UseBlockVGPROpsForCSR; }
647
648 bool hasVALUMaskWriteHazard() const { return getGeneration() == GFX11; }
649
650 bool hasVALUReadSGPRHazard() const {
651 return HasGFX12Insts && !HasGFX1250Insts;
652 }
653
654 bool setRegModeNeedsVNOPs() const {
655 return HasGFX1250Insts && getGeneration() == GFX12;
656 }
657
658 /// Return if operations acting on VGPR tuples require even alignment.
659 bool needsAlignedVGPRs() const { return RequiresAlignVGPR; }
660
661 /// Return true if the target has the S_PACK_HL_B32_B16 instruction.
662 bool hasSPackHL() const { return HasGFX11Insts; }
663
664 /// Return true if the target has the V_CVT_PK_I16_F32/V_CVT_PK_U16_F32
665 /// instructions.
666 bool hasVCvtPkIU16F32() const { return HasGFX11Insts; }
667
668 /// Return true if the target's EXP instruction supports the NULL export
669 /// target.
670 bool hasNullExportTarget() const { return !HasGFX11Insts; }
671
672 bool hasFlatScratchSVSSwizzleBug() const { return getGeneration() == GFX11; }
673
674 /// Return true if the target has the S_DELAY_ALU instruction.
675 bool hasDelayAlu() const { return HasGFX11Insts; }
676
677 /// Returns true if the target supports
678 /// global_load_lds_dwordx3/global_load_lds_dwordx4 or
679 /// buffer_load_dwordx3/buffer_load_dwordx4 with the lds bit.
680 bool hasLDSLoadB96_B128() const { return hasGFX950Insts(); }
681
682 /// \returns true if the target uses LOADcnt/SAMPLEcnt/BVHcnt, DScnt/KMcnt
683 /// and STOREcnt rather than VMcnt, LGKMcnt and VScnt respectively.
684 bool hasExtendedWaitCounts() const { return getGeneration() >= GFX12; }
685
686 /// \returns true if the target has packed f32 instructions that only read 32
687 /// bits from a scalar operand (SGPR or literal) and replicates the bits to
688 /// both channels.
689 bool hasPKF32InstsReplicatingLower32BitsOfScalarInput() const {
690 return getGeneration() == GFX12 && HasGFX1250Insts;
691 }
692
693 bool hasAddPC64Inst() const { return HasGFX1250Insts; }
694
695 /// \returns true if the target supports expert scheduling mode 2 which relies
696 /// on the compiler to insert waits to avoid hazards between VMEM and VALU
697 /// instructions in some instances.
698 bool hasExpertSchedulingMode() const { return getGeneration() >= GFX12; }
699
700 /// \returns The maximum number of instructions that can be enclosed in an
701 /// S_CLAUSE on the given subtarget, or 0 for targets that do not support that
702 /// instruction.
703 unsigned maxHardClauseLength() const { return MaxHardClauseLength; }
704
705 /// Return the maximum number of waves per SIMD for kernels using \p SGPRs
706 /// SGPRs
707 unsigned getOccupancyWithNumSGPRs(unsigned SGPRs) const;
708
709 /// Return the maximum number of waves per SIMD for kernels using \p VGPRs
710 /// VGPRs
711 unsigned getOccupancyWithNumVGPRs(unsigned VGPRs,
712 unsigned DynamicVGPRBlockSize) const;
713
714 /// Subtarget's minimum/maximum occupancy, in number of waves per EU, that can
715 /// be achieved when the only function running on a CU is \p F, each workgroup
716 /// uses \p LDSSize bytes of LDS, and each wave uses \p NumSGPRs SGPRs and \p
717 /// NumVGPRs VGPRs. The flat workgroup sizes associated to the function are a
718 /// range, so this returns a range as well.
719 ///
720 /// Note that occupancy can be affected by the scratch allocation as well, but
721 /// we do not have enough information to compute it.
722 std::pair<unsigned, unsigned> computeOccupancy(const Function &F,
723 unsigned LDSSize = 0,
724 unsigned NumSGPRs = 0,
725 unsigned NumVGPRs = 0) const;
726
727 /// \returns true if the flat_scratch register should be initialized with the
728 /// pointer to the wave's scratch memory rather than a size and offset.
729 bool flatScratchIsPointer() const {
730 return getGeneration() >= AMDGPUSubtarget::GFX9;
731 }
732
733 /// \returns true if the machine has merged shaders in which s0-s7 are
734 /// reserved by the hardware and user SGPRs start at s8
735 bool hasMergedShaders() const { return getGeneration() >= GFX9; }
736
737 // \returns true if the target supports the pre-NGG legacy geometry path.
738 bool hasLegacyGeometry() const { return getGeneration() < GFX11; }
739
740 // \returns true if the target has split barriers feature
741 bool hasSplitBarriers() const { return getGeneration() >= GFX12; }
742
743 // \returns true if the target has WG_RR_MODE kernel descriptor mode bit
744 bool hasRrWGMode() const { return getGeneration() >= GFX12; }
745
746 /// \returns true if VADDR and SADDR fields in VSCRATCH can use negative
747 /// values.
748 bool hasSignedScratchOffsets() const { return getGeneration() >= GFX12; }
749
750 bool hasINVWBL2WaitCntRequirement() const { return HasGFX1250Insts; }
751
752 bool hasVOPD3() const { return HasGFX1250Insts; }
753
754 // \returns true if the target has V_PK_{MIN|MAX}3_{I|U}16 instructions.
755 bool hasPkMinMax3Insts() const { return HasGFX1250Insts; }
756
757 // \returns ture if target has S_GET_SHADER_CYCLES_U64 instruction.
758 bool hasSGetShaderCyclesInst() const { return HasGFX1250Insts; }
759
760 // \returns true if S_GETPC_B64 zero-extends the result from 48 bits instead
761 // of sign-extending. Note that GFX1250 has not only fixed the bug but also
762 // extended VA to 57 bits.
763 bool hasGetPCZeroExtension() const {
764 return HasGFX12Insts && !HasGFX1250Insts;
765 }
766
767 // \returns true if the target needs to create a prolog for backward
768 // compatibility when preloading kernel arguments.
769 bool needsKernArgPreloadProlog() const {
770 return hasKernargPreload() && !HasGFX1250Insts;
771 }
772
773 bool hasCondSubInsts() const { return HasGFX12Insts; }
774
775 bool hasSubClampInsts() const { return hasGFX10_3Insts(); }
776
777 bool hasAnyPackedFP32Ops() const {
778 return hasPackedFP32Ops() || hasPackedFP32SingleSGPROps();
779 };
780
781 bool hasAnyPackedFP64Ops() const { return hasPackedFP64SingleSGPROps(); };
782
783 bool hasAnyPackedU64Ops() const { return hasPackedU64SingleSGPROps(); };
784
785 /// \returns SGPR allocation granularity supported by the subtarget.
786 unsigned getSGPRAllocGranule() const {
787 return AMDGPU::getSGPRAllocGranule(AK: getTargetID().getGPUKind());
788 }
789
790 /// \returns SGPR encoding granularity supported by the subtarget.
791 unsigned getSGPREncodingGranule() const {
792 return AMDGPU::IsaInfo::getSGPREncodingGranule(STI: *this);
793 }
794
795 /// \returns Total number of SGPRs supported by the subtarget.
796 unsigned getTotalNumSGPRs() const {
797 return AMDGPU::getTotalNumSGPRs(AK: getTargetID().getGPUKind());
798 }
799
800 /// \returns Addressable number of SGPRs supported by the subtarget.
801 unsigned getAddressableNumSGPRs() const {
802 return AMDGPU::getAddressableNumSGPRs(AK: getTargetID().getGPUKind());
803 }
804
805 /// \returns Minimum number of SGPRs that meets the given number of waves per
806 /// execution unit requirement supported by the subtarget.
807 unsigned getMinNumSGPRs(unsigned WavesPerEU) const {
808 return AMDGPU::IsaInfo::getMinNumSGPRs(STI: *this, WavesPerEU);
809 }
810
811 /// \returns Maximum number of SGPRs that meets the given number of waves per
812 /// execution unit requirement supported by the subtarget.
813 unsigned getMaxNumSGPRs(unsigned WavesPerEU, bool Addressable) const {
814 return AMDGPU::IsaInfo::getMaxNumSGPRs(STI: *this, WavesPerEU, Addressable);
815 }
816
817 /// \returns Reserved number of SGPRs. This is common
818 /// utility function called by MachineFunction and
819 /// Function variants of getReservedNumSGPRs.
820 unsigned getBaseReservedNumSGPRs(const bool HasFlatScratch) const;
821 /// \returns Reserved number of SGPRs for given machine function \p MF.
822 unsigned getReservedNumSGPRs(const MachineFunction &MF) const;
823
824 /// \returns Reserved number of SGPRs for given function \p F.
825 unsigned getReservedNumSGPRs(const Function &F) const;
826
827 /// \returns Maximum number of preloaded SGPRs for the subtarget.
828 unsigned getMaxNumPreloadedSGPRs() const;
829
830 /// \returns max num SGPRs. This is the common utility
831 /// function called by MachineFunction and Function
832 /// variants of getMaxNumSGPRs.
833 unsigned getBaseMaxNumSGPRs(const Function &F,
834 std::pair<unsigned, unsigned> WavesPerEU,
835 unsigned PreloadedSGPRs,
836 unsigned ReservedNumSGPRs) const;
837
838 /// \returns Maximum number of SGPRs that meets number of waves per execution
839 /// unit requirement for function \p MF, or number of SGPRs explicitly
840 /// requested using "amdgpu-num-sgpr" attribute attached to function \p MF.
841 ///
842 /// \returns Value that meets number of waves per execution unit requirement
843 /// if explicitly requested value cannot be converted to integer, violates
844 /// subtarget's specifications, or does not meet number of waves per execution
845 /// unit requirement.
846 unsigned getMaxNumSGPRs(const MachineFunction &MF) const;
847
848 /// \returns Maximum number of SGPRs that meets number of waves per execution
849 /// unit requirement for function \p F, or number of SGPRs explicitly
850 /// requested using "amdgpu-num-sgpr" attribute attached to function \p F.
851 ///
852 /// \returns Value that meets number of waves per execution unit requirement
853 /// if explicitly requested value cannot be converted to integer, violates
854 /// subtarget's specifications, or does not meet number of waves per execution
855 /// unit requirement.
856 unsigned getMaxNumSGPRs(const Function &F) const;
857
858 /// \returns VGPR allocation granularity supported by the subtarget.
859 unsigned getVGPRAllocGranule(unsigned DynamicVGPRBlockSize) const {
860 return AMDGPU::IsaInfo::getVGPRAllocGranule(STI: *this, DynamicVGPRBlockSize);
861 }
862
863 /// \returns VGPR encoding granularity supported by the subtarget.
864 unsigned getVGPREncodingGranule() const {
865 return AMDGPU::IsaInfo::getVGPREncodingGranule(STI: *this);
866 }
867
868 /// \returns Total number of VGPRs supported by the subtarget.
869 unsigned getTotalNumVGPRs() const {
870 return AMDGPU::getTotalNumVGPRs(AK: getTargetID().getGPUKind(), IsWave32: isWave32());
871 }
872
873 /// \returns Addressable number of architectural VGPRs supported by the
874 /// subtarget.
875 unsigned getAddressableNumArchVGPRs() const {
876 return AMDGPU::IsaInfo::getAddressableNumArchVGPRs(STI: *this);
877 }
878
879 /// \returns Addressable number of VGPRs supported by the subtarget.
880 unsigned getAddressableNumVGPRs(unsigned DynamicVGPRBlockSize) const {
881 // Dynamic VGPR mode is a per-kernel mode, so it is not covered by the
882 // TargetParser query.
883 if (DynamicVGPRBlockSize != 0) {
884 return AMDGPU::IsaInfo::getAddressableNumVGPRs(STI: *this,
885 DynamicVGPRBlockSize);
886 }
887 return AMDGPU::getAddressableNumVGPRs(AK: getTargetID().getGPUKind(),
888 IsWave32: isWave32());
889 }
890
891 /// \returns the minimum number of VGPRs that will prevent achieving more than
892 /// the specified number of waves \p WavesPerEU.
893 unsigned getMinNumVGPRs(unsigned WavesPerEU,
894 unsigned DynamicVGPRBlockSize) const {
895 return AMDGPU::IsaInfo::getMinNumVGPRs(STI: *this, WavesPerEU,
896 DynamicVGPRBlockSize);
897 }
898
899 /// \returns the maximum number of VGPRs that can be used and still achieved
900 /// at least the specified number of waves \p WavesPerEU.
901 unsigned getMaxNumVGPRs(unsigned WavesPerEU,
902 unsigned DynamicVGPRBlockSize) const {
903 return AMDGPU::IsaInfo::getMaxNumVGPRs(STI: *this, WavesPerEU,
904 DynamicVGPRBlockSize);
905 }
906
907 /// \returns max num VGPRs. This is the common utility function
908 /// called by MachineFunction and Function variants of getMaxNumVGPRs.
909 unsigned
910 getBaseMaxNumVGPRs(const Function &F,
911 std::pair<unsigned, unsigned> NumVGPRBounds) const;
912
913 /// \returns Maximum number of VGPRs that meets number of waves per execution
914 /// unit requirement for function \p F, or number of VGPRs explicitly
915 /// requested using "amdgpu-num-vgpr" attribute attached to function \p F.
916 ///
917 /// \returns Value that meets number of waves per execution unit requirement
918 /// if explicitly requested value cannot be converted to integer, violates
919 /// subtarget's specifications, or does not meet number of waves per execution
920 /// unit requirement.
921 unsigned getMaxNumVGPRs(const Function &F) const;
922
923 unsigned getMaxNumAGPRs(const Function &F) const { return getMaxNumVGPRs(F); }
924
925 /// Return a pair of maximum numbers of VGPRs and AGPRs that meet the number
926 /// of waves per execution unit required for the function \p MF.
927 std::pair<unsigned, unsigned> getMaxNumVectorRegs(const Function &F) const;
928
929 /// \returns Maximum number of VGPRs that meets number of waves per execution
930 /// unit requirement for function \p MF, or number of VGPRs explicitly
931 /// requested using "amdgpu-num-vgpr" attribute attached to function \p MF.
932 ///
933 /// \returns Value that meets number of waves per execution unit requirement
934 /// if explicitly requested value cannot be converted to integer, violates
935 /// subtarget's specifications, or does not meet number of waves per execution
936 /// unit requirement.
937 unsigned getMaxNumVGPRs(const MachineFunction &MF) const;
938
939 bool isWave32() const { return getWavefrontSize() == 32; }
940
941 bool isWave64() const { return getWavefrontSize() == 64; }
942
943 /// Returns if the wavesize of this subtarget is known reliable. This is false
944 /// only for the a default target-cpu that does not have an explicit
945 /// +wavefrontsize target feature.
946 bool isWaveSizeKnown() const {
947 return hasFeature(Feature: AMDGPU::FeatureWavefrontSize32) ||
948 hasFeature(Feature: AMDGPU::FeatureWavefrontSize64);
949 }
950
951 const TargetRegisterClass *getBoolRC() const {
952 return getRegisterInfo()->getBoolRC();
953 }
954
955 /// \returns Maximum number of work groups per compute unit supported by the
956 /// subtarget and limited by given \p FlatWorkGroupSize.
957 unsigned getMaxWorkGroupsPerCU(unsigned FlatWorkGroupSize) const override {
958 return AMDGPU::IsaInfo::getMaxWorkGroupsPerCU(STI: *this, FlatWorkGroupSize);
959 }
960
961 /// \returns Minimum flat work group size supported by the subtarget.
962 unsigned getMinFlatWorkGroupSize() const override {
963 return AMDGPU::getMinFlatWorkGroupSize();
964 }
965
966 /// \returns Maximum flat work group size supported by the subtarget.
967 unsigned getMaxFlatWorkGroupSize() const override {
968 return AMDGPU::getMaxFlatWorkGroupSize();
969 }
970
971 /// \returns Number of waves per execution unit required to support the given
972 /// \p FlatWorkGroupSize.
973 unsigned
974 getWavesPerEUForWorkGroup(unsigned FlatWorkGroupSize) const override {
975 return AMDGPU::IsaInfo::getWavesPerEUForWorkGroup(STI: *this, FlatWorkGroupSize);
976 }
977
978 /// \returns Minimum number of waves per execution unit supported by the
979 /// subtarget.
980 unsigned getMinWavesPerEU() const override {
981 return AMDGPU::getMinWavesPerEU();
982 }
983
984 void adjustSchedDependency(SUnit *Def, int DefOpIdx, SUnit *Use, int UseOpIdx,
985 SDep &Dep,
986 const TargetSchedModel *SchedModel) const override;
987
988 // \returns true if it's beneficial on this subtarget for the scheduler to
989 // cluster stores as well as loads.
990 bool shouldClusterStores() const { return getGeneration() >= GFX11; }
991
992 // \returns the number of address arguments from which to enable MIMG NSA
993 // on supported architectures.
994 unsigned getNSAThreshold(const MachineFunction &MF) const;
995
996 // \returns true if the subtarget has a hazard requiring an "s_nop 0"
997 // instruction before "s_sendmsg sendmsg(MSG_DEALLOC_VGPRS)".
998 bool requiresNopBeforeDeallocVGPRs() const { return !HasGFX1250Insts; }
999
1000 // \returns true if the subtarget needs S_WAIT_ALU 0 before S_GETREG_B32 on
1001 // STATUS, STATE_PRIV, EXCP_FLAG_PRIV, or EXCP_FLAG_USER.
1002 bool requiresWaitIdleBeforeGetReg() const { return HasGFX1250Insts; }
1003
1004 bool requiresDisjointEarlyClobberAndUndef() const override {
1005 // AMDGPU doesn't care if early-clobber and undef operands are allocated
1006 // to the same register.
1007 return false;
1008 }
1009
1010 // DS_ATOMIC_ASYNC_BARRIER_ARRIVE_B64 shall not be claused with anything
1011 // and surronded by S_WAIT_ALU(0xFFE3).
1012 bool hasDsAtomicAsyncBarrierArriveB64PipeBug() const {
1013 return getGeneration() == GFX12;
1014 }
1015
1016 // Requires s_wait_alu(0) after s102/s103 write and src_flat_scratch_base
1017 // read.
1018 bool hasScratchBaseForwardingHazard() const {
1019 return HasGFX1250Insts && getGeneration() == GFX12;
1020 }
1021
1022 // src_flat_scratch_hi cannot be used as a source in SALU producing a 64-bit
1023 // result.
1024 bool hasFlatScratchHiInB64InstHazard() const {
1025 return HasGFX1250Insts && getGeneration() == GFX12;
1026 }
1027
1028 /// \returns true if the subtarget requires a wait for xcnt before VMEM
1029 /// accesses that must never be repeated in the event of a page fault/re-try.
1030 /// Atomic stores/rmw and all volatile accesses fall under this criteria.
1031 bool requiresWaitXCntForSingleAccessInstructions() const {
1032 return HasGFX1250Insts;
1033 }
1034
1035 /// True if VALU pipe occupancy is modeled with GFX1250BlockingCycles
1036 /// (gfx1250 pipeline property, not gfx1250 ISA feature).
1037 bool hasGFX1250VALUBlockingCycles() const { return AMDGPU::isGFX1250(STI: *this); }
1038
1039 /// \returns the number of significant bits in the immediate field of the
1040 /// S_NOP instruction.
1041 unsigned getSNopBits() const {
1042 if (getGeneration() >= AMDGPUSubtarget::GFX12)
1043 return 7;
1044 if (getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS)
1045 return 4;
1046 return 3;
1047 }
1048
1049 bool supportsBPermute() const {
1050 return getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS;
1051 }
1052
1053 bool supportsWaveWideBPermute() const {
1054 return (getGeneration() <= AMDGPUSubtarget::GFX9 ||
1055 getGeneration() == AMDGPUSubtarget::GFX12) ||
1056 isWave32();
1057 }
1058
1059 /// Return true if real (non-fake) variants of True16 instructions using
1060 /// 16-bit registers should be code-generated. Fake True16 instructions are
1061 /// identical to non-fake ones except that they take 32-bit registers as
1062 /// operands and always use their low halves.
1063 // TODO: Remove and use hasTrue16BitInsts() instead once True16 is fully
1064 // supported and the support for fake True16 instructions is removed.
1065 bool useRealTrue16Insts() const {
1066 return hasTrue16BitInsts() && EnableRealTrue16Insts;
1067 }
1068
1069 bool requiresWaitOnWorkgroupReleaseFence(bool TgSplit) const {
1070 return getGeneration() >= GFX10 || TgSplit;
1071 }
1072
1073 bool useDFAforSMS() const override { return false; }
1074
1075 bool enableWindowScheduler() const override { return false; }
1076
1077 // \returns true if ISel should select the native i64 min/max instructions
1078 // (V_MIN/MAX_{I|U}64).
1079 bool useMinMaxI64Insts() const {
1080 return hasMinMaxI64Insts() && !hasSlowMaxMinMulI64Insts();
1081 }
1082
1083 // \returns true if ISel should select the native i64 mul instruction
1084 // V_MUL_U64.
1085 bool useVMulU64Inst() const {
1086 return hasVMulU64Inst() && !hasSlowMaxMinMulI64Insts();
1087 }
1088};
1089
1090class GCNUserSGPRUsageInfo {
1091public:
1092 bool hasImplicitBufferPtr() const { return ImplicitBufferPtr; }
1093
1094 bool hasPrivateSegmentBuffer() const { return PrivateSegmentBuffer; }
1095
1096 bool hasDispatchPtr() const { return DispatchPtr; }
1097
1098 bool hasQueuePtr() const { return QueuePtr; }
1099
1100 bool hasKernargSegmentPtr() const { return KernargSegmentPtr; }
1101
1102 bool hasDispatchID() const { return DispatchID; }
1103
1104 bool hasFlatScratchInit() const { return FlatScratchInit; }
1105
1106 bool hasPrivateSegmentSize() const { return PrivateSegmentSize; }
1107
1108 unsigned getNumKernargPreloadSGPRs() const { return NumKernargPreloadSGPRs; }
1109
1110 unsigned getNumUsedUserSGPRs() const { return NumUsedUserSGPRs; }
1111
1112 unsigned getNumFreeUserSGPRs();
1113
1114 void allocKernargPreloadSGPRs(unsigned NumSGPRs);
1115
1116 enum UserSGPRID : unsigned {
1117 ImplicitBufferPtrID = 0,
1118 PrivateSegmentBufferID = 1,
1119 DispatchPtrID = 2,
1120 QueuePtrID = 3,
1121 KernargSegmentPtrID = 4,
1122 DispatchIdID = 5,
1123 FlatScratchInitID = 6,
1124 PrivateSegmentSizeID = 7
1125 };
1126
1127 // Returns the size in number of SGPRs for preload user SGPR field.
1128 static unsigned getNumUserSGPRForField(UserSGPRID ID) {
1129 switch (ID) {
1130 case ImplicitBufferPtrID:
1131 return 2;
1132 case PrivateSegmentBufferID:
1133 return 4;
1134 case DispatchPtrID:
1135 return 2;
1136 case QueuePtrID:
1137 return 2;
1138 case KernargSegmentPtrID:
1139 return 2;
1140 case DispatchIdID:
1141 return 2;
1142 case FlatScratchInitID:
1143 return 2;
1144 case PrivateSegmentSizeID:
1145 return 1;
1146 }
1147 llvm_unreachable("Unknown UserSGPRID.");
1148 }
1149
1150 GCNUserSGPRUsageInfo(const Function &F, const GCNSubtarget &ST);
1151
1152private:
1153 const GCNSubtarget &ST;
1154
1155 // Private memory buffer
1156 // Compute directly in sgpr[0:1]
1157 // Other shaders indirect 64-bits at sgpr[0:1]
1158 bool ImplicitBufferPtr = false;
1159
1160 bool PrivateSegmentBuffer = false;
1161
1162 bool DispatchPtr = false;
1163
1164 bool QueuePtr = false;
1165
1166 bool KernargSegmentPtr = false;
1167
1168 bool DispatchID = false;
1169
1170 bool FlatScratchInit = false;
1171
1172 bool PrivateSegmentSize = false;
1173
1174 unsigned NumKernargPreloadSGPRs = 0;
1175
1176 unsigned NumUsedUserSGPRs = 0;
1177};
1178
1179} // end namespace llvm
1180
1181#endif // LLVM_LIB_TARGET_AMDGPU_GCNSUBTARGET_H
1182