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