LLVM 19.0.0git
GCNSubtarget.h
Go to the documentation of this file.
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"
19#include "AMDGPUSubtarget.h"
20#include "SIFrameLowering.h"
21#include "SIISelLowering.h"
22#include "SIInstrInfo.h"
26
27#define GET_SUBTARGETINFO_HEADER
28#include "AMDGPUGenSubtargetInfo.inc"
29
30namespace llvm {
31
32class GCNTargetMachine;
33
35 public AMDGPUSubtarget {
36public:
38
39 // Following 2 enums are documented at:
40 // - https://llvm.org/docs/AMDGPUUsage.html#trap-handler-abi
41 enum class TrapHandlerAbi {
42 NONE = 0x00,
43 AMDHSA = 0x01,
44 };
45
46 enum class TrapID {
47 LLVMAMDHSATrap = 0x02,
49 };
50
51private:
52 /// GlobalISel related APIs.
53 std::unique_ptr<AMDGPUCallLowering> CallLoweringInfo;
54 std::unique_ptr<InlineAsmLowering> InlineAsmLoweringInfo;
55 std::unique_ptr<InstructionSelector> InstSelector;
56 std::unique_ptr<LegalizerInfo> Legalizer;
57 std::unique_ptr<AMDGPURegisterBankInfo> RegBankInfo;
58
59protected:
60 // Basic subtarget description.
63 unsigned Gen = INVALID;
65 int LDSBankCount = 0;
67
68 // Possibly statically set by tablegen, but may want to be overridden.
69 bool FastDenormalF32 = false;
70 bool HalfRate64Ops = false;
71 bool FullRate64Ops = false;
72
73 // Dynamically set bits that enable features.
74 bool FlatForGlobal = false;
76 bool BackOffBarrier = false;
78 bool UnalignedAccessMode = false;
79 bool HasApertureRegs = false;
80 bool SupportsXNACK = false;
81 bool KernargPreload = false;
82
83 // This should not be used directly. 'TargetID' tracks the dynamic settings
84 // for XNACK.
85 bool EnableXNACK = false;
86
87 bool EnableTgSplit = false;
88 bool EnableCuMode = false;
89 bool TrapHandler = false;
90 bool EnablePreciseMemory = false;
91
92 // Used as options.
93 bool EnableLoadStoreOpt = false;
95 bool EnableSIScheduler = false;
96 bool EnableDS128 = false;
97 bool EnablePRTStrictNull = false;
98 bool DumpCode = false;
99
100 // Subtarget statically properties set by tablegen
101 bool FP64 = false;
102 bool FMA = false;
103 bool MIMG_R128 = false;
104 bool CIInsts = false;
105 bool GFX8Insts = false;
106 bool GFX9Insts = false;
107 bool GFX90AInsts = false;
108 bool GFX940Insts = false;
109 bool GFX10Insts = false;
110 bool GFX11Insts = false;
111 bool GFX12Insts = false;
112 bool GFX10_3Insts = false;
113 bool GFX7GFX8GFX9Insts = false;
114 bool SGPRInitBug = false;
115 bool UserSGPRInit16Bug = false;
118 bool HasSMemRealTime = false;
119 bool HasIntClamp = false;
120 bool HasFmaMixInsts = false;
121 bool HasMovrel = false;
122 bool HasVGPRIndexMode = false;
124 bool HasScalarStores = false;
125 bool HasScalarAtomics = false;
126 bool HasSDWAOmod = false;
127 bool HasSDWAScalar = false;
128 bool HasSDWASdst = false;
129 bool HasSDWAMac = false;
130 bool HasSDWAOutModsVOPC = false;
131 bool HasDPP = false;
132 bool HasDPP8 = false;
133 bool HasDPALU_DPP = false;
134 bool HasDPPSrc1SGPR = false;
135 bool HasPackedFP32Ops = false;
136 bool HasImageInsts = false;
138 bool HasR128A16 = false;
139 bool HasA16 = false;
140 bool HasG16 = false;
141 bool HasNSAEncoding = false;
143 bool GFX10_AEncoding = false;
144 bool GFX10_BEncoding = false;
145 bool HasDLInsts = false;
146 bool HasFmacF64Inst = false;
147 bool HasDot1Insts = false;
148 bool HasDot2Insts = false;
149 bool HasDot3Insts = false;
150 bool HasDot4Insts = false;
151 bool HasDot5Insts = false;
152 bool HasDot6Insts = false;
153 bool HasDot7Insts = false;
154 bool HasDot8Insts = false;
155 bool HasDot9Insts = false;
156 bool HasDot10Insts = false;
157 bool HasDot11Insts = false;
158 bool HasMAIInsts = false;
159 bool HasFP8Insts = false;
161 bool HasPkFmacF16Inst = false;
173 /// The maximum number of instructions that may be placed within an S_CLAUSE,
174 /// which is one greater than the maximum argument to S_CLAUSE. A value of 0
175 /// indicates a lack of S_CLAUSE support.
177 bool SupportsSRAMECC = false;
178
179 // This should not be used directly. 'TargetID' tracks the dynamic settings
180 // for SRAMECC.
181 bool EnableSRAMECC = false;
182
183 bool HasNoSdstCMPX = false;
184 bool HasVscnt = false;
185 bool HasGetWaveIdInst = false;
186 bool HasSMemTimeInst = false;
189 bool HasVOP3Literal = false;
190 bool HasNoDataDepHazard = false;
191 bool FlatAddressSpace = false;
192 bool FlatInstOffsets = false;
193 bool FlatGlobalInsts = false;
194 bool FlatScratchInsts = false;
197 bool EnableFlatScratch = false;
199 bool HasGDS = false;
200 bool HasGWS = false;
201 bool AddNoCarryInsts = false;
202 bool HasUnpackedD16VMem = false;
203 bool LDSMisalignedBug = false;
206 bool UnalignedDSAccess = false;
207 bool HasPackedTID = false;
208 bool ScalarizeGlobal = false;
209 bool HasSALUFloatInsts = false;
213
220 bool HasNSAtoVMEMBug = false;
221 bool HasNSAClauseBug = false;
222 bool HasOffset3fBug = false;
228 bool Has1_5xVGPRs = false;
229 bool HasMADIntraFwdBug = false;
230 bool HasVOPDInsts = false;
233
234 bool RequiresCOV6 = false;
235
236 // Dummy feature to use for assembler in tablegen.
237 bool FeatureDisable = false;
238
240private:
241 SIInstrInfo InstrInfo;
242 SITargetLowering TLInfo;
243 SIFrameLowering FrameLowering;
244
245public:
246 GCNSubtarget(const Triple &TT, StringRef GPU, StringRef FS,
247 const GCNTargetMachine &TM);
248 ~GCNSubtarget() override;
249
251 StringRef GPU, StringRef FS);
252
253 /// Diagnose inconsistent subtarget features before attempting to codegen
254 /// function \p F.
255 void checkSubtargetFeatures(const Function &F) const;
256
257 const SIInstrInfo *getInstrInfo() const override {
258 return &InstrInfo;
259 }
260
261 const SIFrameLowering *getFrameLowering() const override {
262 return &FrameLowering;
263 }
264
265 const SITargetLowering *getTargetLowering() const override {
266 return &TLInfo;
267 }
268
269 const SIRegisterInfo *getRegisterInfo() const override {
270 return &InstrInfo.getRegisterInfo();
271 }
272
273 const CallLowering *getCallLowering() const override {
274 return CallLoweringInfo.get();
275 }
276
277 const InlineAsmLowering *getInlineAsmLowering() const override {
278 return InlineAsmLoweringInfo.get();
279 }
280
282 return InstSelector.get();
283 }
284
285 const LegalizerInfo *getLegalizerInfo() const override {
286 return Legalizer.get();
287 }
288
289 const AMDGPURegisterBankInfo *getRegBankInfo() const override {
290 return RegBankInfo.get();
291 }
292
294 return TargetID;
295 }
296
297 // Nothing implemented, just prevent crashes on use.
299 return &TSInfo;
300 }
301
303 return &InstrItins;
304 }
305
307
309 return (Generation)Gen;
310 }
311
312 unsigned getMaxWaveScratchSize() const {
313 // See COMPUTE_TMPRING_SIZE.WAVESIZE.
314 if (getGeneration() >= GFX12) {
315 // 18-bit field in units of 64-dword.
316 return (64 * 4) * ((1 << 18) - 1);
317 }
318 if (getGeneration() == GFX11) {
319 // 15-bit field in units of 64-dword.
320 return (64 * 4) * ((1 << 15) - 1);
321 }
322 // 13-bit field in units of 256-dword.
323 return (256 * 4) * ((1 << 13) - 1);
324 }
325
326 /// Return the number of high bits known to be zero for a frame index.
329 }
330
331 int getLDSBankCount() const {
332 return LDSBankCount;
333 }
334
335 unsigned getMaxPrivateElementSize(bool ForBufferRSrc = false) const {
336 return (ForBufferRSrc || !enableFlatScratch()) ? MaxPrivateElementSize : 16;
337 }
338
339 unsigned getConstantBusLimit(unsigned Opcode) const;
340
341 /// Returns if the result of this instruction with a 16-bit result returned in
342 /// a 32-bit register implicitly zeroes the high 16-bits, rather than preserve
343 /// the original value.
344 bool zeroesHigh16BitsOfDest(unsigned Opcode) const;
345
346 bool supportsWGP() const { return getGeneration() >= GFX10; }
347
348 bool hasIntClamp() const {
349 return HasIntClamp;
350 }
351
352 bool hasFP64() const {
353 return FP64;
354 }
355
356 bool hasMIMG_R128() const {
357 return MIMG_R128;
358 }
359
360 bool hasHWFP64() const {
361 return FP64;
362 }
363
364 bool hasHalfRate64Ops() const {
365 return HalfRate64Ops;
366 }
367
368 bool hasFullRate64Ops() const {
369 return FullRate64Ops;
370 }
371
372 bool hasAddr64() const {
374 }
375
376 bool hasFlat() const {
378 }
379
380 // Return true if the target only has the reverse operand versions of VALU
381 // shift instructions (e.g. v_lshrrev_b32, and no v_lshr_b32).
382 bool hasOnlyRevVALUShifts() const {
384 }
385
386 bool hasFractBug() const {
388 }
389
390 bool hasBFE() const {
391 return true;
392 }
393
394 bool hasBFI() const {
395 return true;
396 }
397
398 bool hasBFM() const {
399 return hasBFE();
400 }
401
402 bool hasBCNT(unsigned Size) const {
403 return true;
404 }
405
406 bool hasFFBL() const {
407 return true;
408 }
409
410 bool hasFFBH() const {
411 return true;
412 }
413
414 bool hasMed3_16() const {
416 }
417
418 bool hasMin3Max3_16() const {
420 }
421
422 bool hasFmaMixInsts() const {
423 return HasFmaMixInsts;
424 }
425
426 bool hasCARRY() const {
427 return true;
428 }
429
430 bool hasFMA() const {
431 return FMA;
432 }
433
434 bool hasSwap() const {
435 return GFX9Insts;
436 }
437
438 bool hasScalarPackInsts() const {
439 return GFX9Insts;
440 }
441
442 bool hasScalarMulHiInsts() const {
443 return GFX9Insts;
444 }
445
446 bool hasScalarSubwordLoads() const { return getGeneration() >= GFX12; }
447
450 }
451
453 // The S_GETREG DOORBELL_ID is supported by all GFX9 onward targets.
454 return getGeneration() >= GFX9;
455 }
456
457 /// True if the offset field of DS instructions works as expected. On SI, the
458 /// offset uses a 16-bit adder and does not always wrap properly.
459 bool hasUsableDSOffset() const {
460 return getGeneration() >= SEA_ISLANDS;
461 }
462
465 }
466
467 /// Condition output from div_scale is usable.
470 }
471
472 /// Extra wait hazard is needed in some cases before
473 /// s_cbranch_vccnz/s_cbranch_vccz.
474 bool hasReadVCCZBug() const {
475 return getGeneration() <= SEA_ISLANDS;
476 }
477
478 /// Writes to VCC_LO/VCC_HI update the VCCZ flag.
480 return getGeneration() >= GFX10;
481 }
482
483 /// A read of an SGPR by SMRD instruction requires 4 wait states when the SGPR
484 /// was written by a VALU instruction.
487 }
488
489 /// A read of an SGPR by a VMEM instruction requires 5 wait states when the
490 /// SGPR was written by a VALU Instruction.
493 }
494
495 bool hasRFEHazards() const {
497 }
498
499 /// Number of hazard wait states for s_setreg_b32/s_setreg_imm32_b32.
500 unsigned getSetRegWaitStates() const {
501 return getGeneration() <= SEA_ISLANDS ? 1 : 2;
502 }
503
504 bool dumpCode() const {
505 return DumpCode;
506 }
507
508 /// Return the amount of LDS that can be used that will not restrict the
509 /// occupancy lower than WaveCount.
510 unsigned getMaxLocalMemSizeWithWaveCount(unsigned WaveCount,
511 const Function &) const;
512
515 }
516
517 /// \returns If target supports S_DENORM_MODE.
518 bool hasDenormModeInst() const {
520 }
521
522 bool useFlatForGlobal() const {
523 return FlatForGlobal;
524 }
525
526 /// \returns If target supports ds_read/write_b128 and user enables generation
527 /// of ds_read/write_b128.
528 bool useDS128() const {
529 return CIInsts && EnableDS128;
530 }
531
532 /// \return If target supports ds_read/write_b96/128.
533 bool hasDS96AndDS128() const {
534 return CIInsts;
535 }
536
537 /// Have v_trunc_f64, v_ceil_f64, v_rndne_f64
538 bool haveRoundOpsF64() const {
539 return CIInsts;
540 }
541
542 /// \returns If MUBUF instructions always perform range checking, even for
543 /// buffer resources used for private memory access.
546 }
547
548 /// \returns If target requires PRT Struct NULL support (zero result registers
549 /// for sparse texture support).
550 bool usePRTStrictNull() const {
551 return EnablePRTStrictNull;
552 }
553
556 }
557
558 /// \returns true if the target supports backing off of s_barrier instructions
559 /// when an exception is raised.
561 return BackOffBarrier;
562 }
563
566 }
567
570 }
571
572 bool hasUnalignedDSAccess() const {
573 return UnalignedDSAccess;
574 }
575
578 }
579
582 }
583
585 return UnalignedAccessMode;
586 }
587
588 bool hasApertureRegs() const {
589 return HasApertureRegs;
590 }
591
592 bool isTrapHandlerEnabled() const {
593 return TrapHandler;
594 }
595
596 bool isXNACKEnabled() const {
597 return TargetID.isXnackOnOrAny();
598 }
599
600 bool isTgSplitEnabled() const {
601 return EnableTgSplit;
602 }
603
604 bool isCuModeEnabled() const {
605 return EnableCuMode;
606 }
607
609
610 bool hasFlatAddressSpace() const {
611 return FlatAddressSpace;
612 }
613
614 bool hasFlatScrRegister() const {
615 return hasFlatAddressSpace();
616 }
617
618 bool hasFlatInstOffsets() const {
619 return FlatInstOffsets;
620 }
621
622 bool hasFlatGlobalInsts() const {
623 return FlatGlobalInsts;
624 }
625
626 bool hasFlatScratchInsts() const {
627 return FlatScratchInsts;
628 }
629
630 // Check if target supports ST addressing mode with FLAT scratch instructions.
631 // The ST addressing mode means no registers are used, either VGPR or SGPR,
632 // but only immediate offset is swizzled and added to the FLAT scratch base.
633 bool hasFlatScratchSTMode() const {
635 }
636
637 bool hasFlatScratchSVSMode() const { return GFX940Insts || GFX11Insts; }
638
641 }
642
643 bool enableFlatScratch() const {
644 return flatScratchIsArchitected() ||
646 }
647
648 bool hasGlobalAddTidInsts() const {
649 return GFX10_BEncoding;
650 }
651
652 bool hasAtomicCSub() const {
653 return GFX10_BEncoding;
654 }
655
656 // BUFFER/FLAT/GLOBAL_ATOMIC_ADD/MIN/MAX_F64
658
659 bool hasExportInsts() const {
660 return !hasGFX940Insts();
661 }
662
663 bool hasVINTERPEncoding() const {
664 return GFX11Insts;
665 }
666
667 // DS_ADD_F64/DS_ADD_RTN_F64
668 bool hasLdsAtomicAddF64() const { return hasGFX90AInsts(); }
669
671 return getGeneration() >= GFX9;
672 }
673
676 }
677
679 return getGeneration() > GFX9;
680 }
681
682 bool hasD16LoadStore() const {
683 return getGeneration() >= GFX9;
684 }
685
688 }
689
690 bool hasD16Images() const {
692 }
693
694 /// Return if most LDS instructions have an m0 use that require m0 to be
695 /// initialized.
696 bool ldsRequiresM0Init() const {
697 return getGeneration() < GFX9;
698 }
699
700 // True if the hardware rewinds and replays GWS operations if a wave is
701 // preempted.
702 //
703 // If this is false, a GWS operation requires testing if a nack set the
704 // MEM_VIOL bit, and repeating if so.
705 bool hasGWSAutoReplay() const {
706 return getGeneration() >= GFX9;
707 }
708
709 /// \returns if target has ds_gws_sema_release_all instruction.
710 bool hasGWSSemaReleaseAll() const {
711 return CIInsts;
712 }
713
714 /// \returns true if the target has integer add/sub instructions that do not
715 /// produce a carry-out. This includes v_add_[iu]32, v_sub_[iu]32,
716 /// v_add_[iu]16, and v_sub_[iu]16, all of which support the clamp modifier
717 /// for saturation.
718 bool hasAddNoCarry() const {
719 return AddNoCarryInsts;
720 }
721
722 bool hasScalarAddSub64() const { return getGeneration() >= GFX12; }
723
724 bool hasScalarSMulU64() const { return getGeneration() >= GFX12; }
725
726 bool hasUnpackedD16VMem() const {
727 return HasUnpackedD16VMem;
728 }
729
730 // Covers VS/PS/CS graphics shaders
731 bool isMesaGfxShader(const Function &F) const {
732 return isMesa3DOS() && AMDGPU::isShader(F.getCallingConv());
733 }
734
735 bool hasMad64_32() const {
736 return getGeneration() >= SEA_ISLANDS;
737 }
738
739 bool hasSDWAOmod() const {
740 return HasSDWAOmod;
741 }
742
743 bool hasSDWAScalar() const {
744 return HasSDWAScalar;
745 }
746
747 bool hasSDWASdst() const {
748 return HasSDWASdst;
749 }
750
751 bool hasSDWAMac() const {
752 return HasSDWAMac;
753 }
754
755 bool hasSDWAOutModsVOPC() const {
756 return HasSDWAOutModsVOPC;
757 }
758
759 bool hasDLInsts() const {
760 return HasDLInsts;
761 }
762
763 bool hasFmacF64Inst() const { return HasFmacF64Inst; }
764
765 bool hasDot1Insts() const {
766 return HasDot1Insts;
767 }
768
769 bool hasDot2Insts() const {
770 return HasDot2Insts;
771 }
772
773 bool hasDot3Insts() const {
774 return HasDot3Insts;
775 }
776
777 bool hasDot4Insts() const {
778 return HasDot4Insts;
779 }
780
781 bool hasDot5Insts() const {
782 return HasDot5Insts;
783 }
784
785 bool hasDot6Insts() const {
786 return HasDot6Insts;
787 }
788
789 bool hasDot7Insts() const {
790 return HasDot7Insts;
791 }
792
793 bool hasDot8Insts() const {
794 return HasDot8Insts;
795 }
796
797 bool hasDot9Insts() const {
798 return HasDot9Insts;
799 }
800
801 bool hasDot10Insts() const {
802 return HasDot10Insts;
803 }
804
805 bool hasDot11Insts() const {
806 return HasDot11Insts;
807 }
808
809 bool hasMAIInsts() const {
810 return HasMAIInsts;
811 }
812
813 bool hasFP8Insts() const {
814 return HasFP8Insts;
815 }
816
818
819 bool hasPkFmacF16Inst() const {
820 return HasPkFmacF16Inst;
821 }
822
824
826
827 bool hasAtomicFaddInsts() const {
829 }
830
832
834
837 }
838
841 }
842
845 }
846
848
850
853 }
854
855 bool hasNoSdstCMPX() const {
856 return HasNoSdstCMPX;
857 }
858
859 bool hasVscnt() const {
860 return HasVscnt;
861 }
862
863 bool hasGetWaveIdInst() const {
864 return HasGetWaveIdInst;
865 }
866
867 bool hasSMemTimeInst() const {
868 return HasSMemTimeInst;
869 }
870
873 }
874
877 }
878
879 bool hasVOP3Literal() const {
880 return HasVOP3Literal;
881 }
882
883 bool hasNoDataDepHazard() const {
884 return HasNoDataDepHazard;
885 }
886
888 return getGeneration() < SEA_ISLANDS;
889 }
890
891 bool hasInstPrefetch() const {
892 return getGeneration() == GFX10 || getGeneration() == GFX11;
893 }
894
895 bool hasPrefetch() const { return GFX12Insts; }
896
897 // Has s_cmpk_* instructions.
898 bool hasSCmpK() const { return getGeneration() < GFX12; }
899
900 // Scratch is allocated in 256 dword per wave blocks for the entire
901 // wavefront. When viewed from the perspective of an arbitrary workitem, this
902 // is 4-byte aligned.
903 //
904 // Only 4-byte alignment is really needed to access anything. Transformations
905 // on the pointer value itself may rely on the alignment / known low bits of
906 // the pointer. Set this to something above the minimum to avoid needing
907 // dynamic realignment in common cases.
908 Align getStackAlignment() const { return Align(16); }
909
910 bool enableMachineScheduler() const override {
911 return true;
912 }
913
914 bool useAA() const override;
915
916 bool enableSubRegLiveness() const override {
917 return true;
918 }
919
922
923 // static wrappers
924 static bool hasHalfRate64Ops(const TargetSubtargetInfo &STI);
925
926 // XXX - Why is this here if it isn't in the default pass set?
927 bool enableEarlyIfConversion() const override {
928 return true;
929 }
930
932 unsigned NumRegionInstrs) const override;
933
934 void mirFileLoaded(MachineFunction &MF) const override;
935
936 unsigned getMaxNumUserSGPRs() const {
937 return AMDGPU::getMaxNumUserSGPRs(*this);
938 }
939
940 bool hasSMemRealTime() const {
941 return HasSMemRealTime;
942 }
943
944 bool hasMovrel() const {
945 return HasMovrel;
946 }
947
948 bool hasVGPRIndexMode() const {
949 return HasVGPRIndexMode;
950 }
951
952 bool useVGPRIndexMode() const;
953
954 bool hasScalarCompareEq64() const {
956 }
957
959
960 bool hasScalarStores() const {
961 return HasScalarStores;
962 }
963
964 bool hasScalarAtomics() const {
965 return HasScalarAtomics;
966 }
967
968 bool hasLDSFPAtomicAddF32() const { return GFX8Insts; }
969 bool hasLDSFPAtomicAddF64() const { return GFX90AInsts; }
970
971 /// \returns true if the subtarget has the v_permlanex16_b32 instruction.
972 bool hasPermLaneX16() const { return getGeneration() >= GFX10; }
973
974 /// \returns true if the subtarget has the v_permlane64_b32 instruction.
975 bool hasPermLane64() const { return getGeneration() >= GFX11; }
976
977 bool hasDPP() const {
978 return HasDPP;
979 }
980
981 bool hasDPPBroadcasts() const {
982 return HasDPP && getGeneration() < GFX10;
983 }
984
986 return HasDPP && getGeneration() < GFX10;
987 }
988
989 bool hasDPP8() const {
990 return HasDPP8;
991 }
992
993 bool hasDPALU_DPP() const {
994 return HasDPALU_DPP;
995 }
996
997 bool hasDPPSrc1SGPR() const { return HasDPPSrc1SGPR; }
998
999 bool hasPackedFP32Ops() const {
1000 return HasPackedFP32Ops;
1001 }
1002
1003 // Has V_PK_MOV_B32 opcode
1004 bool hasPkMovB32() const {
1005 return GFX90AInsts;
1006 }
1007
1009 return getGeneration() >= GFX10 || hasGFX940Insts();
1010 }
1011
1012 bool hasImageInsts() const {
1013 return HasImageInsts;
1014 }
1015
1017 return HasExtendedImageInsts;
1018 }
1019
1020 bool hasR128A16() const {
1021 return HasR128A16;
1022 }
1023
1024 bool hasA16() const { return HasA16; }
1025
1026 bool hasG16() const { return HasG16; }
1027
1028 bool hasOffset3fBug() const {
1029 return HasOffset3fBug;
1030 }
1031
1033
1035
1036 bool hasMADIntraFwdBug() const { return HasMADIntraFwdBug; }
1037
1039
1041
1042 bool hasNSAEncoding() const { return HasNSAEncoding; }
1043
1044 bool hasNonNSAEncoding() const { return getGeneration() < GFX12; }
1045
1047
1048 unsigned getNSAMaxSize(bool HasSampler = false) const {
1049 return AMDGPU::getNSAMaxSize(*this, HasSampler);
1050 }
1051
1052 bool hasGFX10_AEncoding() const {
1053 return GFX10_AEncoding;
1054 }
1055
1056 bool hasGFX10_BEncoding() const {
1057 return GFX10_BEncoding;
1058 }
1059
1060 bool hasGFX10_3Insts() const {
1061 return GFX10_3Insts;
1062 }
1063
1064 bool hasMadF16() const;
1065
1066 bool hasMovB64() const { return GFX940Insts; }
1067
1068 bool hasLshlAddB64() const { return GFX940Insts; }
1069
1070 bool enableSIScheduler() const {
1071 return EnableSIScheduler;
1072 }
1073
1074 bool loadStoreOptEnabled() const {
1075 return EnableLoadStoreOpt;
1076 }
1077
1078 bool hasSGPRInitBug() const {
1079 return SGPRInitBug;
1080 }
1081
1083 return UserSGPRInit16Bug && isWave32();
1084 }
1085
1087
1090 }
1091
1094 }
1095
1098 }
1099
1100 // \returns true if the subtarget supports DWORDX3 load/store instructions.
1102 return CIInsts;
1103 }
1104
1107 }
1108
1112 }
1113
1116 }
1117
1120 }
1121
1124 }
1125
1128 }
1129
1132 }
1133
1134 bool hasLDSMisalignedBug() const {
1135 return LDSMisalignedBug && !EnableCuMode;
1136 }
1137
1139 return HasInstFwdPrefetchBug;
1140 }
1141
1143 return HasVcmpxExecWARHazard;
1144 }
1145
1148 }
1149
1150 // Shift amount of a 64 bit shift cannot be a highest allocated register
1151 // if also at the end of the allocation block.
1153 return GFX90AInsts && !GFX940Insts;
1154 }
1155
1156 // Has one cycle hazard on transcendental instruction feeding a
1157 // non transcendental VALU.
1158 bool hasTransForwardingHazard() const { return GFX940Insts; }
1159
1160 // Has one cycle hazard on a VALU instruction partially writing dst with
1161 // a shift of result bits feeding another VALU instruction.
1163
1164 // Cannot use op_sel with v_dot instructions.
1165 bool hasDOTOpSelHazard() const { return GFX940Insts || GFX11Insts; }
1166
1167 // Does not have HW interlocs for VALU writing and then reading SGPRs.
1168 bool hasVDecCoExecHazard() const {
1169 return GFX940Insts;
1170 }
1171
1172 bool hasNSAtoVMEMBug() const {
1173 return HasNSAtoVMEMBug;
1174 }
1175
1176 bool hasNSAClauseBug() const { return HasNSAClauseBug; }
1177
1178 bool hasHardClauses() const { return MaxHardClauseLength > 0; }
1179
1180 bool hasGFX90AInsts() const { return GFX90AInsts; }
1181
1183 return getGeneration() == GFX10;
1184 }
1185
1186 bool hasVOP3DPP() const { return getGeneration() >= GFX11; }
1187
1188 bool hasLdsDirect() const { return getGeneration() >= GFX11; }
1189
1190 bool hasLdsWaitVMSRC() const { return getGeneration() >= GFX12; }
1191
1193 return getGeneration() == GFX11;
1194 }
1195
1197
1199
1200 bool requiresCodeObjectV6() const { return RequiresCOV6; }
1201
1202 bool hasVALUMaskWriteHazard() const { return getGeneration() == GFX11; }
1203
1204 /// Return if operations acting on VGPR tuples require even alignment.
1205 bool needsAlignedVGPRs() const { return GFX90AInsts; }
1206
1207 /// Return true if the target has the S_PACK_HL_B32_B16 instruction.
1208 bool hasSPackHL() const { return GFX11Insts; }
1209
1210 /// Return true if the target's EXP instruction has the COMPR flag, which
1211 /// affects the meaning of the EN (enable) bits.
1212 bool hasCompressedExport() const { return !GFX11Insts; }
1213
1214 /// Return true if the target's EXP instruction supports the NULL export
1215 /// target.
1216 bool hasNullExportTarget() const { return !GFX11Insts; }
1217
1218 bool has1_5xVGPRs() const { return Has1_5xVGPRs; }
1219
1220 bool hasVOPDInsts() const { return HasVOPDInsts; }
1221
1223
1224 /// Return true if the target has the S_DELAY_ALU instruction.
1225 bool hasDelayAlu() const { return GFX11Insts; }
1226
1227 bool hasPackedTID() const { return HasPackedTID; }
1228
1229 // GFX940 is a derivation to GFX90A. hasGFX940Insts() being true implies that
1230 // hasGFX90AInsts is also true.
1231 bool hasGFX940Insts() const { return GFX940Insts; }
1232
1233 bool hasSALUFloatInsts() const { return HasSALUFloatInsts; }
1234
1236
1238
1240
1241 /// \returns true if the target uses LOADcnt/SAMPLEcnt/BVHcnt, DScnt/KMcnt
1242 /// and STOREcnt rather than VMcnt, LGKMcnt and VScnt respectively.
1243 bool hasExtendedWaitCounts() const { return getGeneration() >= GFX12; }
1244
1245 /// \returns The maximum number of instructions that can be enclosed in an
1246 /// S_CLAUSE on the given subtarget, or 0 for targets that do not support that
1247 /// instruction.
1248 unsigned maxHardClauseLength() const { return MaxHardClauseLength; }
1249
1250 /// Return the maximum number of waves per SIMD for kernels using \p SGPRs
1251 /// SGPRs
1252 unsigned getOccupancyWithNumSGPRs(unsigned SGPRs) const;
1253
1254 /// Return the maximum number of waves per SIMD for kernels using \p VGPRs
1255 /// VGPRs
1256 unsigned getOccupancyWithNumVGPRs(unsigned VGPRs) const;
1257
1258 /// Return occupancy for the given function. Used LDS and a number of
1259 /// registers if provided.
1260 /// Note, occupancy can be affected by the scratch allocation as well, but
1261 /// we do not have enough information to compute it.
1262 unsigned computeOccupancy(const Function &F, unsigned LDSSize = 0,
1263 unsigned NumSGPRs = 0, unsigned NumVGPRs = 0) const;
1264
1265 /// \returns true if the flat_scratch register should be initialized with the
1266 /// pointer to the wave's scratch memory rather than a size and offset.
1269 }
1270
1271 /// \returns true if the flat_scratch register is initialized by the HW.
1272 /// In this case it is readonly.
1274
1275 /// \returns true if the architected SGPRs are enabled.
1277
1278 /// \returns true if Global Data Share is supported.
1279 bool hasGDS() const { return HasGDS; }
1280
1281 /// \returns true if Global Wave Sync is supported.
1282 bool hasGWS() const { return HasGWS; }
1283
1284 /// \returns true if the machine has merged shaders in which s0-s7 are
1285 /// reserved by the hardware and user SGPRs start at s8
1286 bool hasMergedShaders() const {
1287 return getGeneration() >= GFX9;
1288 }
1289
1290 // \returns true if the target supports the pre-NGG legacy geometry path.
1291 bool hasLegacyGeometry() const { return getGeneration() < GFX11; }
1292
1293 // \returns true if preloading kernel arguments is supported.
1294 bool hasKernargPreload() const { return KernargPreload; }
1295
1296 // \returns true if the target has split barriers feature
1297 bool hasSplitBarriers() const { return getGeneration() >= GFX12; }
1298
1299 // \returns true if FP8/BF8 VOP1 form of conversion to F32 is unreliable.
1300 bool hasCvtFP8VOP1Bug() const { return true; }
1301
1302 // \returns true if CSUB (a.k.a. SUB_CLAMP on GFX12) atomics support a
1303 // no-return form.
1305
1306 // \returns true if the target has DX10_CLAMP kernel descriptor mode bit
1307 bool hasDX10ClampMode() const { return getGeneration() < GFX12; }
1308
1309 // \returns true if the target has IEEE kernel descriptor mode bit
1310 bool hasIEEEMode() const { return getGeneration() < GFX12; }
1311
1312 // \returns true if the target has IEEE fminimum/fmaximum instructions
1313 bool hasIEEEMinMax() const { return getGeneration() >= GFX12; }
1314
1315 // \returns true if the target has WG_RR_MODE kernel descriptor mode bit
1316 bool hasRrWGMode() const { return getGeneration() >= GFX12; }
1317
1318 /// \returns true if VADDR and SADDR fields in VSCRATCH can use negative
1319 /// values.
1320 bool hasSignedScratchOffsets() const { return getGeneration() >= GFX12; }
1321
1322 // \returns true if S_GETPC_B64 zero-extends the result from 48 bits instead
1323 // of sign-extending.
1324 bool hasGetPCZeroExtension() const { return GFX12Insts; }
1325
1326 /// \returns SGPR allocation granularity supported by the subtarget.
1327 unsigned getSGPRAllocGranule() const {
1329 }
1330
1331 /// \returns SGPR encoding granularity supported by the subtarget.
1332 unsigned getSGPREncodingGranule() const {
1334 }
1335
1336 /// \returns Total number of SGPRs supported by the subtarget.
1337 unsigned getTotalNumSGPRs() const {
1339 }
1340
1341 /// \returns Addressable number of SGPRs supported by the subtarget.
1342 unsigned getAddressableNumSGPRs() const {
1344 }
1345
1346 /// \returns Minimum number of SGPRs that meets the given number of waves per
1347 /// execution unit requirement supported by the subtarget.
1348 unsigned getMinNumSGPRs(unsigned WavesPerEU) const {
1349 return AMDGPU::IsaInfo::getMinNumSGPRs(this, WavesPerEU);
1350 }
1351
1352 /// \returns Maximum number of SGPRs that meets the given number of waves per
1353 /// execution unit requirement supported by the subtarget.
1354 unsigned getMaxNumSGPRs(unsigned WavesPerEU, bool Addressable) const {
1355 return AMDGPU::IsaInfo::getMaxNumSGPRs(this, WavesPerEU, Addressable);
1356 }
1357
1358 /// \returns Reserved number of SGPRs. This is common
1359 /// utility function called by MachineFunction and
1360 /// Function variants of getReservedNumSGPRs.
1361 unsigned getBaseReservedNumSGPRs(const bool HasFlatScratch) const;
1362 /// \returns Reserved number of SGPRs for given machine function \p MF.
1363 unsigned getReservedNumSGPRs(const MachineFunction &MF) const;
1364
1365 /// \returns Reserved number of SGPRs for given function \p F.
1366 unsigned getReservedNumSGPRs(const Function &F) const;
1367
1368 /// \returns max num SGPRs. This is the common utility
1369 /// function called by MachineFunction and Function
1370 /// variants of getMaxNumSGPRs.
1371 unsigned getBaseMaxNumSGPRs(const Function &F,
1372 std::pair<unsigned, unsigned> WavesPerEU,
1373 unsigned PreloadedSGPRs,
1374 unsigned ReservedNumSGPRs) const;
1375
1376 /// \returns Maximum number of SGPRs that meets number of waves per execution
1377 /// unit requirement for function \p MF, or number of SGPRs explicitly
1378 /// requested using "amdgpu-num-sgpr" attribute attached to function \p MF.
1379 ///
1380 /// \returns Value that meets number of waves per execution unit requirement
1381 /// if explicitly requested value cannot be converted to integer, violates
1382 /// subtarget's specifications, or does not meet number of waves per execution
1383 /// unit requirement.
1384 unsigned getMaxNumSGPRs(const MachineFunction &MF) const;
1385
1386 /// \returns Maximum number of SGPRs that meets number of waves per execution
1387 /// unit requirement for function \p F, or number of SGPRs explicitly
1388 /// requested using "amdgpu-num-sgpr" attribute attached to function \p F.
1389 ///
1390 /// \returns Value that meets number of waves per execution unit requirement
1391 /// if explicitly requested value cannot be converted to integer, violates
1392 /// subtarget's specifications, or does not meet number of waves per execution
1393 /// unit requirement.
1394 unsigned getMaxNumSGPRs(const Function &F) const;
1395
1396 /// \returns VGPR allocation granularity supported by the subtarget.
1397 unsigned getVGPRAllocGranule() const {
1399 }
1400
1401 /// \returns VGPR encoding granularity supported by the subtarget.
1402 unsigned getVGPREncodingGranule() const {
1404 }
1405
1406 /// \returns Total number of VGPRs supported by the subtarget.
1407 unsigned getTotalNumVGPRs() const {
1409 }
1410
1411 /// \returns Addressable number of architectural VGPRs supported by the
1412 /// subtarget.
1415 }
1416
1417 /// \returns Addressable number of VGPRs supported by the subtarget.
1418 unsigned getAddressableNumVGPRs() const {
1420 }
1421
1422 /// \returns the minimum number of VGPRs that will prevent achieving more than
1423 /// the specified number of waves \p WavesPerEU.
1424 unsigned getMinNumVGPRs(unsigned WavesPerEU) const {
1425 return AMDGPU::IsaInfo::getMinNumVGPRs(this, WavesPerEU);
1426 }
1427
1428 /// \returns the maximum number of VGPRs that can be used and still achieved
1429 /// at least the specified number of waves \p WavesPerEU.
1430 unsigned getMaxNumVGPRs(unsigned WavesPerEU) const {
1431 return AMDGPU::IsaInfo::getMaxNumVGPRs(this, WavesPerEU);
1432 }
1433
1434 /// \returns max num VGPRs. This is the common utility function
1435 /// called by MachineFunction and Function variants of getMaxNumVGPRs.
1436 unsigned getBaseMaxNumVGPRs(const Function &F,
1437 std::pair<unsigned, unsigned> WavesPerEU) const;
1438 /// \returns Maximum number of VGPRs that meets number of waves per execution
1439 /// unit requirement for function \p F, or number of VGPRs explicitly
1440 /// requested using "amdgpu-num-vgpr" attribute attached to function \p F.
1441 ///
1442 /// \returns Value that meets number of waves per execution unit requirement
1443 /// if explicitly requested value cannot be converted to integer, violates
1444 /// subtarget's specifications, or does not meet number of waves per execution
1445 /// unit requirement.
1446 unsigned getMaxNumVGPRs(const Function &F) const;
1447
1448 unsigned getMaxNumAGPRs(const Function &F) const {
1449 return getMaxNumVGPRs(F);
1450 }
1451
1452 /// \returns Maximum number of VGPRs that meets number of waves per execution
1453 /// unit requirement for function \p MF, or number of VGPRs explicitly
1454 /// requested using "amdgpu-num-vgpr" attribute attached to function \p MF.
1455 ///
1456 /// \returns Value that meets number of waves per execution unit requirement
1457 /// if explicitly requested value cannot be converted to integer, violates
1458 /// subtarget's specifications, or does not meet number of waves per execution
1459 /// unit requirement.
1460 unsigned getMaxNumVGPRs(const MachineFunction &MF) const;
1461
1462 void getPostRAMutations(
1463 std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations)
1464 const override;
1465
1466 std::unique_ptr<ScheduleDAGMutation>
1468
1469 bool isWave32() const {
1470 return getWavefrontSize() == 32;
1471 }
1472
1473 bool isWave64() const {
1474 return getWavefrontSize() == 64;
1475 }
1476
1478 return getRegisterInfo()->getBoolRC();
1479 }
1480
1481 /// \returns Maximum number of work groups per compute unit supported by the
1482 /// subtarget and limited by given \p FlatWorkGroupSize.
1483 unsigned getMaxWorkGroupsPerCU(unsigned FlatWorkGroupSize) const override {
1484 return AMDGPU::IsaInfo::getMaxWorkGroupsPerCU(this, FlatWorkGroupSize);
1485 }
1486
1487 /// \returns Minimum flat work group size supported by the subtarget.
1488 unsigned getMinFlatWorkGroupSize() const override {
1490 }
1491
1492 /// \returns Maximum flat work group size supported by the subtarget.
1493 unsigned getMaxFlatWorkGroupSize() const override {
1495 }
1496
1497 /// \returns Number of waves per execution unit required to support the given
1498 /// \p FlatWorkGroupSize.
1499 unsigned
1500 getWavesPerEUForWorkGroup(unsigned FlatWorkGroupSize) const override {
1501 return AMDGPU::IsaInfo::getWavesPerEUForWorkGroup(this, FlatWorkGroupSize);
1502 }
1503
1504 /// \returns Minimum number of waves per execution unit supported by the
1505 /// subtarget.
1506 unsigned getMinWavesPerEU() const override {
1508 }
1509
1510 void adjustSchedDependency(SUnit *Def, int DefOpIdx, SUnit *Use, int UseOpIdx,
1511 SDep &Dep,
1512 const TargetSchedModel *SchedModel) const override;
1513
1514 // \returns true if it's beneficial on this subtarget for the scheduler to
1515 // cluster stores as well as loads.
1516 bool shouldClusterStores() const { return getGeneration() >= GFX11; }
1517
1518 // \returns the number of address arguments from which to enable MIMG NSA
1519 // on supported architectures.
1520 unsigned getNSAThreshold(const MachineFunction &MF) const;
1521
1522 // \returns true if the subtarget has a hazard requiring an "s_nop 0"
1523 // instruction before "s_sendmsg sendmsg(MSG_DEALLOC_VGPRS)".
1525 // Currently all targets that support the dealloc VGPRs message also require
1526 // the nop.
1527 return true;
1528 }
1529};
1530
1532public:
1533 bool hasImplicitBufferPtr() const { return ImplicitBufferPtr; }
1534
1535 bool hasPrivateSegmentBuffer() const { return PrivateSegmentBuffer; }
1536
1537 bool hasDispatchPtr() const { return DispatchPtr; }
1538
1539 bool hasQueuePtr() const { return QueuePtr; }
1540
1541 bool hasKernargSegmentPtr() const { return KernargSegmentPtr; }
1542
1543 bool hasDispatchID() const { return DispatchID; }
1544
1545 bool hasFlatScratchInit() const { return FlatScratchInit; }
1546
1547 unsigned getNumKernargPreloadSGPRs() const { return NumKernargPreloadSGPRs; }
1548
1549 unsigned getNumUsedUserSGPRs() const { return NumUsedUserSGPRs; }
1550
1551 unsigned getNumFreeUserSGPRs();
1552
1553 void allocKernargPreloadSGPRs(unsigned NumSGPRs);
1554
1555 enum UserSGPRID : unsigned {
1565
1566 // Returns the size in number of SGPRs for preload user SGPR field.
1568 switch (ID) {
1570 return 2;
1572 return 4;
1573 case DispatchPtrID:
1574 return 2;
1575 case QueuePtrID:
1576 return 2;
1578 return 2;
1579 case DispatchIdID:
1580 return 2;
1581 case FlatScratchInitID:
1582 return 2;
1584 return 1;
1585 }
1586 llvm_unreachable("Unknown UserSGPRID.");
1587 }
1588
1589 GCNUserSGPRUsageInfo(const Function &F, const GCNSubtarget &ST);
1590
1591private:
1592 const GCNSubtarget &ST;
1593
1594 // Private memory buffer
1595 // Compute directly in sgpr[0:1]
1596 // Other shaders indirect 64-bits at sgpr[0:1]
1597 bool ImplicitBufferPtr = false;
1598
1599 bool PrivateSegmentBuffer = false;
1600
1601 bool DispatchPtr = false;
1602
1603 bool QueuePtr = false;
1604
1605 bool KernargSegmentPtr = false;
1606
1607 bool DispatchID = false;
1608
1609 bool FlatScratchInit = false;
1610
1611 unsigned NumKernargPreloadSGPRs = 0;
1612
1613 unsigned NumUsedUserSGPRs = 0;
1614};
1615
1616} // end namespace llvm
1617
1618#endif // LLVM_LIB_TARGET_AMDGPU_GCNSUBTARGET_H
This file describes how to lower LLVM calls to machine code calls.
This file declares the targeting of the RegisterBankInfo class for AMDGPU.
Base class for AMDGPU specific classes of TargetSubtarget.
uint64_t Size
const HexagonInstrInfo * TII
#define F(x, y, z)
Definition: MD5.cpp:55
const char LLVMTargetMachineRef TM
SI DAG Lowering interface definition.
Interface definition for SIInstrInfo.
unsigned getWavefrontSizeLog2() const
unsigned getMaxWavesPerEU() const
unsigned getWavefrontSize() const
bool hasPrefetch() const
Definition: GCNSubtarget.h:895
bool hasFlat() const
Definition: GCNSubtarget.h:376
bool hasD16Images() const
Definition: GCNSubtarget.h:690
InstrItineraryData InstrItins
Definition: GCNSubtarget.h:64
bool useVGPRIndexMode() const
bool hasAtomicDsPkAdd16Insts() const
Definition: GCNSubtarget.h:823
bool hasSDWAOmod() const
Definition: GCNSubtarget.h:739
bool HasLdsBranchVmemWARHazard
Definition: GCNSubtarget.h:219
bool partialVCCWritesUpdateVCCZ() const
Writes to VCC_LO/VCC_HI update the VCCZ flag.
Definition: GCNSubtarget.h:479
bool hasSwap() const
Definition: GCNSubtarget.h:434
bool hasPkFmacF16Inst() const
Definition: GCNSubtarget.h:819
bool hasDot2Insts() const
Definition: GCNSubtarget.h:769
bool hasD16LoadStore() const
Definition: GCNSubtarget.h:682
bool hasMergedShaders() const
bool hasA16() const
bool hasSDWAScalar() const
Definition: GCNSubtarget.h:743
bool hasRrWGMode() const
bool supportsBackOffBarrier() const
Definition: GCNSubtarget.h:560
bool hasScalarCompareEq64() const
Definition: GCNSubtarget.h:954
bool has1_5xVGPRs() const
int getLDSBankCount() const
Definition: GCNSubtarget.h:331
bool hasOnlyRevVALUShifts() const
Definition: GCNSubtarget.h:382
bool hasImageStoreD16Bug() const
bool hasNonNSAEncoding() const
bool hasUsableDivScaleConditionOutput() const
Condition output from div_scale is usable.
Definition: GCNSubtarget.h:468
void mirFileLoaded(MachineFunction &MF) const override
bool hasUsableDSOffset() const
True if the offset field of DS instructions works as expected.
Definition: GCNSubtarget.h:459
bool loadStoreOptEnabled() const
bool enableSubRegLiveness() const override
Definition: GCNSubtarget.h:916
bool hasDPPWavefrontShifts() const
Definition: GCNSubtarget.h:985
unsigned getSGPRAllocGranule() const
bool hasLdsAtomicAddF64() const
Definition: GCNSubtarget.h:668
bool hasFlatLgkmVMemCountInOrder() const
Definition: GCNSubtarget.h:678
bool flatScratchIsPointer() const
bool hasSDWAMac() const
Definition: GCNSubtarget.h:751
bool hasFP8ConversionInsts() const
Definition: GCNSubtarget.h:817
bool hasShift64HighRegBug() const
bool hasDot7Insts() const
Definition: GCNSubtarget.h:789
bool hasApertureRegs() const
Definition: GCNSubtarget.h:588
unsigned MaxPrivateElementSize
Definition: GCNSubtarget.h:66
bool unsafeDSOffsetFoldingEnabled() const
Definition: GCNSubtarget.h:463
bool hasFPAtomicToDenormModeHazard() const
unsigned getAddressableNumArchVGPRs() const
bool hasFlatInstOffsets() const
Definition: GCNSubtarget.h:618
bool vmemWriteNeedsExpWaitcnt() const
Definition: GCNSubtarget.h:887
bool shouldClusterStores() const
unsigned getMinNumSGPRs(unsigned WavesPerEU) const
unsigned getSGPREncodingGranule() const
void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
bool hasLdsBranchVmemWARHazard() const
bool hasDefaultComponentZero() const
Definition: GCNSubtarget.h:849
bool hasGetWaveIdInst() const
Definition: GCNSubtarget.h:863
bool hasCompressedExport() const
Return true if the target's EXP instruction has the COMPR flag, which affects the meaning of the EN (...
bool hasGFX90AInsts() const
bool hasDstSelForwardingHazard() const
void setScalarizeGlobalBehavior(bool b)
Definition: GCNSubtarget.h:920
unsigned computeOccupancy(const Function &F, unsigned LDSSize=0, unsigned NumSGPRs=0, unsigned NumVGPRs=0) const
Return occupancy for the given function.
bool hasDLInsts() const
Definition: GCNSubtarget.h:759
bool hasExtendedImageInsts() const
bool hasBCNT(unsigned Size) const
Definition: GCNSubtarget.h:402
bool hasMAIInsts() const
Definition: GCNSubtarget.h:809
bool hasFlatScratchInsts() const
Definition: GCNSubtarget.h:626
unsigned getBaseMaxNumVGPRs(const Function &F, std::pair< unsigned, unsigned > WavesPerEU) const
bool hasMultiDwordFlatScratchAddressing() const
Definition: GCNSubtarget.h:670
bool hasArchitectedSGPRs() const
bool hasHWFP64() const
Definition: GCNSubtarget.h:360
bool hasDenormModeInst() const
Definition: GCNSubtarget.h:518
bool hasPrivEnabledTrap2NopBug() const
bool hasMFMAInlineLiteralBug() const
unsigned getTotalNumVGPRs() const
unsigned getMinWavesPerEU() const override
bool hasSMemTimeInst() const
Definition: GCNSubtarget.h:867
bool hasUnalignedDSAccessEnabled() const
Definition: GCNSubtarget.h:576
bool hasNegativeScratchOffsetBug() const
const SIInstrInfo * getInstrInfo() const override
Definition: GCNSubtarget.h:257
unsigned getMaxWorkGroupsPerCU(unsigned FlatWorkGroupSize) const override
bool AutoWaitcntBeforeBarrier
Definition: GCNSubtarget.h:75
bool hasDot1Insts() const
Definition: GCNSubtarget.h:765
bool hasDot3Insts() const
Definition: GCNSubtarget.h:773
unsigned getConstantBusLimit(unsigned Opcode) const
bool hasMADIntraFwdBug() const
bool hasVALUMaskWriteHazard() const
const InlineAsmLowering * getInlineAsmLowering() const override
Definition: GCNSubtarget.h:277
bool HasVGPRSingleUseHintInsts
Definition: GCNSubtarget.h:210
bool hasAutoWaitcntBeforeBarrier() const
Definition: GCNSubtarget.h:554
bool hasNSAClauseBug() const
bool hasAtomicFaddRtnInsts() const
Definition: GCNSubtarget.h:831
unsigned getTotalNumSGPRs() const
const InstrItineraryData * getInstrItineraryData() const override
Definition: GCNSubtarget.h:302
void adjustSchedDependency(SUnit *Def, int DefOpIdx, SUnit *Use, int UseOpIdx, SDep &Dep, const TargetSchedModel *SchedModel) const override
bool HasShaderCyclesHiLoRegisters
Definition: GCNSubtarget.h:188
unsigned getMaxLocalMemSizeWithWaveCount(unsigned WaveCount, const Function &) const
Return the amount of LDS that can be used that will not restrict the occupancy lower than WaveCount.
bool hasPkMovB32() const
bool needsAlignedVGPRs() const
Return if operations acting on VGPR tuples require even alignment.
bool hasGFX10_3Insts() const
Align getStackAlignment() const
Definition: GCNSubtarget.h:908
bool privateMemoryResourceIsRangeChecked() const
Definition: GCNSubtarget.h:544
bool hasScalarSubwordLoads() const
Definition: GCNSubtarget.h:446
bool hasDot11Insts() const
Definition: GCNSubtarget.h:805
bool enableFlatScratch() const
Definition: GCNSubtarget.h:643
bool hasUnalignedBufferAccess() const
Definition: GCNSubtarget.h:564
bool hasR128A16() const
bool hasOffset3fBug() const
bool hasDwordx3LoadStores() const
bool hasSignedScratchOffsets() const
bool HasPrivEnabledTrap2NopBug
Definition: GCNSubtarget.h:227
bool hasGlobalAddTidInsts() const
Definition: GCNSubtarget.h:648
bool hasSGPRInitBug() const
bool hasFlatScrRegister() const
Definition: GCNSubtarget.h:614
bool hasGetPCZeroExtension() const
bool hasPermLane64() const
Definition: GCNSubtarget.h:975
bool requiresNopBeforeDeallocVGPRs() const
bool supportsGetDoorbellID() const
Definition: GCNSubtarget.h:452
bool hasVcmpxExecWARHazard() const
bool isTgSplitEnabled() const
Definition: GCNSubtarget.h:600
bool hasFlatAtomicFaddF32Inst() const
Definition: GCNSubtarget.h:847
bool hasKernargPreload() const
bool hasFP8Insts() const
Definition: GCNSubtarget.h:813
unsigned getMaxNumAGPRs(const Function &F) const
unsigned getVGPRAllocGranule() const
bool hasReadM0MovRelInterpHazard() const
const SIRegisterInfo * getRegisterInfo() const override
Definition: GCNSubtarget.h:269
unsigned getMaxNumVGPRs(unsigned WavesPerEU) const
bool hasDOTOpSelHazard() const
bool hasLdsWaitVMSRC() const
bool hasMSAALoadDstSelBug() const
const TargetRegisterClass * getBoolRC() const
bool hasFmaakFmamkF32Insts() const
bool hasVscnt() const
Definition: GCNSubtarget.h:859
bool hasMad64_32() const
Definition: GCNSubtarget.h:735
InstructionSelector * getInstructionSelector() const override
Definition: GCNSubtarget.h:281
unsigned getVGPREncodingGranule() const
bool NegativeUnalignedScratchOffsetBug
Definition: GCNSubtarget.h:117
bool hasHardClauses() const
bool useDS128() const
Definition: GCNSubtarget.h:528
bool hasExtendedWaitCounts() const
bool hasLDSMisalignedBug() const
bool d16PreservesUnusedBits() const
Definition: GCNSubtarget.h:686
bool hasFmacF64Inst() const
Definition: GCNSubtarget.h:763
bool hasInstPrefetch() const
Definition: GCNSubtarget.h:891
unsigned maxHardClauseLength() const
bool isMesaGfxShader(const Function &F) const
Definition: GCNSubtarget.h:731
bool hasVcmpxPermlaneHazard() const
bool hasUserSGPRInit16Bug() const
bool hasExportInsts() const
Definition: GCNSubtarget.h:659
bool hasDPP() const
Definition: GCNSubtarget.h:977
bool hasVINTERPEncoding() const
Definition: GCNSubtarget.h:663
const AMDGPURegisterBankInfo * getRegBankInfo() const override
Definition: GCNSubtarget.h:289
bool hasLegacyGeometry() const
unsigned getMinNumVGPRs(unsigned WavesPerEU) const
TrapHandlerAbi getTrapHandlerAbi() const
Definition: GCNSubtarget.h:448
bool isCuModeEnabled() const
Definition: GCNSubtarget.h:604
bool hasScalarAtomics() const
Definition: GCNSubtarget.h:964
const SIFrameLowering * getFrameLowering() const override
Definition: GCNSubtarget.h:261
bool hasUnalignedScratchAccess() const
Definition: GCNSubtarget.h:580
const SelectionDAGTargetInfo * getSelectionDAGInfo() const override
Definition: GCNSubtarget.h:298
bool zeroesHigh16BitsOfDest(unsigned Opcode) const
Returns if the result of this instruction with a 16-bit result returned in a 32-bit register implicit...
bool hasSDWAOutModsVOPC() const
Definition: GCNSubtarget.h:755
unsigned getBaseMaxNumSGPRs(const Function &F, std::pair< unsigned, unsigned > WavesPerEU, unsigned PreloadedSGPRs, unsigned ReservedNumSGPRs) const
const AMDGPU::IsaInfo::AMDGPUTargetID & getTargetID() const
Definition: GCNSubtarget.h:293
bool hasAtomicCSubNoRtnInsts() const
bool hasScalarFlatScratchInsts() const
Definition: GCNSubtarget.h:639
GCNSubtarget & initializeSubtargetDependencies(const Triple &TT, StringRef GPU, StringRef FS)
bool has12DWordStoreHazard() const
bool hasVALUPartialForwardingHazard() const
bool dumpCode() const
Definition: GCNSubtarget.h:504
bool hasNoDataDepHazard() const
Definition: GCNSubtarget.h:883
bool hasUnalignedDSAccess() const
Definition: GCNSubtarget.h:572
bool hasRestrictedSOffset() const
bool hasMin3Max3_16() const
Definition: GCNSubtarget.h:418
bool hasIntClamp() const
Definition: GCNSubtarget.h:348
bool hasGFX10_AEncoding() const
bool hasFlatSegmentOffsetBug() const
Definition: GCNSubtarget.h:674
unsigned getSetRegWaitStates() const
Number of hazard wait states for s_setreg_b32/s_setreg_imm32_b32.
Definition: GCNSubtarget.h:500
const SITargetLowering * getTargetLowering() const override
Definition: GCNSubtarget.h:265
bool hasPackedFP32Ops() const
Definition: GCNSubtarget.h:999
bool hasTransForwardingHazard() const
bool hasDot6Insts() const
Definition: GCNSubtarget.h:785
bool hasGFX940Insts() const
bool hasLshlAddB64() const
bool hasFullRate64Ops() const
Definition: GCNSubtarget.h:368
bool hasScalarStores() const
Definition: GCNSubtarget.h:960
bool isTrapHandlerEnabled() const
Definition: GCNSubtarget.h:592
bool enableMachineScheduler() const override
Definition: GCNSubtarget.h:910
bool hasLDSFPAtomicAddF64() const
Definition: GCNSubtarget.h:969
bool HasAtomicFlatPkAdd16Insts
Definition: GCNSubtarget.h:163
bool hasFlatGlobalInsts() const
Definition: GCNSubtarget.h:622
bool hasDX10ClampMode() const
unsigned getNSAThreshold(const MachineFunction &MF) const
bool getScalarizeGlobalBehavior() const
Definition: GCNSubtarget.h:921
bool hasReadM0LdsDmaHazard() const
bool hasScalarSMulU64() const
Definition: GCNSubtarget.h:724
unsigned getKnownHighZeroBitsForFrameIndex() const
Return the number of high bits known to be zero for a frame index.
Definition: GCNSubtarget.h:327
bool hasShaderCyclesHiLoRegisters() const
Definition: GCNSubtarget.h:875
bool hasSDWASdst() const
Definition: GCNSubtarget.h:747
bool HasDefaultComponentBroadcast
Definition: GCNSubtarget.h:172
bool hasScalarPackInsts() const
Definition: GCNSubtarget.h:438
bool hasFFBL() const
Definition: GCNSubtarget.h:406
bool hasNSAEncoding() const
bool hasSMemRealTime() const
Definition: GCNSubtarget.h:940
bool hasFlatAddressSpace() const
Definition: GCNSubtarget.h:610
bool hasDPPBroadcasts() const
Definition: GCNSubtarget.h:981
bool usePRTStrictNull() const
Definition: GCNSubtarget.h:550
bool hasMovB64() const
bool hasInstFwdPrefetchBug() const
bool hasMed3_16() const
Definition: GCNSubtarget.h:414
unsigned getReservedNumSGPRs(const MachineFunction &MF) const
bool hasMovrel() const
Definition: GCNSubtarget.h:944
bool hasNullExportTarget() const
Return true if the target's EXP instruction supports the NULL export target.
bool hasAtomicFlatPkAdd16Insts() const
Definition: GCNSubtarget.h:825
bool hasBFI() const
Definition: GCNSubtarget.h:394
bool ldsRequiresM0Init() const
Return if most LDS instructions have an m0 use that require m0 to be initialized.
Definition: GCNSubtarget.h:696
bool HasSMEMtoVectorWriteHazard
Definition: GCNSubtarget.h:216
bool hasSMEMtoVectorWriteHazard() const
bool useAA() const override
bool isWave32() const
bool hasVGPRIndexMode() const
Definition: GCNSubtarget.h:948
bool HasAtomicBufferGlobalPkAddF16Insts
Definition: GCNSubtarget.h:167
bool hasUnalignedBufferAccessEnabled() const
Definition: GCNSubtarget.h:568
unsigned getOccupancyWithNumVGPRs(unsigned VGPRs) const
Return the maximum number of waves per SIMD for kernels using VGPRs VGPRs.
unsigned getMaxPrivateElementSize(bool ForBufferRSrc=false) const
Definition: GCNSubtarget.h:335
unsigned getMinFlatWorkGroupSize() const override
bool hasImageInsts() const
bool hasImageGather4D16Bug() const
bool hasFMA() const
Definition: GCNSubtarget.h:430
bool hasDot10Insts() const
Definition: GCNSubtarget.h:801
bool hasSPackHL() const
Return true if the target has the S_PACK_HL_B32_B16 instruction.
bool hasVMEMtoScalarWriteHazard() const
bool hasCvtFP8VOP1Bug() const
bool supportsMinMaxDenormModes() const
Definition: GCNSubtarget.h:513
bool hasNegativeUnalignedScratchOffsetBug() const
bool hasFFBH() const
Definition: GCNSubtarget.h:410
bool hasFlatScratchSVSMode() const
Definition: GCNSubtarget.h:637
bool supportsWGP() const
Definition: GCNSubtarget.h:346
bool hasG16() const
bool hasHalfRate64Ops() const
Definition: GCNSubtarget.h:364
bool hasAtomicFaddInsts() const
Definition: GCNSubtarget.h:827
bool HasAtomicBufferGlobalPkAddF16NoRtnInsts
Definition: GCNSubtarget.h:166
bool hasNSAtoVMEMBug() const
bool HasArchitectedFlatScratch
Definition: GCNSubtarget.h:196
unsigned getNSAMaxSize(bool HasSampler=false) const
bool hasAtomicBufferGlobalPkAddF16NoRtnInsts() const
Definition: GCNSubtarget.h:835
bool hasMIMG_R128() const
Definition: GCNSubtarget.h:356
std::unique_ptr< ScheduleDAGMutation > createFillMFMAShadowMutation(const TargetInstrInfo *TII) const
unsigned getOccupancyWithNumSGPRs(unsigned SGPRs) const
Return the maximum number of waves per SIMD for kernels using SGPRs SGPRs.
bool hasVOP3DPP() const
unsigned getMaxFlatWorkGroupSize() const override
bool hasDPP8() const
Definition: GCNSubtarget.h:989
bool hasDot5Insts() const
Definition: GCNSubtarget.h:781
unsigned getMaxNumUserSGPRs() const
Definition: GCNSubtarget.h:936
bool hasAtomicFaddNoRtnInsts() const
Definition: GCNSubtarget.h:833
unsigned MaxHardClauseLength
The maximum number of instructions that may be placed within an S_CLAUSE, which is one greater than t...
Definition: GCNSubtarget.h:176
bool hasPermLaneX16() const
Definition: GCNSubtarget.h:972
bool hasFlatScratchSVSSwizzleBug() const
bool hasIEEEMode() const
bool hasScalarDwordx3Loads() const
Definition: GCNSubtarget.h:958
bool hasVDecCoExecHazard() const
bool hasLDSFPAtomicAddF32() const
Definition: GCNSubtarget.h:968
unsigned getWavesPerEUForWorkGroup(unsigned FlatWorkGroupSize) const override
bool hasBFM() const
Definition: GCNSubtarget.h:398
bool haveRoundOpsF64() const
Have v_trunc_f64, v_ceil_f64, v_rndne_f64.
Definition: GCNSubtarget.h:538
bool hasDelayAlu() const
Return true if the target has the S_DELAY_ALU instruction.
bool hasReadM0SendMsgHazard() const
bool hasDot8Insts() const
Definition: GCNSubtarget.h:793
bool hasScalarMulHiInsts() const
Definition: GCNSubtarget.h:442
bool hasSCmpK() const
Definition: GCNSubtarget.h:898
bool hasPseudoScalarTrans() const
const LegalizerInfo * getLegalizerInfo() const override
Definition: GCNSubtarget.h:285
bool hasDS96AndDS128() const
Definition: GCNSubtarget.h:533
bool hasGWS() const
bool hasReadM0LdsDirectHazard() const
bool useFlatForGlobal() const
Definition: GCNSubtarget.h:522
static bool hasHalfRate64Ops(const TargetSubtargetInfo &STI)
bool hasVOPDInsts() const
bool hasGFX10_BEncoding() const
SelectionDAGTargetInfo TSInfo
Definition: GCNSubtarget.h:239
Generation getGeneration() const
Definition: GCNSubtarget.h:308
unsigned getMaxNumSGPRs(unsigned WavesPerEU, bool Addressable) const
bool hasForceStoreSC0SC1() const
bool hasVOP3Literal() const
Definition: GCNSubtarget.h:879
bool hasAtomicBufferGlobalPkAddF16Insts() const
Definition: GCNSubtarget.h:839
bool hasNoSdstCMPX() const
Definition: GCNSubtarget.h:855
bool hasBufferFlatGlobalAtomicsF64() const
Definition: GCNSubtarget.h:657
unsigned getAddressableNumVGPRs() const
bool isXNACKEnabled() const
Definition: GCNSubtarget.h:596
bool hasScalarAddSub64() const
Definition: GCNSubtarget.h:722
bool hasSplitBarriers() const
bool hasUnpackedD16VMem() const
Definition: GCNSubtarget.h:726
bool enableEarlyIfConversion() const override
Definition: GCNSubtarget.h:927
bool hasSMRDReadVALUDefHazard() const
A read of an SGPR by SMRD instruction requires 4 wait states when the SGPR was written by a VALU inst...
Definition: GCNSubtarget.h:485
bool hasRFEHazards() const
Definition: GCNSubtarget.h:495
bool hasVMEMReadSGPRVALUDefHazard() const
A read of an SGPR by a VMEM instruction requires 5 wait states when the SGPR was written by a VALU In...
Definition: GCNSubtarget.h:491
bool hasFlatScratchSTMode() const
Definition: GCNSubtarget.h:633
unsigned getBaseReservedNumSGPRs(const bool HasFlatScratch) const
bool hasGWSSemaReleaseAll() const
Definition: GCNSubtarget.h:710
bool hasDPALU_DPP() const
Definition: GCNSubtarget.h:993
bool enableSIScheduler() const
bool hasAtomicGlobalPkAddBF16Inst() const
Definition: GCNSubtarget.h:843
bool hasAddr64() const
Definition: GCNSubtarget.h:372
bool HasVMEMtoScalarWriteHazard
Definition: GCNSubtarget.h:215
bool HasAtomicGlobalPkAddBF16Inst
Definition: GCNSubtarget.h:169
bool hasUnalignedAccessMode() const
Definition: GCNSubtarget.h:584
unsigned getAddressableNumSGPRs() const
bool hasReadVCCZBug() const
Extra wait hazard is needed in some cases before s_cbranch_vccnz/s_cbranch_vccz.
Definition: GCNSubtarget.h:474
bool isWave64() const
bool hasIEEEMinMax() const
bool hasFmaMixInsts() const
Definition: GCNSubtarget.h:422
bool hasCARRY() const
Definition: GCNSubtarget.h:426
bool hasPackedTID() const
bool hasFP64() const
Definition: GCNSubtarget.h:352
bool hasAddNoCarry() const
Definition: GCNSubtarget.h:718
bool hasVALUTransUseHazard() const
bool hasShaderCyclesRegister() const
Definition: GCNSubtarget.h:871
bool hasSALUFloatInsts() const
bool hasVGPRSingleUseHintInsts() const
bool EnableUnsafeDSOffsetFolding
Definition: GCNSubtarget.h:94
bool hasFractBug() const
Definition: GCNSubtarget.h:386
bool isPreciseMemoryEnabled() const
Definition: GCNSubtarget.h:608
void overrideSchedPolicy(MachineSchedPolicy &Policy, unsigned NumRegionInstrs) const override
bool hasDPPSrc1SGPR() const
Definition: GCNSubtarget.h:997
bool hasGDS() const
unsigned getMaxWaveScratchSize() const
Definition: GCNSubtarget.h:312
bool hasDot4Insts() const
Definition: GCNSubtarget.h:777
void getPostRAMutations(std::vector< std::unique_ptr< ScheduleDAGMutation > > &Mutations) const override
bool flatScratchIsArchitected() const
bool hasPartialNSAEncoding() const
void checkSubtargetFeatures(const Function &F) const
Diagnose inconsistent subtarget features before attempting to codegen function F.
~GCNSubtarget() override
bool hasDot9Insts() const
Definition: GCNSubtarget.h:797
bool hasAtomicCSub() const
Definition: GCNSubtarget.h:652
AMDGPU::IsaInfo::AMDGPUTargetID TargetID
Definition: GCNSubtarget.h:62
bool hasDefaultComponentBroadcast() const
Definition: GCNSubtarget.h:851
bool requiresCodeObjectV6() const
const CallLowering * getCallLowering() const override
Definition: GCNSubtarget.h:273
bool hasBFE() const
Definition: GCNSubtarget.h:390
bool hasLdsDirect() const
bool hasGWSAutoReplay() const
Definition: GCNSubtarget.h:705
static unsigned getNumUserSGPRForField(UserSGPRID ID)
bool hasKernargSegmentPtr() const
void allocKernargPreloadSGPRs(unsigned NumSGPRs)
bool hasPrivateSegmentBuffer() const
bool hasImplicitBufferPtr() const
unsigned getNumKernargPreloadSGPRs() const
unsigned getNumUsedUserSGPRs() const
Itinerary data supplied by a subtarget to be used by a target.
Scheduling dependency.
Definition: ScheduleDAG.h:49
const SIRegisterInfo & getRegisterInfo() const
Definition: SIInstrInfo.h:222
const TargetRegisterClass * getBoolRC() const
Scheduling unit. This is a node in the scheduling DAG.
Definition: ScheduleDAG.h:242
Targets can subclass this to parameterize the SelectionDAG lowering and instruction selection process...
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
TargetInstrInfo - Interface to description of machine instruction set.
Provide an instruction scheduling machine model to CodeGen passes.
TargetSubtargetInfo - Generic base class for all target subtargets.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
A Use represents the edge between a Value definition and its users.
Definition: Use.h:43
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned getVGPREncodingGranule(const MCSubtargetInfo *STI, std::optional< bool > EnableWavefrontSize32)
unsigned getTotalNumVGPRs(const MCSubtargetInfo *STI)
unsigned getWavesPerEUForWorkGroup(const MCSubtargetInfo *STI, unsigned FlatWorkGroupSize)
unsigned getMaxWorkGroupsPerCU(const MCSubtargetInfo *STI, unsigned FlatWorkGroupSize)
unsigned getMaxFlatWorkGroupSize(const MCSubtargetInfo *STI)
unsigned getSGPREncodingGranule(const MCSubtargetInfo *STI)
unsigned getMinNumVGPRs(const MCSubtargetInfo *STI, unsigned WavesPerEU)
unsigned getAddressableNumSGPRs(const MCSubtargetInfo *STI)
unsigned getAddressableNumVGPRs(const MCSubtargetInfo *STI)
unsigned getMinNumSGPRs(const MCSubtargetInfo *STI, unsigned WavesPerEU)
unsigned getMinFlatWorkGroupSize(const MCSubtargetInfo *STI)
unsigned getMaxNumSGPRs(const MCSubtargetInfo *STI, unsigned WavesPerEU, bool Addressable)
unsigned getMinWavesPerEU(const MCSubtargetInfo *STI)
unsigned getSGPRAllocGranule(const MCSubtargetInfo *STI)
unsigned getMaxNumVGPRs(const MCSubtargetInfo *STI, unsigned WavesPerEU)
unsigned getVGPRAllocGranule(const MCSubtargetInfo *STI, std::optional< bool > EnableWavefrontSize32)
unsigned getAddressableNumArchVGPRs(const MCSubtargetInfo *STI)
unsigned getTotalNumSGPRs(const MCSubtargetInfo *STI)
unsigned getMaxNumUserSGPRs(const MCSubtargetInfo &STI)
unsigned getNSAMaxSize(const MCSubtargetInfo &STI, bool HasSampler)
bool isShader(CallingConv::ID cc)
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
Definition: bit.h:281
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
Define a generic scheduling policy for targets that don't provide their own MachineSchedStrategy.