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