1 //=====-- AMDGPUSubtarget.h - Define Subtarget for AMDGPU ------*- C++ -*-====//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //==-----------------------------------------------------------------------===//
9 //
10 /// \file
11 /// AMDGPU specific subclass of TargetSubtarget.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUSUBTARGET_H
16 #define LLVM_LIB_TARGET_AMDGPU_AMDGPUSUBTARGET_H
17 
18 #include "AMDGPU.h"
19 #include "AMDGPUCallLowering.h"
20 #include "R600FrameLowering.h"
21 #include "R600ISelLowering.h"
22 #include "R600InstrInfo.h"
23 #include "SIFrameLowering.h"
24 #include "SIISelLowering.h"
25 #include "SIInstrInfo.h"
26 #include "Utils/AMDGPUBaseInfo.h"
27 #include "llvm/ADT/Triple.h"
28 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
29 #include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
30 #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
31 #include "llvm/CodeGen/MachineFunction.h"
32 #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
33 #include "llvm/MC/MCInstrItineraries.h"
34 #include "llvm/Support/MathExtras.h"
35 #include <cassert>
36 #include <cstdint>
37 #include <memory>
38 #include <utility>
39 
40 #define GET_SUBTARGETINFO_HEADER
41 #include "AMDGPUGenSubtargetInfo.inc"
42 #define GET_SUBTARGETINFO_HEADER
43 #include "R600GenSubtargetInfo.inc"
44 
45 namespace llvm {
46 
47 class StringRef;
48 
49 class AMDGPUSubtarget {
50 public:
51   enum Generation {
52     R600 = 0,
53     R700 = 1,
54     EVERGREEN = 2,
55     NORTHERN_ISLANDS = 3,
56     SOUTHERN_ISLANDS = 4,
57     SEA_ISLANDS = 5,
58     VOLCANIC_ISLANDS = 6,
59     GFX9 = 7
60   };
61 
62 private:
63   Triple TargetTriple;
64 
65 protected:
66   bool Has16BitInsts;
67   bool HasMadMixInsts;
68   bool FP32Denormals;
69   bool FPExceptions;
70   bool HasSDWA;
71   bool HasVOP3PInsts;
72   bool HasMulI24;
73   bool HasMulU24;
74   bool HasInv2PiInlineImm;
75   bool HasFminFmaxLegacy;
76   bool EnablePromoteAlloca;
77   bool HasTrigReducedRange;
78   int LocalMemorySize;
79   unsigned WavefrontSize;
80 
81 public:
82   AMDGPUSubtarget(const Triple &TT);
83 
84   static const AMDGPUSubtarget &get(const MachineFunction &MF);
85   static const AMDGPUSubtarget &get(const TargetMachine &TM,
86                                     const Function &F);
87 
88   /// \returns Default range flat work group size for a calling convention.
89   std::pair<unsigned, unsigned> getDefaultFlatWorkGroupSize(CallingConv::ID CC) const;
90 
91   /// \returns Subtarget's default pair of minimum/maximum flat work group sizes
92   /// for function \p F, or minimum/maximum flat work group sizes explicitly
93   /// requested using "amdgpu-flat-work-group-size" attribute attached to
94   /// function \p F.
95   ///
96   /// \returns Subtarget's default values if explicitly requested values cannot
97   /// be converted to integer, or violate subtarget's specifications.
98   std::pair<unsigned, unsigned> getFlatWorkGroupSizes(const Function &F) const;
99 
100   /// \returns Subtarget's default pair of minimum/maximum number of waves per
101   /// execution unit for function \p F, or minimum/maximum number of waves per
102   /// execution unit explicitly requested using "amdgpu-waves-per-eu" attribute
103   /// attached to function \p F.
104   ///
105   /// \returns Subtarget's default values if explicitly requested values cannot
106   /// be converted to integer, violate subtarget's specifications, or are not
107   /// compatible with minimum/maximum number of waves limited by flat work group
108   /// size, register usage, and/or lds usage.
109   std::pair<unsigned, unsigned> getWavesPerEU(const Function &F) const;
110 
111   /// Return the amount of LDS that can be used that will not restrict the
112   /// occupancy lower than WaveCount.
113   unsigned getMaxLocalMemSizeWithWaveCount(unsigned WaveCount,
114                                            const Function &) const;
115 
116   /// Inverse of getMaxLocalMemWithWaveCount. Return the maximum wavecount if
117   /// the given LDS memory size is the only constraint.
118   unsigned getOccupancyWithLocalMemSize(uint32_t Bytes, const Function &) const;
119 
120   unsigned getOccupancyWithLocalMemSize(const MachineFunction &MF) const;
121 
122   bool isAmdHsaOS() const {
123     return TargetTriple.getOS() == Triple::AMDHSA;
124   }
125 
126   bool isAmdPalOS() const {
127     return TargetTriple.getOS() == Triple::AMDPAL;
128   }
129 
130   bool isMesa3DOS() const {
131     return TargetTriple.getOS() == Triple::Mesa3D;
132   }
133 
134   bool isMesaKernel(const Function &F) const {
135     return isMesa3DOS() && !AMDGPU::isShader(F.getCallingConv());
136   }
137 
138   bool isAmdHsaOrMesa(const Function &F) const {
139     return isAmdHsaOS() || isMesaKernel(F);
140   }
141 
142   bool has16BitInsts() const {
143     return Has16BitInsts;
144   }
145 
146   bool hasMadMixInsts() const {
147     return HasMadMixInsts;
148   }
149 
150   bool hasFP32Denormals() const {
151     return FP32Denormals;
152   }
153 
154   bool hasFPExceptions() const {
155     return FPExceptions;
156   }
157 
158   bool hasSDWA() const {
159     return HasSDWA;
160   }
161 
162   bool hasVOP3PInsts() const {
163     return HasVOP3PInsts;
164   }
165 
166   bool hasMulI24() const {
167     return HasMulI24;
168   }
169 
170   bool hasMulU24() const {
171     return HasMulU24;
172   }
173 
174   bool hasInv2PiInlineImm() const {
175     return HasInv2PiInlineImm;
176   }
177 
178   bool hasFminFmaxLegacy() const {
179     return HasFminFmaxLegacy;
180   }
181 
182   bool hasTrigReducedRange() const {
183     return HasTrigReducedRange;
184   }
185 
186   bool isPromoteAllocaEnabled() const {
187     return EnablePromoteAlloca;
188   }
189 
190   unsigned getWavefrontSize() const {
191     return WavefrontSize;
192   }
193 
194   int getLocalMemorySize() const {
195     return LocalMemorySize;
196   }
197 
198   unsigned getAlignmentForImplicitArgPtr() const {
199     return isAmdHsaOS() ? 8 : 4;
200   }
201 
202   /// Returns the offset in bytes from the start of the input buffer
203   ///        of the first explicit kernel argument.
204   unsigned getExplicitKernelArgOffset(const Function &F) const {
205     return isAmdHsaOrMesa(F) ? 0 : 36;
206   }
207 
208   /// \returns Maximum number of work groups per compute unit supported by the
209   /// subtarget and limited by given \p FlatWorkGroupSize.
210   virtual unsigned getMaxWorkGroupsPerCU(unsigned FlatWorkGroupSize) const = 0;
211 
212   /// \returns Minimum flat work group size supported by the subtarget.
213   virtual unsigned getMinFlatWorkGroupSize() const = 0;
214 
215   /// \returns Maximum flat work group size supported by the subtarget.
216   virtual unsigned getMaxFlatWorkGroupSize() const = 0;
217 
218   /// \returns Maximum number of waves per execution unit supported by the
219   /// subtarget and limited by given \p FlatWorkGroupSize.
220   virtual unsigned getMaxWavesPerEU(unsigned FlatWorkGroupSize) const  = 0;
221 
222   /// \returns Minimum number of waves per execution unit supported by the
223   /// subtarget.
224   virtual unsigned getMinWavesPerEU() const = 0;
225 
226   unsigned getMaxWavesPerEU() const { return 10; }
227 
228   /// Creates value range metadata on an workitemid.* inrinsic call or load.
229   bool makeLIDRangeMetadata(Instruction *I) const;
230 
231   /// \returns Number of bytes of arguments that are passed to a shader or
232   /// kernel in addition to the explicit ones declared for the function.
233   unsigned getImplicitArgNumBytes(const Function &F) const {
234     if (isMesaKernel(F))
235       return 16;
236     return AMDGPU::getIntegerAttribute(F, "amdgpu-implicitarg-num-bytes", 0);
237   }
238   uint64_t getExplicitKernArgSize(const Function &F,
239                                   unsigned &MaxAlign) const;
240   unsigned getKernArgSegmentSize(const Function &F,
241                                  unsigned &MaxAlign) const;
242 
243   virtual ~AMDGPUSubtarget() {}
244 };
245 
246 class GCNSubtarget : public AMDGPUGenSubtargetInfo,
247                      public AMDGPUSubtarget {
248 public:
249   enum {
250     ISAVersion0_0_0,
251     ISAVersion6_0_0,
252     ISAVersion6_0_1,
253     ISAVersion7_0_0,
254     ISAVersion7_0_1,
255     ISAVersion7_0_2,
256     ISAVersion7_0_3,
257     ISAVersion7_0_4,
258     ISAVersion8_0_1,
259     ISAVersion8_0_2,
260     ISAVersion8_0_3,
261     ISAVersion8_1_0,
262     ISAVersion9_0_0,
263     ISAVersion9_0_2,
264     ISAVersion9_0_4,
265     ISAVersion9_0_6,
266     ISAVersion9_0_9,
267   };
268 
269   enum TrapHandlerAbi {
270     TrapHandlerAbiNone = 0,
271     TrapHandlerAbiHsa = 1
272   };
273 
274   enum TrapID {
275     TrapIDHardwareReserved = 0,
276     TrapIDHSADebugTrap = 1,
277     TrapIDLLVMTrap = 2,
278     TrapIDLLVMDebugTrap = 3,
279     TrapIDDebugBreakpoint = 7,
280     TrapIDDebugReserved8 = 8,
281     TrapIDDebugReservedFE = 0xfe,
282     TrapIDDebugReservedFF = 0xff
283   };
284 
285   enum TrapRegValues {
286     LLVMTrapHandlerRegValue = 1
287   };
288 
289 private:
290   /// GlobalISel related APIs.
291   std::unique_ptr<AMDGPUCallLowering> CallLoweringInfo;
292   std::unique_ptr<InstructionSelector> InstSelector;
293   std::unique_ptr<LegalizerInfo> Legalizer;
294   std::unique_ptr<RegisterBankInfo> RegBankInfo;
295 
296 protected:
297   // Basic subtarget description.
298   Triple TargetTriple;
299   unsigned Gen;
300   unsigned IsaVersion;
301   InstrItineraryData InstrItins;
302   int LDSBankCount;
303   unsigned MaxPrivateElementSize;
304 
305   // Possibly statically set by tablegen, but may want to be overridden.
306   bool FastFMAF32;
307   bool HalfRate64Ops;
308 
309   // Dynamially set bits that enable features.
310   bool FP64FP16Denormals;
311   bool DX10Clamp;
312   bool FlatForGlobal;
313   bool AutoWaitcntBeforeBarrier;
314   bool CodeObjectV3;
315   bool UnalignedScratchAccess;
316   bool UnalignedBufferAccess;
317   bool HasApertureRegs;
318   bool EnableXNACK;
319   bool TrapHandler;
320   bool DebuggerInsertNops;
321   bool DebuggerEmitPrologue;
322 
323   // Used as options.
324   bool EnableHugePrivateBuffer;
325   bool EnableVGPRSpilling;
326   bool EnableLoadStoreOpt;
327   bool EnableUnsafeDSOffsetFolding;
328   bool EnableSIScheduler;
329   bool EnableDS128;
330   bool DumpCode;
331 
332   // Subtarget statically properties set by tablegen
333   bool FP64;
334   bool FMA;
335   bool MIMG_R128;
336   bool IsGCN;
337   bool GCN3Encoding;
338   bool CIInsts;
339   bool VIInsts;
340   bool GFX9Insts;
341   bool SGPRInitBug;
342   bool HasSMemRealTime;
343   bool HasIntClamp;
344   bool HasFmaMixInsts;
345   bool HasMovrel;
346   bool HasVGPRIndexMode;
347   bool HasScalarStores;
348   bool HasScalarAtomics;
349   bool HasSDWAOmod;
350   bool HasSDWAScalar;
351   bool HasSDWASdst;
352   bool HasSDWAMac;
353   bool HasSDWAOutModsVOPC;
354   bool HasDPP;
355   bool HasR128A16;
356   bool HasDLInsts;
357   bool D16PreservesUnusedBits;
358   bool FlatAddressSpace;
359   bool FlatInstOffsets;
360   bool FlatGlobalInsts;
361   bool FlatScratchInsts;
362   bool AddNoCarryInsts;
363   bool HasUnpackedD16VMem;
364   bool R600ALUInst;
365   bool CaymanISA;
366   bool CFALUBug;
367   bool HasVertexCache;
368   short TexVTXClauseSize;
369   bool ScalarizeGlobal;
370 
371   // Dummy feature to use for assembler in tablegen.
372   bool FeatureDisable;
373 
374   SelectionDAGTargetInfo TSInfo;
375 private:
376   SIInstrInfo InstrInfo;
377   SITargetLowering TLInfo;
378   SIFrameLowering FrameLowering;
379 
380 public:
381   GCNSubtarget(const Triple &TT, StringRef GPU, StringRef FS,
382                const GCNTargetMachine &TM);
383   ~GCNSubtarget() override;
384 
385   GCNSubtarget &initializeSubtargetDependencies(const Triple &TT,
386                                                    StringRef GPU, StringRef FS);
387 
388   const SIInstrInfo *getInstrInfo() const override {
389     return &InstrInfo;
390   }
391 
392   const SIFrameLowering *getFrameLowering() const override {
393     return &FrameLowering;
394   }
395 
396   const SITargetLowering *getTargetLowering() const override {
397     return &TLInfo;
398   }
399 
400   const SIRegisterInfo *getRegisterInfo() const override {
401     return &InstrInfo.getRegisterInfo();
402   }
403 
404   const CallLowering *getCallLowering() const override {
405     return CallLoweringInfo.get();
406   }
407 
408   const InstructionSelector *getInstructionSelector() const override {
409     return InstSelector.get();
410   }
411 
412   const LegalizerInfo *getLegalizerInfo() const override {
413     return Legalizer.get();
414   }
415 
416   const RegisterBankInfo *getRegBankInfo() const override {
417     return RegBankInfo.get();
418   }
419 
420   // Nothing implemented, just prevent crashes on use.
421   const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
422     return &TSInfo;
423   }
424 
425   const InstrItineraryData *getInstrItineraryData() const override {
426     return &InstrItins;
427   }
428 
429   void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
430 
431   Generation getGeneration() const {
432     return (Generation)Gen;
433   }
434 
435   unsigned getWavefrontSizeLog2() const {
436     return Log2_32(WavefrontSize);
437   }
438 
439   int getLDSBankCount() const {
440     return LDSBankCount;
441   }
442 
443   unsigned getMaxPrivateElementSize() const {
444     return MaxPrivateElementSize;
445   }
446 
447   bool hasIntClamp() const {
448     return HasIntClamp;
449   }
450 
451   bool hasFP64() const {
452     return FP64;
453   }
454 
455   bool hasMIMG_R128() const {
456     return MIMG_R128;
457   }
458 
459   bool hasHWFP64() const {
460     return FP64;
461   }
462 
463   bool hasFastFMAF32() const {
464     return FastFMAF32;
465   }
466 
467   bool hasHalfRate64Ops() const {
468     return HalfRate64Ops;
469   }
470 
471   bool hasAddr64() const {
472     return (getGeneration() < AMDGPUSubtarget::VOLCANIC_ISLANDS);
473   }
474 
475   bool hasBFE() const {
476     return true;
477   }
478 
479   bool hasBFI() const {
480     return true;
481   }
482 
483   bool hasBFM() const {
484     return hasBFE();
485   }
486 
487   bool hasBCNT(unsigned Size) const {
488     return true;
489   }
490 
491   bool hasFFBL() const {
492     return true;
493   }
494 
495   bool hasFFBH() const {
496     return true;
497   }
498 
499   bool hasMed3_16() const {
500     return getGeneration() >= AMDGPUSubtarget::GFX9;
501   }
502 
503   bool hasMin3Max3_16() const {
504     return getGeneration() >= AMDGPUSubtarget::GFX9;
505   }
506 
507   bool hasFmaMixInsts() const {
508     return HasFmaMixInsts;
509   }
510 
511   bool hasCARRY() const {
512     return true;
513   }
514 
515   bool hasFMA() const {
516     return FMA;
517   }
518 
519   bool hasSwap() const {
520     return GFX9Insts;
521   }
522 
523   TrapHandlerAbi getTrapHandlerAbi() const {
524     return isAmdHsaOS() ? TrapHandlerAbiHsa : TrapHandlerAbiNone;
525   }
526 
527   bool enableHugePrivateBuffer() const {
528     return EnableHugePrivateBuffer;
529   }
530 
531   bool unsafeDSOffsetFoldingEnabled() const {
532     return EnableUnsafeDSOffsetFolding;
533   }
534 
535   bool dumpCode() const {
536     return DumpCode;
537   }
538 
539   /// Return the amount of LDS that can be used that will not restrict the
540   /// occupancy lower than WaveCount.
541   unsigned getMaxLocalMemSizeWithWaveCount(unsigned WaveCount,
542                                            const Function &) const;
543 
544   bool hasFP16Denormals() const {
545     return FP64FP16Denormals;
546   }
547 
548   bool hasFP64Denormals() const {
549     return FP64FP16Denormals;
550   }
551 
552   bool supportsMinMaxDenormModes() const {
553     return getGeneration() >= AMDGPUSubtarget::GFX9;
554   }
555 
556   bool enableDX10Clamp() const {
557     return DX10Clamp;
558   }
559 
560   bool enableIEEEBit(const MachineFunction &MF) const {
561     return AMDGPU::isCompute(MF.getFunction().getCallingConv());
562   }
563 
564   bool useFlatForGlobal() const {
565     return FlatForGlobal;
566   }
567 
568   /// \returns If target supports ds_read/write_b128 and user enables generation
569   /// of ds_read/write_b128.
570   bool useDS128() const {
571     return CIInsts && EnableDS128;
572   }
573 
574   /// \returns If MUBUF instructions always perform range checking, even for
575   /// buffer resources used for private memory access.
576   bool privateMemoryResourceIsRangeChecked() const {
577     return getGeneration() < AMDGPUSubtarget::GFX9;
578   }
579 
580   bool hasAutoWaitcntBeforeBarrier() const {
581     return AutoWaitcntBeforeBarrier;
582   }
583 
584   bool hasCodeObjectV3() const {
585     return CodeObjectV3;
586   }
587 
588   bool hasUnalignedBufferAccess() const {
589     return UnalignedBufferAccess;
590   }
591 
592   bool hasUnalignedScratchAccess() const {
593     return UnalignedScratchAccess;
594   }
595 
596   bool hasApertureRegs() const {
597     return HasApertureRegs;
598   }
599 
600   bool isTrapHandlerEnabled() const {
601     return TrapHandler;
602   }
603 
604   bool isXNACKEnabled() const {
605     return EnableXNACK;
606   }
607 
608   bool hasFlatAddressSpace() const {
609     return FlatAddressSpace;
610   }
611 
612   bool hasFlatInstOffsets() const {
613     return FlatInstOffsets;
614   }
615 
616   bool hasFlatGlobalInsts() const {
617     return FlatGlobalInsts;
618   }
619 
620   bool hasFlatScratchInsts() const {
621     return FlatScratchInsts;
622   }
623 
624   bool hasFlatLgkmVMemCountInOrder() const {
625     return getGeneration() > GFX9;
626   }
627 
628   bool hasD16LoadStore() const {
629     return getGeneration() >= GFX9;
630   }
631 
632   /// Return if most LDS instructions have an m0 use that require m0 to be
633   /// iniitalized.
634   bool ldsRequiresM0Init() const {
635     return getGeneration() < GFX9;
636   }
637 
638   bool hasAddNoCarry() const {
639     return AddNoCarryInsts;
640   }
641 
642   bool hasUnpackedD16VMem() const {
643     return HasUnpackedD16VMem;
644   }
645 
646   // Covers VS/PS/CS graphics shaders
647   bool isMesaGfxShader(const Function &F) const {
648     return isMesa3DOS() && AMDGPU::isShader(F.getCallingConv());
649   }
650 
651   bool hasMad64_32() const {
652     return getGeneration() >= SEA_ISLANDS;
653   }
654 
655   bool hasSDWAOmod() const {
656     return HasSDWAOmod;
657   }
658 
659   bool hasSDWAScalar() const {
660     return HasSDWAScalar;
661   }
662 
663   bool hasSDWASdst() const {
664     return HasSDWASdst;
665   }
666 
667   bool hasSDWAMac() const {
668     return HasSDWAMac;
669   }
670 
671   bool hasSDWAOutModsVOPC() const {
672     return HasSDWAOutModsVOPC;
673   }
674 
675   bool vmemWriteNeedsExpWaitcnt() const {
676     return getGeneration() < SEA_ISLANDS;
677   }
678 
679   bool hasDLInsts() const {
680     return HasDLInsts;
681   }
682 
683   bool d16PreservesUnusedBits() const {
684     return D16PreservesUnusedBits;
685   }
686 
687   // Scratch is allocated in 256 dword per wave blocks for the entire
688   // wavefront. When viewed from the perspecive of an arbitrary workitem, this
689   // is 4-byte aligned.
690   //
691   // Only 4-byte alignment is really needed to access anything. Transformations
692   // on the pointer value itself may rely on the alignment / known low bits of
693   // the pointer. Set this to something above the minimum to avoid needing
694   // dynamic realignment in common cases.
695   unsigned getStackAlignment() const {
696     return 16;
697   }
698 
699   bool enableMachineScheduler() const override {
700     return true;
701   }
702 
703   bool enableSubRegLiveness() const override {
704     return true;
705   }
706 
707   void setScalarizeGlobalBehavior(bool b) { ScalarizeGlobal = b; }
708   bool getScalarizeGlobalBehavior() const { return ScalarizeGlobal; }
709 
710   /// \returns Number of execution units per compute unit supported by the
711   /// subtarget.
712   unsigned getEUsPerCU() const {
713     return AMDGPU::IsaInfo::getEUsPerCU(this);
714   }
715 
716   /// \returns Maximum number of waves per compute unit supported by the
717   /// subtarget without any kind of limitation.
718   unsigned getMaxWavesPerCU() const {
719     return AMDGPU::IsaInfo::getMaxWavesPerCU(this);
720   }
721 
722   /// \returns Maximum number of waves per compute unit supported by the
723   /// subtarget and limited by given \p FlatWorkGroupSize.
724   unsigned getMaxWavesPerCU(unsigned FlatWorkGroupSize) const {
725     return AMDGPU::IsaInfo::getMaxWavesPerCU(this, FlatWorkGroupSize);
726   }
727 
728   /// \returns Maximum number of waves per execution unit supported by the
729   /// subtarget without any kind of limitation.
730   unsigned getMaxWavesPerEU() const {
731     return AMDGPU::IsaInfo::getMaxWavesPerEU();
732   }
733 
734   /// \returns Number of waves per work group supported by the subtarget and
735   /// limited by given \p FlatWorkGroupSize.
736   unsigned getWavesPerWorkGroup(unsigned FlatWorkGroupSize) const {
737     return AMDGPU::IsaInfo::getWavesPerWorkGroup(this, FlatWorkGroupSize);
738   }
739 
740   // static wrappers
741   static bool hasHalfRate64Ops(const TargetSubtargetInfo &STI);
742 
743   // XXX - Why is this here if it isn't in the default pass set?
744   bool enableEarlyIfConversion() const override {
745     return true;
746   }
747 
748   void overrideSchedPolicy(MachineSchedPolicy &Policy,
749                            unsigned NumRegionInstrs) const override;
750 
751   bool isVGPRSpillingEnabled(const Function &F) const;
752 
753   unsigned getMaxNumUserSGPRs() const {
754     return 16;
755   }
756 
757   bool hasSMemRealTime() const {
758     return HasSMemRealTime;
759   }
760 
761   bool hasMovrel() const {
762     return HasMovrel;
763   }
764 
765   bool hasVGPRIndexMode() const {
766     return HasVGPRIndexMode;
767   }
768 
769   bool useVGPRIndexMode(bool UserEnable) const {
770     return !hasMovrel() || (UserEnable && hasVGPRIndexMode());
771   }
772 
773   bool hasScalarCompareEq64() const {
774     return getGeneration() >= VOLCANIC_ISLANDS;
775   }
776 
777   bool hasScalarStores() const {
778     return HasScalarStores;
779   }
780 
781   bool hasScalarAtomics() const {
782     return HasScalarAtomics;
783   }
784 
785 
786   bool hasDPP() const {
787     return HasDPP;
788   }
789 
790   bool hasR128A16() const {
791     return HasR128A16;
792   }
793 
794   bool enableSIScheduler() const {
795     return EnableSIScheduler;
796   }
797 
798   bool debuggerSupported() const {
799     return debuggerInsertNops() && debuggerEmitPrologue();
800   }
801 
802   bool debuggerInsertNops() const {
803     return DebuggerInsertNops;
804   }
805 
806   bool debuggerEmitPrologue() const {
807     return DebuggerEmitPrologue;
808   }
809 
810   bool loadStoreOptEnabled() const {
811     return EnableLoadStoreOpt;
812   }
813 
814   bool hasSGPRInitBug() const {
815     return SGPRInitBug;
816   }
817 
818   bool has12DWordStoreHazard() const {
819     return getGeneration() != AMDGPUSubtarget::SOUTHERN_ISLANDS;
820   }
821 
822   bool hasSMovFedHazard() const {
823     return getGeneration() >= AMDGPUSubtarget::GFX9;
824   }
825 
826   bool hasReadM0MovRelInterpHazard() const {
827     return getGeneration() >= AMDGPUSubtarget::GFX9;
828   }
829 
830   bool hasReadM0SendMsgHazard() const {
831     return getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS;
832   }
833 
834   /// Return the maximum number of waves per SIMD for kernels using \p SGPRs
835   /// SGPRs
836   unsigned getOccupancyWithNumSGPRs(unsigned SGPRs) const;
837 
838   /// Return the maximum number of waves per SIMD for kernels using \p VGPRs
839   /// VGPRs
840   unsigned getOccupancyWithNumVGPRs(unsigned VGPRs) const;
841 
842   /// \returns true if the flat_scratch register should be initialized with the
843   /// pointer to the wave's scratch memory rather than a size and offset.
844   bool flatScratchIsPointer() const {
845     return getGeneration() >= AMDGPUSubtarget::GFX9;
846   }
847 
848   /// \returns true if the machine has merged shaders in which s0-s7 are
849   /// reserved by the hardware and user SGPRs start at s8
850   bool hasMergedShaders() const {
851     return getGeneration() >= GFX9;
852   }
853 
854   /// \returns SGPR allocation granularity supported by the subtarget.
855   unsigned getSGPRAllocGranule() const {
856     return AMDGPU::IsaInfo::getSGPRAllocGranule(this);
857   }
858 
859   /// \returns SGPR encoding granularity supported by the subtarget.
860   unsigned getSGPREncodingGranule() const {
861     return AMDGPU::IsaInfo::getSGPREncodingGranule(this);
862   }
863 
864   /// \returns Total number of SGPRs supported by the subtarget.
865   unsigned getTotalNumSGPRs() const {
866     return AMDGPU::IsaInfo::getTotalNumSGPRs(this);
867   }
868 
869   /// \returns Addressable number of SGPRs supported by the subtarget.
870   unsigned getAddressableNumSGPRs() const {
871     return AMDGPU::IsaInfo::getAddressableNumSGPRs(this);
872   }
873 
874   /// \returns Minimum number of SGPRs that meets the given number of waves per
875   /// execution unit requirement supported by the subtarget.
876   unsigned getMinNumSGPRs(unsigned WavesPerEU) const {
877     return AMDGPU::IsaInfo::getMinNumSGPRs(this, WavesPerEU);
878   }
879 
880   /// \returns Maximum number of SGPRs that meets the given number of waves per
881   /// execution unit requirement supported by the subtarget.
882   unsigned getMaxNumSGPRs(unsigned WavesPerEU, bool Addressable) const {
883     return AMDGPU::IsaInfo::getMaxNumSGPRs(this, WavesPerEU, Addressable);
884   }
885 
886   /// \returns Reserved number of SGPRs for given function \p MF.
887   unsigned getReservedNumSGPRs(const MachineFunction &MF) const;
888 
889   /// \returns Maximum number of SGPRs that meets number of waves per execution
890   /// unit requirement for function \p MF, or number of SGPRs explicitly
891   /// requested using "amdgpu-num-sgpr" attribute attached to function \p MF.
892   ///
893   /// \returns Value that meets number of waves per execution unit requirement
894   /// if explicitly requested value cannot be converted to integer, violates
895   /// subtarget's specifications, or does not meet number of waves per execution
896   /// unit requirement.
897   unsigned getMaxNumSGPRs(const MachineFunction &MF) const;
898 
899   /// \returns VGPR allocation granularity supported by the subtarget.
900   unsigned getVGPRAllocGranule() const {
901     return AMDGPU::IsaInfo::getVGPRAllocGranule(this);
902   }
903 
904   /// \returns VGPR encoding granularity supported by the subtarget.
905   unsigned getVGPREncodingGranule() const {
906     return AMDGPU::IsaInfo::getVGPREncodingGranule(this);
907   }
908 
909   /// \returns Total number of VGPRs supported by the subtarget.
910   unsigned getTotalNumVGPRs() const {
911     return AMDGPU::IsaInfo::getTotalNumVGPRs(this);
912   }
913 
914   /// \returns Addressable number of VGPRs supported by the subtarget.
915   unsigned getAddressableNumVGPRs() const {
916     return AMDGPU::IsaInfo::getAddressableNumVGPRs(this);
917   }
918 
919   /// \returns Minimum number of VGPRs that meets given number of waves per
920   /// execution unit requirement supported by the subtarget.
921   unsigned getMinNumVGPRs(unsigned WavesPerEU) const {
922     return AMDGPU::IsaInfo::getMinNumVGPRs(this, WavesPerEU);
923   }
924 
925   /// \returns Maximum number of VGPRs that meets given number of waves per
926   /// execution unit requirement supported by the subtarget.
927   unsigned getMaxNumVGPRs(unsigned WavesPerEU) const {
928     return AMDGPU::IsaInfo::getMaxNumVGPRs(this, WavesPerEU);
929   }
930 
931   /// \returns Maximum number of VGPRs that meets number of waves per execution
932   /// unit requirement for function \p MF, or number of VGPRs explicitly
933   /// requested using "amdgpu-num-vgpr" attribute attached to function \p MF.
934   ///
935   /// \returns Value that meets number of waves per execution unit requirement
936   /// if explicitly requested value cannot be converted to integer, violates
937   /// subtarget's specifications, or does not meet number of waves per execution
938   /// unit requirement.
939   unsigned getMaxNumVGPRs(const MachineFunction &MF) const;
940 
941   void getPostRAMutations(
942       std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations)
943       const override;
944 
945   /// \returns Maximum number of work groups per compute unit supported by the
946   /// subtarget and limited by given \p FlatWorkGroupSize.
947   unsigned getMaxWorkGroupsPerCU(unsigned FlatWorkGroupSize) const override {
948     return AMDGPU::IsaInfo::getMaxWorkGroupsPerCU(this, FlatWorkGroupSize);
949   }
950 
951   /// \returns Minimum flat work group size supported by the subtarget.
952   unsigned getMinFlatWorkGroupSize() const override {
953     return AMDGPU::IsaInfo::getMinFlatWorkGroupSize(this);
954   }
955 
956   /// \returns Maximum flat work group size supported by the subtarget.
957   unsigned getMaxFlatWorkGroupSize() const override {
958     return AMDGPU::IsaInfo::getMaxFlatWorkGroupSize(this);
959   }
960 
961   /// \returns Maximum number of waves per execution unit supported by the
962   /// subtarget and limited by given \p FlatWorkGroupSize.
963   unsigned getMaxWavesPerEU(unsigned FlatWorkGroupSize) const override {
964     return AMDGPU::IsaInfo::getMaxWavesPerEU(this, FlatWorkGroupSize);
965   }
966 
967   /// \returns Minimum number of waves per execution unit supported by the
968   /// subtarget.
969   unsigned getMinWavesPerEU() const override {
970     return AMDGPU::IsaInfo::getMinWavesPerEU(this);
971   }
972 };
973 
974 class R600Subtarget final : public R600GenSubtargetInfo,
975                             public AMDGPUSubtarget {
976 private:
977   R600InstrInfo InstrInfo;
978   R600FrameLowering FrameLowering;
979   bool FMA;
980   bool CaymanISA;
981   bool CFALUBug;
982   bool DX10Clamp;
983   bool HasVertexCache;
984   bool R600ALUInst;
985   bool FP64;
986   short TexVTXClauseSize;
987   Generation Gen;
988   R600TargetLowering TLInfo;
989   InstrItineraryData InstrItins;
990   SelectionDAGTargetInfo TSInfo;
991 
992 public:
993   R600Subtarget(const Triple &TT, StringRef CPU, StringRef FS,
994                 const TargetMachine &TM);
995 
996   const R600InstrInfo *getInstrInfo() const override { return &InstrInfo; }
997 
998   const R600FrameLowering *getFrameLowering() const override {
999     return &FrameLowering;
1000   }
1001 
1002   const R600TargetLowering *getTargetLowering() const override {
1003     return &TLInfo;
1004   }
1005 
1006   const R600RegisterInfo *getRegisterInfo() const override {
1007     return &InstrInfo.getRegisterInfo();
1008   }
1009 
1010   const InstrItineraryData *getInstrItineraryData() const override {
1011     return &InstrItins;
1012   }
1013 
1014   // Nothing implemented, just prevent crashes on use.
1015   const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
1016     return &TSInfo;
1017   }
1018 
1019   void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
1020 
1021   Generation getGeneration() const {
1022     return Gen;
1023   }
1024 
1025   unsigned getStackAlignment() const {
1026     return 4;
1027   }
1028 
1029   R600Subtarget &initializeSubtargetDependencies(const Triple &TT,
1030                                                  StringRef GPU, StringRef FS);
1031 
1032   bool hasBFE() const {
1033     return (getGeneration() >= EVERGREEN);
1034   }
1035 
1036   bool hasBFI() const {
1037     return (getGeneration() >= EVERGREEN);
1038   }
1039 
1040   bool hasBCNT(unsigned Size) const {
1041     if (Size == 32)
1042       return (getGeneration() >= EVERGREEN);
1043 
1044     return false;
1045   }
1046 
1047   bool hasBORROW() const {
1048     return (getGeneration() >= EVERGREEN);
1049   }
1050 
1051   bool hasCARRY() const {
1052     return (getGeneration() >= EVERGREEN);
1053   }
1054 
1055   bool hasCaymanISA() const {
1056     return CaymanISA;
1057   }
1058 
1059   bool hasFFBL() const {
1060     return (getGeneration() >= EVERGREEN);
1061   }
1062 
1063   bool hasFFBH() const {
1064     return (getGeneration() >= EVERGREEN);
1065   }
1066 
1067   bool hasFMA() const { return FMA; }
1068 
1069   bool hasCFAluBug() const { return CFALUBug; }
1070 
1071   bool hasVertexCache() const { return HasVertexCache; }
1072 
1073   short getTexVTXClauseSize() const { return TexVTXClauseSize; }
1074 
1075   bool enableMachineScheduler() const override {
1076     return true;
1077   }
1078 
1079   bool enableSubRegLiveness() const override {
1080     return true;
1081   }
1082 
1083   /// \returns Maximum number of work groups per compute unit supported by the
1084   /// subtarget and limited by given \p FlatWorkGroupSize.
1085   unsigned getMaxWorkGroupsPerCU(unsigned FlatWorkGroupSize) const override {
1086     return AMDGPU::IsaInfo::getMaxWorkGroupsPerCU(this, FlatWorkGroupSize);
1087   }
1088 
1089   /// \returns Minimum flat work group size supported by the subtarget.
1090   unsigned getMinFlatWorkGroupSize() const override {
1091     return AMDGPU::IsaInfo::getMinFlatWorkGroupSize(this);
1092   }
1093 
1094   /// \returns Maximum flat work group size supported by the subtarget.
1095   unsigned getMaxFlatWorkGroupSize() const override {
1096     return AMDGPU::IsaInfo::getMaxFlatWorkGroupSize(this);
1097   }
1098 
1099   /// \returns Maximum number of waves per execution unit supported by the
1100   /// subtarget and limited by given \p FlatWorkGroupSize.
1101   unsigned getMaxWavesPerEU(unsigned FlatWorkGroupSize) const override {
1102     return AMDGPU::IsaInfo::getMaxWavesPerEU(this, FlatWorkGroupSize);
1103   }
1104 
1105   /// \returns Minimum number of waves per execution unit supported by the
1106   /// subtarget.
1107   unsigned getMinWavesPerEU() const override {
1108     return AMDGPU::IsaInfo::getMinWavesPerEU(this);
1109   }
1110 };
1111 
1112 } // end namespace llvm
1113 
1114 #endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUSUBTARGET_H
1115