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