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