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 "AMDGPUSubtarget.h"
19 #include "SIFrameLowering.h"
20 #include "SIISelLowering.h"
21 #include "SIInstrInfo.h"
22 #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
23 
24 namespace llvm {
25 
26 class MCInst;
27 class MCInstrInfo;
28 
29 } // namespace llvm
30 
31 #define GET_SUBTARGETINFO_HEADER
32 #include "AMDGPUGenSubtargetInfo.inc"
33 
34 namespace llvm {
35 
36 class GCNTargetMachine;
37 
38 class GCNSubtarget final : public AMDGPUGenSubtargetInfo,
39                            public AMDGPUSubtarget {
40 
41   using AMDGPUSubtarget::getMaxWavesPerEU;
42 
43 public:
44   // Following 2 enums are documented at:
45   //   - https://llvm.org/docs/AMDGPUUsage.html#trap-handler-abi
46   enum class TrapHandlerAbi {
47     NONE   = 0x00,
48     AMDHSA = 0x01,
49   };
50 
51   enum class TrapID {
52     LLVMAMDHSATrap      = 0x02,
53     LLVMAMDHSADebugTrap = 0x03,
54   };
55 
56 private:
57   /// GlobalISel related APIs.
58   std::unique_ptr<AMDGPUCallLowering> CallLoweringInfo;
59   std::unique_ptr<InlineAsmLowering> InlineAsmLoweringInfo;
60   std::unique_ptr<InstructionSelector> InstSelector;
61   std::unique_ptr<LegalizerInfo> Legalizer;
62   std::unique_ptr<RegisterBankInfo> RegBankInfo;
63 
64 protected:
65   // Basic subtarget description.
66   Triple TargetTriple;
67   AMDGPU::IsaInfo::AMDGPUTargetID TargetID;
68   unsigned Gen;
69   InstrItineraryData InstrItins;
70   int LDSBankCount;
71   unsigned MaxPrivateElementSize;
72 
73   // Possibly statically set by tablegen, but may want to be overridden.
74   bool FastFMAF32;
75   bool FastDenormalF32;
76   bool HalfRate64Ops;
77   bool FullRate64Ops;
78 
79   // Dynamically set bits that enable features.
80   bool FlatForGlobal;
81   bool AutoWaitcntBeforeBarrier;
82   bool UnalignedScratchAccess;
83   bool UnalignedAccessMode;
84   bool HasApertureRegs;
85   bool SupportsXNACK;
86 
87   // This should not be used directly. 'TargetID' tracks the dynamic settings
88   // for XNACK.
89   bool EnableXNACK;
90 
91   bool EnableTgSplit;
92   bool EnableCuMode;
93   bool TrapHandler;
94 
95   // Used as options.
96   bool EnableLoadStoreOpt;
97   bool EnableUnsafeDSOffsetFolding;
98   bool EnableSIScheduler;
99   bool EnableDS128;
100   bool EnablePRTStrictNull;
101   bool DumpCode;
102 
103   // Subtarget statically properties set by tablegen
104   bool FP64;
105   bool FMA;
106   bool MIMG_R128;
107   bool IsGCN;
108   bool CIInsts;
109   bool GFX8Insts;
110   bool GFX9Insts;
111   bool GFX90AInsts;
112   bool GFX10Insts;
113   bool GFX10_3Insts;
114   bool GFX7GFX8GFX9Insts;
115   bool SGPRInitBug;
116   bool NegativeScratchOffsetBug;
117   bool NegativeUnalignedScratchOffsetBug;
118   bool HasSMemRealTime;
119   bool HasIntClamp;
120   bool HasFmaMixInsts;
121   bool HasMovrel;
122   bool HasVGPRIndexMode;
123   bool HasScalarStores;
124   bool HasScalarAtomics;
125   bool HasSDWAOmod;
126   bool HasSDWAScalar;
127   bool HasSDWASdst;
128   bool HasSDWAMac;
129   bool HasSDWAOutModsVOPC;
130   bool HasDPP;
131   bool HasDPP8;
132   bool Has64BitDPP;
133   bool HasPackedFP32Ops;
134   bool HasExtendedImageInsts;
135   bool HasR128A16;
136   bool HasGFX10A16;
137   bool HasG16;
138   bool HasNSAEncoding;
139   bool GFX10_BEncoding;
140   bool HasDLInsts;
141   bool HasDot1Insts;
142   bool HasDot2Insts;
143   bool HasDot3Insts;
144   bool HasDot4Insts;
145   bool HasDot5Insts;
146   bool HasDot6Insts;
147   bool HasDot7Insts;
148   bool HasMAIInsts;
149   bool HasPkFmacF16Inst;
150   bool HasAtomicFaddInsts;
151   bool SupportsSRAMECC;
152 
153   // This should not be used directly. 'TargetID' tracks the dynamic settings
154   // for SRAMECC.
155   bool EnableSRAMECC;
156 
157   bool HasNoSdstCMPX;
158   bool HasVscnt;
159   bool HasGetWaveIdInst;
160   bool HasSMemTimeInst;
161   bool HasShaderCyclesRegister;
162   bool HasRegisterBanking;
163   bool HasVOP3Literal;
164   bool HasNoDataDepHazard;
165   bool FlatAddressSpace;
166   bool FlatInstOffsets;
167   bool FlatGlobalInsts;
168   bool FlatScratchInsts;
169   bool ScalarFlatScratchInsts;
170   bool AddNoCarryInsts;
171   bool HasUnpackedD16VMem;
172   bool R600ALUInst;
173   bool CaymanISA;
174   bool CFALUBug;
175   bool LDSMisalignedBug;
176   bool HasMFMAInlineLiteralBug;
177   bool HasVertexCache;
178   short TexVTXClauseSize;
179   bool UnalignedBufferAccess;
180   bool UnalignedDSAccess;
181   bool HasPackedTID;
182   bool ScalarizeGlobal;
183 
184   bool HasVcmpxPermlaneHazard;
185   bool HasVMEMtoScalarWriteHazard;
186   bool HasSMEMtoVectorWriteHazard;
187   bool HasInstFwdPrefetchBug;
188   bool HasVcmpxExecWARHazard;
189   bool HasLdsBranchVmemWARHazard;
190   bool HasNSAtoVMEMBug;
191   bool HasNSAClauseBug;
192   bool HasOffset3fBug;
193   bool HasFlatSegmentOffsetBug;
194   bool HasImageStoreD16Bug;
195   bool HasImageGather4D16Bug;
196 
197   // Dummy feature to use for assembler in tablegen.
198   bool FeatureDisable;
199 
200   SelectionDAGTargetInfo TSInfo;
201 private:
202   SIInstrInfo InstrInfo;
203   SITargetLowering TLInfo;
204   SIFrameLowering FrameLowering;
205 
206 public:
207   // See COMPUTE_TMPRING_SIZE.WAVESIZE, 13-bit field in units of 256-dword.
208   static const unsigned MaxWaveScratchSize = (256 * 4) * ((1 << 13) - 1);
209 
210   GCNSubtarget(const Triple &TT, StringRef GPU, StringRef FS,
211                const GCNTargetMachine &TM);
212   ~GCNSubtarget() override;
213 
214   GCNSubtarget &initializeSubtargetDependencies(const Triple &TT,
215                                                    StringRef GPU, StringRef FS);
216 
217   const SIInstrInfo *getInstrInfo() const override {
218     return &InstrInfo;
219   }
220 
221   const SIFrameLowering *getFrameLowering() const override {
222     return &FrameLowering;
223   }
224 
225   const SITargetLowering *getTargetLowering() const override {
226     return &TLInfo;
227   }
228 
229   const SIRegisterInfo *getRegisterInfo() const override {
230     return &InstrInfo.getRegisterInfo();
231   }
232 
233   const CallLowering *getCallLowering() const override {
234     return CallLoweringInfo.get();
235   }
236 
237   const InlineAsmLowering *getInlineAsmLowering() const override {
238     return InlineAsmLoweringInfo.get();
239   }
240 
241   InstructionSelector *getInstructionSelector() const override {
242     return InstSelector.get();
243   }
244 
245   const LegalizerInfo *getLegalizerInfo() const override {
246     return Legalizer.get();
247   }
248 
249   const RegisterBankInfo *getRegBankInfo() const override {
250     return RegBankInfo.get();
251   }
252 
253   const AMDGPU::IsaInfo::AMDGPUTargetID &getTargetID() const {
254     return TargetID;
255   }
256 
257   // Nothing implemented, just prevent crashes on use.
258   const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
259     return &TSInfo;
260   }
261 
262   const InstrItineraryData *getInstrItineraryData() const override {
263     return &InstrItins;
264   }
265 
266   void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
267 
268   Generation getGeneration() const {
269     return (Generation)Gen;
270   }
271 
272   /// Return the number of high bits known to be zero fror a frame index.
273   unsigned getKnownHighZeroBitsForFrameIndex() const {
274     return countLeadingZeros(MaxWaveScratchSize) + getWavefrontSizeLog2();
275   }
276 
277   int getLDSBankCount() const {
278     return LDSBankCount;
279   }
280 
281   unsigned getMaxPrivateElementSize(bool ForBufferRSrc = false) const {
282     return (ForBufferRSrc || !enableFlatScratch()) ? MaxPrivateElementSize : 16;
283   }
284 
285   unsigned getConstantBusLimit(unsigned Opcode) const;
286 
287   bool hasIntClamp() const {
288     return HasIntClamp;
289   }
290 
291   bool hasFP64() const {
292     return FP64;
293   }
294 
295   bool hasMIMG_R128() const {
296     return MIMG_R128;
297   }
298 
299   bool hasHWFP64() const {
300     return FP64;
301   }
302 
303   bool hasFastFMAF32() const {
304     return FastFMAF32;
305   }
306 
307   bool hasHalfRate64Ops() const {
308     return HalfRate64Ops;
309   }
310 
311   bool hasFullRate64Ops() const {
312     return FullRate64Ops;
313   }
314 
315   bool hasAddr64() const {
316     return (getGeneration() < AMDGPUSubtarget::VOLCANIC_ISLANDS);
317   }
318 
319   bool hasFlat() const {
320     return (getGeneration() > AMDGPUSubtarget::SOUTHERN_ISLANDS);
321   }
322 
323   // Return true if the target only has the reverse operand versions of VALU
324   // shift instructions (e.g. v_lshrrev_b32, and no v_lshr_b32).
325   bool hasOnlyRevVALUShifts() const {
326     return getGeneration() >= VOLCANIC_ISLANDS;
327   }
328 
329   bool hasFractBug() const {
330     return getGeneration() == SOUTHERN_ISLANDS;
331   }
332 
333   bool hasBFE() const {
334     return true;
335   }
336 
337   bool hasBFI() const {
338     return true;
339   }
340 
341   bool hasBFM() const {
342     return hasBFE();
343   }
344 
345   bool hasBCNT(unsigned Size) const {
346     return true;
347   }
348 
349   bool hasFFBL() const {
350     return true;
351   }
352 
353   bool hasFFBH() const {
354     return true;
355   }
356 
357   bool hasMed3_16() const {
358     return getGeneration() >= AMDGPUSubtarget::GFX9;
359   }
360 
361   bool hasMin3Max3_16() const {
362     return getGeneration() >= AMDGPUSubtarget::GFX9;
363   }
364 
365   bool hasFmaMixInsts() const {
366     return HasFmaMixInsts;
367   }
368 
369   bool hasCARRY() const {
370     return true;
371   }
372 
373   bool hasFMA() const {
374     return FMA;
375   }
376 
377   bool hasSwap() const {
378     return GFX9Insts;
379   }
380 
381   bool hasScalarPackInsts() const {
382     return GFX9Insts;
383   }
384 
385   bool hasScalarMulHiInsts() const {
386     return GFX9Insts;
387   }
388 
389   TrapHandlerAbi getTrapHandlerAbi() const {
390     return isAmdHsaOS() ? TrapHandlerAbi::AMDHSA : TrapHandlerAbi::NONE;
391   }
392 
393   bool supportsGetDoorbellID() const {
394     // The S_GETREG DOORBELL_ID is supported by all GFX9 onward targets.
395     return getGeneration() >= GFX9;
396   }
397 
398   /// True if the offset field of DS instructions works as expected. On SI, the
399   /// offset uses a 16-bit adder and does not always wrap properly.
400   bool hasUsableDSOffset() const {
401     return getGeneration() >= SEA_ISLANDS;
402   }
403 
404   bool unsafeDSOffsetFoldingEnabled() const {
405     return EnableUnsafeDSOffsetFolding;
406   }
407 
408   /// Condition output from div_scale is usable.
409   bool hasUsableDivScaleConditionOutput() const {
410     return getGeneration() != SOUTHERN_ISLANDS;
411   }
412 
413   /// Extra wait hazard is needed in some cases before
414   /// s_cbranch_vccnz/s_cbranch_vccz.
415   bool hasReadVCCZBug() const {
416     return getGeneration() <= SEA_ISLANDS;
417   }
418 
419   /// Writes to VCC_LO/VCC_HI update the VCCZ flag.
420   bool partialVCCWritesUpdateVCCZ() const {
421     return getGeneration() >= GFX10;
422   }
423 
424   /// A read of an SGPR by SMRD instruction requires 4 wait states when the SGPR
425   /// was written by a VALU instruction.
426   bool hasSMRDReadVALUDefHazard() const {
427     return getGeneration() == SOUTHERN_ISLANDS;
428   }
429 
430   /// A read of an SGPR by a VMEM instruction requires 5 wait states when the
431   /// SGPR was written by a VALU Instruction.
432   bool hasVMEMReadSGPRVALUDefHazard() const {
433     return getGeneration() >= VOLCANIC_ISLANDS;
434   }
435 
436   bool hasRFEHazards() const {
437     return getGeneration() >= VOLCANIC_ISLANDS;
438   }
439 
440   /// Number of hazard wait states for s_setreg_b32/s_setreg_imm32_b32.
441   unsigned getSetRegWaitStates() const {
442     return getGeneration() <= SEA_ISLANDS ? 1 : 2;
443   }
444 
445   bool dumpCode() const {
446     return DumpCode;
447   }
448 
449   /// Return the amount of LDS that can be used that will not restrict the
450   /// occupancy lower than WaveCount.
451   unsigned getMaxLocalMemSizeWithWaveCount(unsigned WaveCount,
452                                            const Function &) const;
453 
454   bool supportsMinMaxDenormModes() const {
455     return getGeneration() >= AMDGPUSubtarget::GFX9;
456   }
457 
458   /// \returns If target supports S_DENORM_MODE.
459   bool hasDenormModeInst() const {
460     return getGeneration() >= AMDGPUSubtarget::GFX10;
461   }
462 
463   bool useFlatForGlobal() const {
464     return FlatForGlobal;
465   }
466 
467   /// \returns If target supports ds_read/write_b128 and user enables generation
468   /// of ds_read/write_b128.
469   bool useDS128() const {
470     return CIInsts && EnableDS128;
471   }
472 
473   /// \return If target supports ds_read/write_b96/128.
474   bool hasDS96AndDS128() const {
475     return CIInsts;
476   }
477 
478   /// Have v_trunc_f64, v_ceil_f64, v_rndne_f64
479   bool haveRoundOpsF64() const {
480     return CIInsts;
481   }
482 
483   /// \returns If MUBUF instructions always perform range checking, even for
484   /// buffer resources used for private memory access.
485   bool privateMemoryResourceIsRangeChecked() const {
486     return getGeneration() < AMDGPUSubtarget::GFX9;
487   }
488 
489   /// \returns If target requires PRT Struct NULL support (zero result registers
490   /// for sparse texture support).
491   bool usePRTStrictNull() const {
492     return EnablePRTStrictNull;
493   }
494 
495   bool hasAutoWaitcntBeforeBarrier() const {
496     return AutoWaitcntBeforeBarrier;
497   }
498 
499   bool hasUnalignedBufferAccess() const {
500     return UnalignedBufferAccess;
501   }
502 
503   bool hasUnalignedBufferAccessEnabled() const {
504     return UnalignedBufferAccess && UnalignedAccessMode;
505   }
506 
507   bool hasUnalignedDSAccess() const {
508     return UnalignedDSAccess;
509   }
510 
511   bool hasUnalignedDSAccessEnabled() const {
512     return UnalignedDSAccess && UnalignedAccessMode;
513   }
514 
515   bool hasUnalignedScratchAccess() const {
516     return UnalignedScratchAccess;
517   }
518 
519   bool hasUnalignedAccessMode() const {
520     return UnalignedAccessMode;
521   }
522 
523   bool hasApertureRegs() const {
524     return HasApertureRegs;
525   }
526 
527   bool isTrapHandlerEnabled() const {
528     return TrapHandler;
529   }
530 
531   bool isXNACKEnabled() const {
532     return TargetID.isXnackOnOrAny();
533   }
534 
535   bool isTgSplitEnabled() const {
536     return EnableTgSplit;
537   }
538 
539   bool isCuModeEnabled() const {
540     return EnableCuMode;
541   }
542 
543   bool hasFlatAddressSpace() const {
544     return FlatAddressSpace;
545   }
546 
547   bool hasFlatScrRegister() const {
548     return hasFlatAddressSpace();
549   }
550 
551   bool hasFlatInstOffsets() const {
552     return FlatInstOffsets;
553   }
554 
555   bool hasFlatGlobalInsts() const {
556     return FlatGlobalInsts;
557   }
558 
559   bool hasFlatScratchInsts() const {
560     return FlatScratchInsts;
561   }
562 
563   // Check if target supports ST addressing mode with FLAT scratch instructions.
564   // The ST addressing mode means no registers are used, either VGPR or SGPR,
565   // but only immediate offset is swizzled and added to the FLAT scratch base.
566   bool hasFlatScratchSTMode() const {
567     return hasFlatScratchInsts() && hasGFX10_3Insts();
568   }
569 
570   bool hasScalarFlatScratchInsts() const {
571     return ScalarFlatScratchInsts;
572   }
573 
574   bool hasGlobalAddTidInsts() const {
575     return GFX10_BEncoding;
576   }
577 
578   bool hasAtomicCSub() const {
579     return GFX10_BEncoding;
580   }
581 
582   bool hasMultiDwordFlatScratchAddressing() const {
583     return getGeneration() >= GFX9;
584   }
585 
586   bool hasFlatSegmentOffsetBug() const {
587     return HasFlatSegmentOffsetBug;
588   }
589 
590   bool hasFlatLgkmVMemCountInOrder() const {
591     return getGeneration() > GFX9;
592   }
593 
594   bool hasD16LoadStore() const {
595     return getGeneration() >= GFX9;
596   }
597 
598   bool d16PreservesUnusedBits() const {
599     return hasD16LoadStore() && !TargetID.isSramEccOnOrAny();
600   }
601 
602   bool hasD16Images() const {
603     return getGeneration() >= VOLCANIC_ISLANDS;
604   }
605 
606   /// Return if most LDS instructions have an m0 use that require m0 to be
607   /// iniitalized.
608   bool ldsRequiresM0Init() const {
609     return getGeneration() < GFX9;
610   }
611 
612   // True if the hardware rewinds and replays GWS operations if a wave is
613   // preempted.
614   //
615   // If this is false, a GWS operation requires testing if a nack set the
616   // MEM_VIOL bit, and repeating if so.
617   bool hasGWSAutoReplay() const {
618     return getGeneration() >= GFX9;
619   }
620 
621   /// \returns if target has ds_gws_sema_release_all instruction.
622   bool hasGWSSemaReleaseAll() const {
623     return CIInsts;
624   }
625 
626   /// \returns true if the target has integer add/sub instructions that do not
627   /// produce a carry-out. This includes v_add_[iu]32, v_sub_[iu]32,
628   /// v_add_[iu]16, and v_sub_[iu]16, all of which support the clamp modifier
629   /// for saturation.
630   bool hasAddNoCarry() const {
631     return AddNoCarryInsts;
632   }
633 
634   bool hasUnpackedD16VMem() const {
635     return HasUnpackedD16VMem;
636   }
637 
638   // Covers VS/PS/CS graphics shaders
639   bool isMesaGfxShader(const Function &F) const {
640     return isMesa3DOS() && AMDGPU::isShader(F.getCallingConv());
641   }
642 
643   bool hasMad64_32() const {
644     return getGeneration() >= SEA_ISLANDS;
645   }
646 
647   bool hasSDWAOmod() const {
648     return HasSDWAOmod;
649   }
650 
651   bool hasSDWAScalar() const {
652     return HasSDWAScalar;
653   }
654 
655   bool hasSDWASdst() const {
656     return HasSDWASdst;
657   }
658 
659   bool hasSDWAMac() const {
660     return HasSDWAMac;
661   }
662 
663   bool hasSDWAOutModsVOPC() const {
664     return HasSDWAOutModsVOPC;
665   }
666 
667   bool hasDLInsts() const {
668     return HasDLInsts;
669   }
670 
671   bool hasDot1Insts() const {
672     return HasDot1Insts;
673   }
674 
675   bool hasDot2Insts() const {
676     return HasDot2Insts;
677   }
678 
679   bool hasDot3Insts() const {
680     return HasDot3Insts;
681   }
682 
683   bool hasDot4Insts() const {
684     return HasDot4Insts;
685   }
686 
687   bool hasDot5Insts() const {
688     return HasDot5Insts;
689   }
690 
691   bool hasDot6Insts() const {
692     return HasDot6Insts;
693   }
694 
695   bool hasDot7Insts() const {
696     return HasDot7Insts;
697   }
698 
699   bool hasMAIInsts() const {
700     return HasMAIInsts;
701   }
702 
703   bool hasPkFmacF16Inst() const {
704     return HasPkFmacF16Inst;
705   }
706 
707   bool hasAtomicFaddInsts() const {
708     return HasAtomicFaddInsts;
709   }
710 
711   bool hasNoSdstCMPX() const {
712     return HasNoSdstCMPX;
713   }
714 
715   bool hasVscnt() const {
716     return HasVscnt;
717   }
718 
719   bool hasGetWaveIdInst() const {
720     return HasGetWaveIdInst;
721   }
722 
723   bool hasSMemTimeInst() const {
724     return HasSMemTimeInst;
725   }
726 
727   bool hasShaderCyclesRegister() const {
728     return HasShaderCyclesRegister;
729   }
730 
731   bool hasRegisterBanking() const {
732     return HasRegisterBanking;
733   }
734 
735   bool hasVOP3Literal() const {
736     return HasVOP3Literal;
737   }
738 
739   bool hasNoDataDepHazard() const {
740     return HasNoDataDepHazard;
741   }
742 
743   bool vmemWriteNeedsExpWaitcnt() const {
744     return getGeneration() < SEA_ISLANDS;
745   }
746 
747   // Scratch is allocated in 256 dword per wave blocks for the entire
748   // wavefront. When viewed from the perspecive of an arbitrary workitem, this
749   // is 4-byte aligned.
750   //
751   // Only 4-byte alignment is really needed to access anything. Transformations
752   // on the pointer value itself may rely on the alignment / known low bits of
753   // the pointer. Set this to something above the minimum to avoid needing
754   // dynamic realignment in common cases.
755   Align getStackAlignment() const { return Align(16); }
756 
757   bool enableMachineScheduler() const override {
758     return true;
759   }
760 
761   bool useAA() const override;
762 
763   bool enableSubRegLiveness() const override {
764     return true;
765   }
766 
767   void setScalarizeGlobalBehavior(bool b) { ScalarizeGlobal = b; }
768   bool getScalarizeGlobalBehavior() const { return ScalarizeGlobal; }
769 
770   // static wrappers
771   static bool hasHalfRate64Ops(const TargetSubtargetInfo &STI);
772 
773   // XXX - Why is this here if it isn't in the default pass set?
774   bool enableEarlyIfConversion() const override {
775     return true;
776   }
777 
778   bool enableFlatScratch() const;
779 
780   void overrideSchedPolicy(MachineSchedPolicy &Policy,
781                            unsigned NumRegionInstrs) const override;
782 
783   unsigned getMaxNumUserSGPRs() const {
784     return 16;
785   }
786 
787   bool hasSMemRealTime() const {
788     return HasSMemRealTime;
789   }
790 
791   bool hasMovrel() const {
792     return HasMovrel;
793   }
794 
795   bool hasVGPRIndexMode() const {
796     return HasVGPRIndexMode;
797   }
798 
799   bool useVGPRIndexMode() const;
800 
801   bool hasScalarCompareEq64() const {
802     return getGeneration() >= VOLCANIC_ISLANDS;
803   }
804 
805   bool hasScalarStores() const {
806     return HasScalarStores;
807   }
808 
809   bool hasScalarAtomics() const {
810     return HasScalarAtomics;
811   }
812 
813   bool hasLDSFPAtomics() const {
814     return GFX8Insts;
815   }
816 
817   /// \returns true if the subtarget has the v_permlanex16_b32 instruction.
818   bool hasPermLaneX16() const { return getGeneration() >= GFX10; }
819 
820   bool hasDPP() const {
821     return HasDPP;
822   }
823 
824   bool hasDPPBroadcasts() const {
825     return HasDPP && getGeneration() < GFX10;
826   }
827 
828   bool hasDPPWavefrontShifts() const {
829     return HasDPP && getGeneration() < GFX10;
830   }
831 
832   bool hasDPP8() const {
833     return HasDPP8;
834   }
835 
836   bool has64BitDPP() const {
837     return Has64BitDPP;
838   }
839 
840   bool hasPackedFP32Ops() const {
841     return HasPackedFP32Ops;
842   }
843 
844   bool hasFmaakFmamkF32Insts() const {
845     return getGeneration() >= GFX10;
846   }
847 
848   bool hasExtendedImageInsts() const {
849     return HasExtendedImageInsts;
850   }
851 
852   bool hasR128A16() const {
853     return HasR128A16;
854   }
855 
856   bool hasGFX10A16() const {
857     return HasGFX10A16;
858   }
859 
860   bool hasA16() const { return hasR128A16() || hasGFX10A16(); }
861 
862   bool hasG16() const { return HasG16; }
863 
864   bool hasOffset3fBug() const {
865     return HasOffset3fBug;
866   }
867 
868   bool hasImageStoreD16Bug() const { return HasImageStoreD16Bug; }
869 
870   bool hasImageGather4D16Bug() const { return HasImageGather4D16Bug; }
871 
872   bool hasNSAEncoding() const { return HasNSAEncoding; }
873 
874   bool hasGFX10_BEncoding() const {
875     return GFX10_BEncoding;
876   }
877 
878   bool hasGFX10_3Insts() const {
879     return GFX10_3Insts;
880   }
881 
882   bool hasMadF16() const;
883 
884   bool enableSIScheduler() const {
885     return EnableSIScheduler;
886   }
887 
888   bool loadStoreOptEnabled() const {
889     return EnableLoadStoreOpt;
890   }
891 
892   bool hasSGPRInitBug() const {
893     return SGPRInitBug;
894   }
895 
896   bool hasNegativeScratchOffsetBug() const { return NegativeScratchOffsetBug; }
897 
898   bool hasNegativeUnalignedScratchOffsetBug() const {
899     return NegativeUnalignedScratchOffsetBug;
900   }
901 
902   bool hasMFMAInlineLiteralBug() const {
903     return HasMFMAInlineLiteralBug;
904   }
905 
906   bool has12DWordStoreHazard() const {
907     return getGeneration() != AMDGPUSubtarget::SOUTHERN_ISLANDS;
908   }
909 
910   // \returns true if the subtarget supports DWORDX3 load/store instructions.
911   bool hasDwordx3LoadStores() const {
912     return CIInsts;
913   }
914 
915   bool hasReadM0MovRelInterpHazard() const {
916     return getGeneration() == AMDGPUSubtarget::GFX9;
917   }
918 
919   bool hasReadM0SendMsgHazard() const {
920     return getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS &&
921            getGeneration() <= AMDGPUSubtarget::GFX9;
922   }
923 
924   bool hasVcmpxPermlaneHazard() const {
925     return HasVcmpxPermlaneHazard;
926   }
927 
928   bool hasVMEMtoScalarWriteHazard() const {
929     return HasVMEMtoScalarWriteHazard;
930   }
931 
932   bool hasSMEMtoVectorWriteHazard() const {
933     return HasSMEMtoVectorWriteHazard;
934   }
935 
936   bool hasLDSMisalignedBug() const {
937     return LDSMisalignedBug && !EnableCuMode;
938   }
939 
940   bool hasInstFwdPrefetchBug() const {
941     return HasInstFwdPrefetchBug;
942   }
943 
944   bool hasVcmpxExecWARHazard() const {
945     return HasVcmpxExecWARHazard;
946   }
947 
948   bool hasLdsBranchVmemWARHazard() const {
949     return HasLdsBranchVmemWARHazard;
950   }
951 
952   bool hasNSAtoVMEMBug() const {
953     return HasNSAtoVMEMBug;
954   }
955 
956   bool hasNSAClauseBug() const { return HasNSAClauseBug; }
957 
958   bool hasHardClauses() const { return getGeneration() >= GFX10; }
959 
960   bool hasGFX90AInsts() const { return GFX90AInsts; }
961 
962   /// Return if operations acting on VGPR tuples require even alignment.
963   bool needsAlignedVGPRs() const { return GFX90AInsts; }
964 
965   bool hasPackedTID() const { return HasPackedTID; }
966 
967   /// Return the maximum number of waves per SIMD for kernels using \p SGPRs
968   /// SGPRs
969   unsigned getOccupancyWithNumSGPRs(unsigned SGPRs) const;
970 
971   /// Return the maximum number of waves per SIMD for kernels using \p VGPRs
972   /// VGPRs
973   unsigned getOccupancyWithNumVGPRs(unsigned VGPRs) const;
974 
975   /// Return occupancy for the given function. Used LDS and a number of
976   /// registers if provided.
977   /// Note, occupancy can be affected by the scratch allocation as well, but
978   /// we do not have enough information to compute it.
979   unsigned computeOccupancy(const Function &F, unsigned LDSSize = 0,
980                             unsigned NumSGPRs = 0, unsigned NumVGPRs = 0) const;
981 
982   /// \returns true if the flat_scratch register should be initialized with the
983   /// pointer to the wave's scratch memory rather than a size and offset.
984   bool flatScratchIsPointer() const {
985     return getGeneration() >= AMDGPUSubtarget::GFX9;
986   }
987 
988   /// \returns true if the machine has merged shaders in which s0-s7 are
989   /// reserved by the hardware and user SGPRs start at s8
990   bool hasMergedShaders() const {
991     return getGeneration() >= GFX9;
992   }
993 
994   /// \returns SGPR allocation granularity supported by the subtarget.
995   unsigned getSGPRAllocGranule() const {
996     return AMDGPU::IsaInfo::getSGPRAllocGranule(this);
997   }
998 
999   /// \returns SGPR encoding granularity supported by the subtarget.
1000   unsigned getSGPREncodingGranule() const {
1001     return AMDGPU::IsaInfo::getSGPREncodingGranule(this);
1002   }
1003 
1004   /// \returns Total number of SGPRs supported by the subtarget.
1005   unsigned getTotalNumSGPRs() const {
1006     return AMDGPU::IsaInfo::getTotalNumSGPRs(this);
1007   }
1008 
1009   /// \returns Addressable number of SGPRs supported by the subtarget.
1010   unsigned getAddressableNumSGPRs() const {
1011     return AMDGPU::IsaInfo::getAddressableNumSGPRs(this);
1012   }
1013 
1014   /// \returns Minimum number of SGPRs that meets the given number of waves per
1015   /// execution unit requirement supported by the subtarget.
1016   unsigned getMinNumSGPRs(unsigned WavesPerEU) const {
1017     return AMDGPU::IsaInfo::getMinNumSGPRs(this, WavesPerEU);
1018   }
1019 
1020   /// \returns Maximum number of SGPRs that meets the given number of waves per
1021   /// execution unit requirement supported by the subtarget.
1022   unsigned getMaxNumSGPRs(unsigned WavesPerEU, bool Addressable) const {
1023     return AMDGPU::IsaInfo::getMaxNumSGPRs(this, WavesPerEU, Addressable);
1024   }
1025 
1026   /// \returns Reserved number of SGPRs for given function \p MF.
1027   unsigned getReservedNumSGPRs(const MachineFunction &MF) const;
1028 
1029   /// \returns Maximum number of SGPRs that meets number of waves per execution
1030   /// unit requirement for function \p MF, or number of SGPRs explicitly
1031   /// requested using "amdgpu-num-sgpr" attribute attached to function \p MF.
1032   ///
1033   /// \returns Value that meets number of waves per execution unit requirement
1034   /// if explicitly requested value cannot be converted to integer, violates
1035   /// subtarget's specifications, or does not meet number of waves per execution
1036   /// unit requirement.
1037   unsigned getMaxNumSGPRs(const MachineFunction &MF) const;
1038 
1039   /// \returns VGPR allocation granularity supported by the subtarget.
1040   unsigned getVGPRAllocGranule() const {
1041     return AMDGPU::IsaInfo::getVGPRAllocGranule(this);
1042   }
1043 
1044   /// \returns VGPR encoding granularity supported by the subtarget.
1045   unsigned getVGPREncodingGranule() const {
1046     return AMDGPU::IsaInfo::getVGPREncodingGranule(this);
1047   }
1048 
1049   /// \returns Total number of VGPRs supported by the subtarget.
1050   unsigned getTotalNumVGPRs() const {
1051     return AMDGPU::IsaInfo::getTotalNumVGPRs(this);
1052   }
1053 
1054   /// \returns Addressable number of VGPRs supported by the subtarget.
1055   unsigned getAddressableNumVGPRs() const {
1056     return AMDGPU::IsaInfo::getAddressableNumVGPRs(this);
1057   }
1058 
1059   /// \returns Minimum number of VGPRs that meets given number of waves per
1060   /// execution unit requirement supported by the subtarget.
1061   unsigned getMinNumVGPRs(unsigned WavesPerEU) const {
1062     return AMDGPU::IsaInfo::getMinNumVGPRs(this, WavesPerEU);
1063   }
1064 
1065   /// \returns Maximum number of VGPRs that meets given number of waves per
1066   /// execution unit requirement supported by the subtarget.
1067   unsigned getMaxNumVGPRs(unsigned WavesPerEU) const {
1068     return AMDGPU::IsaInfo::getMaxNumVGPRs(this, WavesPerEU);
1069   }
1070 
1071   /// \returns Maximum number of VGPRs that meets number of waves per execution
1072   /// unit requirement for function \p MF, or number of VGPRs explicitly
1073   /// requested using "amdgpu-num-vgpr" attribute attached to function \p MF.
1074   ///
1075   /// \returns Value that meets number of waves per execution unit requirement
1076   /// if explicitly requested value cannot be converted to integer, violates
1077   /// subtarget's specifications, or does not meet number of waves per execution
1078   /// unit requirement.
1079   unsigned getMaxNumVGPRs(const MachineFunction &MF) const;
1080 
1081   void getPostRAMutations(
1082       std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations)
1083       const override;
1084 
1085   bool isWave32() const {
1086     return getWavefrontSize() == 32;
1087   }
1088 
1089   bool isWave64() const {
1090     return getWavefrontSize() == 64;
1091   }
1092 
1093   const TargetRegisterClass *getBoolRC() const {
1094     return getRegisterInfo()->getBoolRC();
1095   }
1096 
1097   /// \returns Maximum number of work groups per compute unit supported by the
1098   /// subtarget and limited by given \p FlatWorkGroupSize.
1099   unsigned getMaxWorkGroupsPerCU(unsigned FlatWorkGroupSize) const override {
1100     return AMDGPU::IsaInfo::getMaxWorkGroupsPerCU(this, FlatWorkGroupSize);
1101   }
1102 
1103   /// \returns Minimum flat work group size supported by the subtarget.
1104   unsigned getMinFlatWorkGroupSize() const override {
1105     return AMDGPU::IsaInfo::getMinFlatWorkGroupSize(this);
1106   }
1107 
1108   /// \returns Maximum flat work group size supported by the subtarget.
1109   unsigned getMaxFlatWorkGroupSize() const override {
1110     return AMDGPU::IsaInfo::getMaxFlatWorkGroupSize(this);
1111   }
1112 
1113   /// \returns Number of waves per execution unit required to support the given
1114   /// \p FlatWorkGroupSize.
1115   unsigned
1116   getWavesPerEUForWorkGroup(unsigned FlatWorkGroupSize) const override {
1117     return AMDGPU::IsaInfo::getWavesPerEUForWorkGroup(this, FlatWorkGroupSize);
1118   }
1119 
1120   /// \returns Minimum number of waves per execution unit supported by the
1121   /// subtarget.
1122   unsigned getMinWavesPerEU() const override {
1123     return AMDGPU::IsaInfo::getMinWavesPerEU(this);
1124   }
1125 
1126   void adjustSchedDependency(SUnit *Def, int DefOpIdx, SUnit *Use, int UseOpIdx,
1127                              SDep &Dep) const override;
1128 };
1129 
1130 } // end namespace llvm
1131 
1132 #endif // LLVM_LIB_TARGET_AMDGPU_GCNSUBTARGET_H
1133