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 /// \brief 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 "R600InstrInfo.h"
20 #include "R600ISelLowering.h"
21 #include "R600FrameLowering.h"
22 #include "SIInstrInfo.h"
23 #include "SIISelLowering.h"
24 #include "SIFrameLowering.h"
25 #include "Utils/AMDGPUBaseInfo.h"
26 #include "llvm/ADT/Triple.h"
27 #include "llvm/CodeGen/GlobalISel/GISelAccessor.h"
28 #include "llvm/CodeGen/MachineFunction.h"
29 #include "llvm/CodeGen/SelectionDAGTargetInfo.h"
30 #include "llvm/MC/MCInstrItineraries.h"
31 #include "llvm/Support/MathExtras.h"
32 #include <cassert>
33 #include <cstdint>
34 #include <memory>
35 #include <utility>
36 
37 #define GET_SUBTARGETINFO_HEADER
38 #include "AMDGPUGenSubtargetInfo.inc"
39 
40 namespace llvm {
41 
42 class StringRef;
43 
44 class AMDGPUSubtarget : public AMDGPUGenSubtargetInfo {
45 public:
46   enum Generation {
47     R600 = 0,
48     R700,
49     EVERGREEN,
50     NORTHERN_ISLANDS,
51     SOUTHERN_ISLANDS,
52     SEA_ISLANDS,
53     VOLCANIC_ISLANDS,
54     GFX9,
55   };
56 
57   enum {
58     ISAVersion0_0_0,
59     ISAVersion7_0_0,
60     ISAVersion7_0_1,
61     ISAVersion7_0_2,
62     ISAVersion8_0_0,
63     ISAVersion8_0_1,
64     ISAVersion8_0_2,
65     ISAVersion8_0_3,
66     ISAVersion8_0_4,
67     ISAVersion8_1_0,
68     ISAVersion9_0_0,
69     ISAVersion9_0_1
70   };
71 
72   enum TrapHandlerAbi {
73     TrapHandlerAbiNone = 0,
74     TrapHandlerAbiHsa = 1
75   };
76 
77   enum TrapID {
78     TrapIDHardwareReserved = 0,
79     TrapIDHSADebugTrap = 1,
80     TrapIDLLVMTrap = 2,
81     TrapIDLLVMDebugTrap = 3,
82     TrapIDDebugBreakpoint = 7,
83     TrapIDDebugReserved8 = 8,
84     TrapIDDebugReservedFE = 0xfe,
85     TrapIDDebugReservedFF = 0xff
86   };
87 
88   enum TrapRegValues {
89     LLVMTrapHandlerRegValue = 1
90   };
91 
92 protected:
93   // Basic subtarget description.
94   Triple TargetTriple;
95   Generation Gen;
96   unsigned IsaVersion;
97   unsigned WavefrontSize;
98   int LocalMemorySize;
99   int LDSBankCount;
100   unsigned MaxPrivateElementSize;
101 
102   // Possibly statically set by tablegen, but may want to be overridden.
103   bool FastFMAF32;
104   bool HalfRate64Ops;
105 
106   // Dynamially set bits that enable features.
107   bool FP32Denormals;
108   bool FP64FP16Denormals;
109   bool FPExceptions;
110   bool DX10Clamp;
111   bool FlatForGlobal;
112   bool UnalignedScratchAccess;
113   bool UnalignedBufferAccess;
114   bool HasApertureRegs;
115   bool EnableXNACK;
116   bool TrapHandler;
117   bool DebuggerInsertNops;
118   bool DebuggerReserveRegs;
119   bool DebuggerEmitPrologue;
120 
121   // Used as options.
122   bool EnableVGPRSpilling;
123   bool EnablePromoteAlloca;
124   bool EnableLoadStoreOpt;
125   bool EnableUnsafeDSOffsetFolding;
126   bool EnableSIScheduler;
127   bool DumpCode;
128 
129   // Subtarget statically properties set by tablegen
130   bool FP64;
131   bool IsGCN;
132   bool GCN1Encoding;
133   bool GCN3Encoding;
134   bool CIInsts;
135   bool GFX9Insts;
136   bool SGPRInitBug;
137   bool HasSMemRealTime;
138   bool Has16BitInsts;
139   bool HasVOP3PInsts;
140   bool HasMovrel;
141   bool HasVGPRIndexMode;
142   bool HasScalarStores;
143   bool HasInv2PiInlineImm;
144   bool HasSDWA;
145   bool HasDPP;
146   bool FlatAddressSpace;
147   bool R600ALUInst;
148   bool CaymanISA;
149   bool CFALUBug;
150   bool HasVertexCache;
151   short TexVTXClauseSize;
152   bool ScalarizeGlobal;
153 
154   // Dummy feature to use for assembler in tablegen.
155   bool FeatureDisable;
156 
157   InstrItineraryData InstrItins;
158   SelectionDAGTargetInfo TSInfo;
159 
160 public:
161   AMDGPUSubtarget(const Triple &TT, StringRef GPU, StringRef FS,
162                   const TargetMachine &TM);
163   ~AMDGPUSubtarget() override;
164 
165   AMDGPUSubtarget &initializeSubtargetDependencies(const Triple &TT,
166                                                    StringRef GPU, StringRef FS);
167 
168   const AMDGPUInstrInfo *getInstrInfo() const override = 0;
169   const AMDGPUFrameLowering *getFrameLowering() const override = 0;
170   const AMDGPUTargetLowering *getTargetLowering() const override = 0;
171   const AMDGPURegisterInfo *getRegisterInfo() const override = 0;
172 
173   const InstrItineraryData *getInstrItineraryData() const override {
174     return &InstrItins;
175   }
176 
177   // Nothing implemented, just prevent crashes on use.
178   const SelectionDAGTargetInfo *getSelectionDAGInfo() const override {
179     return &TSInfo;
180   }
181 
182   void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
183 
184   bool isAmdHsaOS() const {
185     return TargetTriple.getOS() == Triple::AMDHSA;
186   }
187 
188   bool isMesa3DOS() const {
189     return TargetTriple.getOS() == Triple::Mesa3D;
190   }
191 
192   bool isOpenCLEnv() const {
193     return TargetTriple.getEnvironment() == Triple::OpenCL;
194   }
195 
196   Generation getGeneration() const {
197     return Gen;
198   }
199 
200   unsigned getWavefrontSize() const {
201     return WavefrontSize;
202   }
203 
204   int getLocalMemorySize() const {
205     return LocalMemorySize;
206   }
207 
208   int getLDSBankCount() const {
209     return LDSBankCount;
210   }
211 
212   unsigned getMaxPrivateElementSize() const {
213     return MaxPrivateElementSize;
214   }
215 
216   bool has16BitInsts() const {
217     return Has16BitInsts;
218   }
219 
220   bool hasVOP3PInsts() const {
221     return HasVOP3PInsts;
222   }
223 
224   bool hasHWFP64() const {
225     return FP64;
226   }
227 
228   bool hasFastFMAF32() const {
229     return FastFMAF32;
230   }
231 
232   bool hasHalfRate64Ops() const {
233     return HalfRate64Ops;
234   }
235 
236   bool hasAddr64() const {
237     return (getGeneration() < VOLCANIC_ISLANDS);
238   }
239 
240   bool hasBFE() const {
241     return (getGeneration() >= EVERGREEN);
242   }
243 
244   bool hasBFI() const {
245     return (getGeneration() >= EVERGREEN);
246   }
247 
248   bool hasBFM() const {
249     return hasBFE();
250   }
251 
252   bool hasBCNT(unsigned Size) const {
253     if (Size == 32)
254       return (getGeneration() >= EVERGREEN);
255 
256     if (Size == 64)
257       return (getGeneration() >= SOUTHERN_ISLANDS);
258 
259     return false;
260   }
261 
262   bool hasMulU24() const {
263     return (getGeneration() >= EVERGREEN);
264   }
265 
266   bool hasMulI24() const {
267     return (getGeneration() >= SOUTHERN_ISLANDS ||
268             hasCaymanISA());
269   }
270 
271   bool hasFFBL() const {
272     return (getGeneration() >= EVERGREEN);
273   }
274 
275   bool hasFFBH() const {
276     return (getGeneration() >= EVERGREEN);
277   }
278 
279   bool hasMed3_16() const {
280     return getGeneration() >= GFX9;
281   }
282 
283   bool hasCARRY() const {
284     return (getGeneration() >= EVERGREEN);
285   }
286 
287   bool hasBORROW() const {
288     return (getGeneration() >= EVERGREEN);
289   }
290 
291   bool hasCaymanISA() const {
292     return CaymanISA;
293   }
294 
295   TrapHandlerAbi getTrapHandlerAbi() const {
296     return isAmdHsaOS() ? TrapHandlerAbiHsa : TrapHandlerAbiNone;
297   }
298 
299   bool isPromoteAllocaEnabled() const {
300     return EnablePromoteAlloca;
301   }
302 
303   bool unsafeDSOffsetFoldingEnabled() const {
304     return EnableUnsafeDSOffsetFolding;
305   }
306 
307   bool dumpCode() const {
308     return DumpCode;
309   }
310 
311   /// Return the amount of LDS that can be used that will not restrict the
312   /// occupancy lower than WaveCount.
313   unsigned getMaxLocalMemSizeWithWaveCount(unsigned WaveCount,
314                                            const Function &) const;
315 
316   /// Inverse of getMaxLocalMemWithWaveCount. Return the maximum wavecount if
317   /// the given LDS memory size is the only constraint.
318   unsigned getOccupancyWithLocalMemSize(uint32_t Bytes, const Function &) const;
319 
320   bool hasFP16Denormals() const {
321     return FP64FP16Denormals;
322   }
323 
324   bool hasFP32Denormals() const {
325     return FP32Denormals;
326   }
327 
328   bool hasFP64Denormals() const {
329     return FP64FP16Denormals;
330   }
331 
332   bool hasFPExceptions() const {
333     return FPExceptions;
334   }
335 
336   bool enableDX10Clamp() const {
337     return DX10Clamp;
338   }
339 
340   bool enableIEEEBit(const MachineFunction &MF) const {
341     return AMDGPU::isCompute(MF.getFunction()->getCallingConv());
342   }
343 
344   bool useFlatForGlobal() const {
345     return FlatForGlobal;
346   }
347 
348   bool hasUnalignedBufferAccess() const {
349     return UnalignedBufferAccess;
350   }
351 
352   bool hasUnalignedScratchAccess() const {
353     return UnalignedScratchAccess;
354   }
355 
356   bool hasApertureRegs() const {
357    return HasApertureRegs;
358   }
359 
360   bool isTrapHandlerEnabled() const {
361     return TrapHandler;
362   }
363 
364   bool isXNACKEnabled() const {
365     return EnableXNACK;
366   }
367 
368   bool hasFlatAddressSpace() const {
369     return FlatAddressSpace;
370   }
371 
372   bool isMesaKernel(const MachineFunction &MF) const {
373     return isMesa3DOS() && !AMDGPU::isShader(MF.getFunction()->getCallingConv());
374   }
375 
376   // Covers VS/PS/CS graphics shaders
377   bool isMesaGfxShader(const MachineFunction &MF) const {
378     return isMesa3DOS() && AMDGPU::isShader(MF.getFunction()->getCallingConv());
379   }
380 
381   bool isAmdCodeObjectV2(const MachineFunction &MF) const {
382     return isAmdHsaOS() || isMesaKernel(MF);
383   }
384 
385   bool hasFminFmaxLegacy() const {
386     return getGeneration() < AMDGPUSubtarget::VOLCANIC_ISLANDS;
387   }
388 
389   /// \brief Returns the offset in bytes from the start of the input buffer
390   ///        of the first explicit kernel argument.
391   unsigned getExplicitKernelArgOffset(const MachineFunction &MF) const {
392     return isAmdCodeObjectV2(MF) ? 0 : 36;
393   }
394 
395   unsigned getAlignmentForImplicitArgPtr() const {
396     return isAmdHsaOS() ? 8 : 4;
397   }
398 
399   unsigned getImplicitArgNumBytes(const MachineFunction &MF) const {
400     if (isMesaKernel(MF))
401       return 16;
402     if (isAmdHsaOS() && isOpenCLEnv())
403       return 32;
404     return 0;
405   }
406 
407   unsigned getStackAlignment() const {
408     // Scratch is allocated in 256 dword per wave blocks.
409     return 4 * 256 / getWavefrontSize();
410   }
411 
412   bool enableMachineScheduler() const override {
413     return true;
414   }
415 
416   bool enableSubRegLiveness() const override {
417     return true;
418   }
419 
420   void setScalarizeGlobalBehavior(bool b) { ScalarizeGlobal = b;}
421   bool getScalarizeGlobalBehavior() const { return ScalarizeGlobal;}
422 
423   /// \returns Number of execution units per compute unit supported by the
424   /// subtarget.
425   unsigned getEUsPerCU() const {
426     return AMDGPU::IsaInfo::getEUsPerCU(getFeatureBits());
427   }
428 
429   /// \returns Maximum number of work groups per compute unit supported by the
430   /// subtarget and limited by given \p FlatWorkGroupSize.
431   unsigned getMaxWorkGroupsPerCU(unsigned FlatWorkGroupSize) const {
432     return AMDGPU::IsaInfo::getMaxWorkGroupsPerCU(getFeatureBits(),
433                                                   FlatWorkGroupSize);
434   }
435 
436   /// \returns Maximum number of waves per compute unit supported by the
437   /// subtarget without any kind of limitation.
438   unsigned getMaxWavesPerCU() const {
439     return AMDGPU::IsaInfo::getMaxWavesPerCU(getFeatureBits());
440   }
441 
442   /// \returns Maximum number of waves per compute unit supported by the
443   /// subtarget and limited by given \p FlatWorkGroupSize.
444   unsigned getMaxWavesPerCU(unsigned FlatWorkGroupSize) const {
445     return AMDGPU::IsaInfo::getMaxWavesPerCU(getFeatureBits(),
446                                              FlatWorkGroupSize);
447   }
448 
449   /// \returns Minimum number of waves per execution unit supported by the
450   /// subtarget.
451   unsigned getMinWavesPerEU() const {
452     return AMDGPU::IsaInfo::getMinWavesPerEU(getFeatureBits());
453   }
454 
455   /// \returns Maximum number of waves per execution unit supported by the
456   /// subtarget without any kind of limitation.
457   unsigned getMaxWavesPerEU() const {
458     return AMDGPU::IsaInfo::getMaxWavesPerEU(getFeatureBits());
459   }
460 
461   /// \returns Maximum number of waves per execution unit supported by the
462   /// subtarget and limited by given \p FlatWorkGroupSize.
463   unsigned getMaxWavesPerEU(unsigned FlatWorkGroupSize) const {
464     return AMDGPU::IsaInfo::getMaxWavesPerEU(getFeatureBits(),
465                                              FlatWorkGroupSize);
466   }
467 
468   /// \returns Minimum flat work group size supported by the subtarget.
469   unsigned getMinFlatWorkGroupSize() const {
470     return AMDGPU::IsaInfo::getMinFlatWorkGroupSize(getFeatureBits());
471   }
472 
473   /// \returns Maximum flat work group size supported by the subtarget.
474   unsigned getMaxFlatWorkGroupSize() const {
475     return AMDGPU::IsaInfo::getMaxFlatWorkGroupSize(getFeatureBits());
476   }
477 
478   /// \returns Number of waves per work group supported by the subtarget and
479   /// limited by given \p FlatWorkGroupSize.
480   unsigned getWavesPerWorkGroup(unsigned FlatWorkGroupSize) const {
481     return AMDGPU::IsaInfo::getWavesPerWorkGroup(getFeatureBits(),
482                                                  FlatWorkGroupSize);
483   }
484 
485   /// \returns Subtarget's default pair of minimum/maximum flat work group sizes
486   /// for function \p F, or minimum/maximum flat work group sizes explicitly
487   /// requested using "amdgpu-flat-work-group-size" attribute attached to
488   /// function \p F.
489   ///
490   /// \returns Subtarget's default values if explicitly requested values cannot
491   /// be converted to integer, or violate subtarget's specifications.
492   std::pair<unsigned, unsigned> getFlatWorkGroupSizes(const Function &F) const;
493 
494   /// \returns Subtarget's default pair of minimum/maximum number of waves per
495   /// execution unit for function \p F, or minimum/maximum number of waves per
496   /// execution unit explicitly requested using "amdgpu-waves-per-eu" attribute
497   /// attached to function \p F.
498   ///
499   /// \returns Subtarget's default values if explicitly requested values cannot
500   /// be converted to integer, violate subtarget's specifications, or are not
501   /// compatible with minimum/maximum number of waves limited by flat work group
502   /// size, register usage, and/or lds usage.
503   std::pair<unsigned, unsigned> getWavesPerEU(const Function &F) const;
504 };
505 
506 class R600Subtarget final : public AMDGPUSubtarget {
507 private:
508   R600InstrInfo InstrInfo;
509   R600FrameLowering FrameLowering;
510   R600TargetLowering TLInfo;
511 
512 public:
513   R600Subtarget(const Triple &TT, StringRef CPU, StringRef FS,
514                 const TargetMachine &TM);
515 
516   const R600InstrInfo *getInstrInfo() const override {
517     return &InstrInfo;
518   }
519 
520   const R600FrameLowering *getFrameLowering() const override {
521     return &FrameLowering;
522   }
523 
524   const R600TargetLowering *getTargetLowering() const override {
525     return &TLInfo;
526   }
527 
528   const R600RegisterInfo *getRegisterInfo() const override {
529     return &InstrInfo.getRegisterInfo();
530   }
531 
532   bool hasCFAluBug() const {
533     return CFALUBug;
534   }
535 
536   bool hasVertexCache() const {
537     return HasVertexCache;
538   }
539 
540   short getTexVTXClauseSize() const {
541     return TexVTXClauseSize;
542   }
543 };
544 
545 class SISubtarget final : public AMDGPUSubtarget {
546 private:
547   SIInstrInfo InstrInfo;
548   SIFrameLowering FrameLowering;
549   SITargetLowering TLInfo;
550   std::unique_ptr<GISelAccessor> GISel;
551 
552 public:
553   SISubtarget(const Triple &TT, StringRef CPU, StringRef FS,
554               const TargetMachine &TM);
555 
556   const SIInstrInfo *getInstrInfo() const override {
557     return &InstrInfo;
558   }
559 
560   const SIFrameLowering *getFrameLowering() const override {
561     return &FrameLowering;
562   }
563 
564   const SITargetLowering *getTargetLowering() const override {
565     return &TLInfo;
566   }
567 
568   const CallLowering *getCallLowering() const override {
569     assert(GISel && "Access to GlobalISel APIs not set");
570     return GISel->getCallLowering();
571   }
572 
573   const InstructionSelector *getInstructionSelector() const override {
574     assert(GISel && "Access to GlobalISel APIs not set");
575     return GISel->getInstructionSelector();
576   }
577 
578   const LegalizerInfo *getLegalizerInfo() const override {
579     assert(GISel && "Access to GlobalISel APIs not set");
580     return GISel->getLegalizerInfo();
581   }
582 
583   const RegisterBankInfo *getRegBankInfo() const override {
584     assert(GISel && "Access to GlobalISel APIs not set");
585     return GISel->getRegBankInfo();
586   }
587 
588   const SIRegisterInfo *getRegisterInfo() const override {
589     return &InstrInfo.getRegisterInfo();
590   }
591 
592   void setGISelAccessor(GISelAccessor &GISel) {
593     this->GISel.reset(&GISel);
594   }
595 
596   // XXX - Why is this here if it isn't in the default pass set?
597   bool enableEarlyIfConversion() const override {
598     return true;
599   }
600 
601   void overrideSchedPolicy(MachineSchedPolicy &Policy,
602                            unsigned NumRegionInstrs) const override;
603 
604   bool isVGPRSpillingEnabled(const Function& F) const;
605 
606   unsigned getMaxNumUserSGPRs() const {
607     return 16;
608   }
609 
610   bool hasSMemRealTime() const {
611     return HasSMemRealTime;
612   }
613 
614   bool hasMovrel() const {
615     return HasMovrel;
616   }
617 
618   bool hasVGPRIndexMode() const {
619     return HasVGPRIndexMode;
620   }
621 
622   bool hasScalarCompareEq64() const {
623     return getGeneration() >= VOLCANIC_ISLANDS;
624   }
625 
626   bool hasScalarStores() const {
627     return HasScalarStores;
628   }
629 
630   bool hasInv2PiInlineImm() const {
631     return HasInv2PiInlineImm;
632   }
633 
634   bool hasSDWA() const {
635     return HasSDWA;
636   }
637 
638   bool hasDPP() const {
639     return HasDPP;
640   }
641 
642   bool enableSIScheduler() const {
643     return EnableSIScheduler;
644   }
645 
646   bool debuggerSupported() const {
647     return debuggerInsertNops() && debuggerReserveRegs() &&
648       debuggerEmitPrologue();
649   }
650 
651   bool debuggerInsertNops() const {
652     return DebuggerInsertNops;
653   }
654 
655   bool debuggerReserveRegs() const {
656     return DebuggerReserveRegs;
657   }
658 
659   bool debuggerEmitPrologue() const {
660     return DebuggerEmitPrologue;
661   }
662 
663   bool loadStoreOptEnabled() const {
664     return EnableLoadStoreOpt;
665   }
666 
667   bool hasSGPRInitBug() const {
668     return SGPRInitBug;
669   }
670 
671   bool has12DWordStoreHazard() const {
672     return getGeneration() != AMDGPUSubtarget::SOUTHERN_ISLANDS;
673   }
674 
675   bool hasSMovFedHazard() const {
676     return getGeneration() >= AMDGPUSubtarget::GFX9;
677   }
678 
679   bool hasReadM0Hazard() const {
680     return getGeneration() >= AMDGPUSubtarget::GFX9;
681   }
682 
683   unsigned getKernArgSegmentSize(const MachineFunction &MF, unsigned ExplictArgBytes) const;
684 
685   /// Return the maximum number of waves per SIMD for kernels using \p SGPRs SGPRs
686   unsigned getOccupancyWithNumSGPRs(unsigned SGPRs) const;
687 
688   /// Return the maximum number of waves per SIMD for kernels using \p VGPRs VGPRs
689   unsigned getOccupancyWithNumVGPRs(unsigned VGPRs) const;
690 
691   /// \returns True if waitcnt instruction is needed before barrier instruction,
692   /// false otherwise.
693   bool needWaitcntBeforeBarrier() const {
694     return getGeneration() < GFX9;
695   }
696 
697   /// \returns true if the flat_scratch register should be initialized with the
698   /// pointer to the wave's scratch memory rather than a size and offset.
699   bool flatScratchIsPointer() const {
700     return getGeneration() >= GFX9;
701   }
702 
703   /// \returns SGPR allocation granularity supported by the subtarget.
704   unsigned getSGPRAllocGranule() const {
705     return AMDGPU::IsaInfo::getSGPRAllocGranule(getFeatureBits());
706   }
707 
708   /// \returns SGPR encoding granularity supported by the subtarget.
709   unsigned getSGPREncodingGranule() const {
710     return AMDGPU::IsaInfo::getSGPREncodingGranule(getFeatureBits());
711   }
712 
713   /// \returns Total number of SGPRs supported by the subtarget.
714   unsigned getTotalNumSGPRs() const {
715     return AMDGPU::IsaInfo::getTotalNumSGPRs(getFeatureBits());
716   }
717 
718   /// \returns Addressable number of SGPRs supported by the subtarget.
719   unsigned getAddressableNumSGPRs() const {
720     return AMDGPU::IsaInfo::getAddressableNumSGPRs(getFeatureBits());
721   }
722 
723   /// \returns Minimum number of SGPRs that meets the given number of waves per
724   /// execution unit requirement supported by the subtarget.
725   unsigned getMinNumSGPRs(unsigned WavesPerEU) const {
726     return AMDGPU::IsaInfo::getMinNumSGPRs(getFeatureBits(), WavesPerEU);
727   }
728 
729   /// \returns Maximum number of SGPRs that meets the given number of waves per
730   /// execution unit requirement supported by the subtarget.
731   unsigned getMaxNumSGPRs(unsigned WavesPerEU, bool Addressable) const {
732     return AMDGPU::IsaInfo::getMaxNumSGPRs(getFeatureBits(), WavesPerEU,
733                                            Addressable);
734   }
735 
736   /// \returns Reserved number of SGPRs for given function \p MF.
737   unsigned getReservedNumSGPRs(const MachineFunction &MF) const;
738 
739   /// \returns Maximum number of SGPRs that meets number of waves per execution
740   /// unit requirement for function \p MF, or number of SGPRs explicitly
741   /// requested using "amdgpu-num-sgpr" attribute attached to function \p MF.
742   ///
743   /// \returns Value that meets number of waves per execution unit requirement
744   /// if explicitly requested value cannot be converted to integer, violates
745   /// subtarget's specifications, or does not meet number of waves per execution
746   /// unit requirement.
747   unsigned getMaxNumSGPRs(const MachineFunction &MF) const;
748 
749   /// \returns VGPR allocation granularity supported by the subtarget.
750   unsigned getVGPRAllocGranule() const {
751     return AMDGPU::IsaInfo::getVGPRAllocGranule(getFeatureBits());;
752   }
753 
754   /// \returns VGPR encoding granularity supported by the subtarget.
755   unsigned getVGPREncodingGranule() const {
756     return AMDGPU::IsaInfo::getVGPREncodingGranule(getFeatureBits());
757   }
758 
759   /// \returns Total number of VGPRs supported by the subtarget.
760   unsigned getTotalNumVGPRs() const {
761     return AMDGPU::IsaInfo::getTotalNumVGPRs(getFeatureBits());
762   }
763 
764   /// \returns Addressable number of VGPRs supported by the subtarget.
765   unsigned getAddressableNumVGPRs() const {
766     return AMDGPU::IsaInfo::getAddressableNumVGPRs(getFeatureBits());
767   }
768 
769   /// \returns Minimum number of VGPRs that meets given number of waves per
770   /// execution unit requirement supported by the subtarget.
771   unsigned getMinNumVGPRs(unsigned WavesPerEU) const {
772     return AMDGPU::IsaInfo::getMinNumVGPRs(getFeatureBits(), WavesPerEU);
773   }
774 
775   /// \returns Maximum number of VGPRs that meets given number of waves per
776   /// execution unit requirement supported by the subtarget.
777   unsigned getMaxNumVGPRs(unsigned WavesPerEU) const {
778     return AMDGPU::IsaInfo::getMaxNumVGPRs(getFeatureBits(), WavesPerEU);
779   }
780 
781   /// \returns Reserved number of VGPRs for given function \p MF.
782   unsigned getReservedNumVGPRs(const MachineFunction &MF) const {
783     return debuggerReserveRegs() ? 4 : 0;
784   }
785 
786   /// \returns Maximum number of VGPRs that meets number of waves per execution
787   /// unit requirement for function \p MF, or number of VGPRs explicitly
788   /// requested using "amdgpu-num-vgpr" attribute attached to function \p MF.
789   ///
790   /// \returns Value that meets number of waves per execution unit requirement
791   /// if explicitly requested value cannot be converted to integer, violates
792   /// subtarget's specifications, or does not meet number of waves per execution
793   /// unit requirement.
794   unsigned getMaxNumVGPRs(const MachineFunction &MF) const;
795 };
796 
797 } // end namespace llvm
798 
799 #endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUSUBTARGET_H
800