xref: /aosp_15_r20/external/llvm/lib/Target/AMDGPU/SIRegisterInfo.h (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- SIRegisterInfo.h - SI Register Info Interface ----------*- C++ -*--===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker /// \file
11*9880d681SAndroid Build Coastguard Worker /// \brief Interface definition for SIRegisterInfo
12*9880d681SAndroid Build Coastguard Worker //
13*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
14*9880d681SAndroid Build Coastguard Worker 
15*9880d681SAndroid Build Coastguard Worker #ifndef LLVM_LIB_TARGET_AMDGPU_SIREGISTERINFO_H
16*9880d681SAndroid Build Coastguard Worker #define LLVM_LIB_TARGET_AMDGPU_SIREGISTERINFO_H
17*9880d681SAndroid Build Coastguard Worker 
18*9880d681SAndroid Build Coastguard Worker #include "AMDGPURegisterInfo.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
20*9880d681SAndroid Build Coastguard Worker 
21*9880d681SAndroid Build Coastguard Worker namespace llvm {
22*9880d681SAndroid Build Coastguard Worker 
23*9880d681SAndroid Build Coastguard Worker class SISubtarget;
24*9880d681SAndroid Build Coastguard Worker class MachineRegisterInfo;
25*9880d681SAndroid Build Coastguard Worker 
26*9880d681SAndroid Build Coastguard Worker struct SIRegisterInfo final : public AMDGPURegisterInfo {
27*9880d681SAndroid Build Coastguard Worker private:
28*9880d681SAndroid Build Coastguard Worker   unsigned SGPR32SetID;
29*9880d681SAndroid Build Coastguard Worker   unsigned VGPR32SetID;
30*9880d681SAndroid Build Coastguard Worker   BitVector SGPRPressureSets;
31*9880d681SAndroid Build Coastguard Worker   BitVector VGPRPressureSets;
32*9880d681SAndroid Build Coastguard Worker 
33*9880d681SAndroid Build Coastguard Worker   void reserveRegisterTuples(BitVector &, unsigned Reg) const;
34*9880d681SAndroid Build Coastguard Worker   void classifyPressureSet(unsigned PSetID, unsigned Reg,
35*9880d681SAndroid Build Coastguard Worker                            BitVector &PressureSets) const;
36*9880d681SAndroid Build Coastguard Worker 
37*9880d681SAndroid Build Coastguard Worker public:
38*9880d681SAndroid Build Coastguard Worker   SIRegisterInfo();
39*9880d681SAndroid Build Coastguard Worker 
40*9880d681SAndroid Build Coastguard Worker   /// Return the end register initially reserved for the scratch buffer in case
41*9880d681SAndroid Build Coastguard Worker   /// spilling is needed.
42*9880d681SAndroid Build Coastguard Worker   unsigned reservedPrivateSegmentBufferReg(const MachineFunction &MF) const;
43*9880d681SAndroid Build Coastguard Worker 
44*9880d681SAndroid Build Coastguard Worker   /// Return the end register initially reserved for the scratch wave offset in
45*9880d681SAndroid Build Coastguard Worker   /// case spilling is needed.
46*9880d681SAndroid Build Coastguard Worker   unsigned reservedPrivateSegmentWaveByteOffsetReg(
47*9880d681SAndroid Build Coastguard Worker     const MachineFunction &MF) const;
48*9880d681SAndroid Build Coastguard Worker 
49*9880d681SAndroid Build Coastguard Worker   BitVector getReservedRegs(const MachineFunction &MF) const override;
50*9880d681SAndroid Build Coastguard Worker 
51*9880d681SAndroid Build Coastguard Worker   unsigned getRegPressureSetLimit(const MachineFunction &MF,
52*9880d681SAndroid Build Coastguard Worker                                   unsigned Idx) const override;
53*9880d681SAndroid Build Coastguard Worker 
54*9880d681SAndroid Build Coastguard Worker 
55*9880d681SAndroid Build Coastguard Worker   bool requiresRegisterScavenging(const MachineFunction &Fn) const override;
56*9880d681SAndroid Build Coastguard Worker 
57*9880d681SAndroid Build Coastguard Worker 
58*9880d681SAndroid Build Coastguard Worker   bool requiresFrameIndexScavenging(const MachineFunction &MF) const override;
59*9880d681SAndroid Build Coastguard Worker   bool requiresVirtualBaseRegisters(const MachineFunction &Fn) const override;
60*9880d681SAndroid Build Coastguard Worker   bool trackLivenessAfterRegAlloc(const MachineFunction &MF) const override;
61*9880d681SAndroid Build Coastguard Worker 
62*9880d681SAndroid Build Coastguard Worker   int64_t getFrameIndexInstrOffset(const MachineInstr *MI,
63*9880d681SAndroid Build Coastguard Worker                                    int Idx) const override;
64*9880d681SAndroid Build Coastguard Worker 
65*9880d681SAndroid Build Coastguard Worker   bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override;
66*9880d681SAndroid Build Coastguard Worker 
67*9880d681SAndroid Build Coastguard Worker   void materializeFrameBaseRegister(MachineBasicBlock *MBB,
68*9880d681SAndroid Build Coastguard Worker                                     unsigned BaseReg, int FrameIdx,
69*9880d681SAndroid Build Coastguard Worker                                     int64_t Offset) const override;
70*9880d681SAndroid Build Coastguard Worker 
71*9880d681SAndroid Build Coastguard Worker   void resolveFrameIndex(MachineInstr &MI, unsigned BaseReg,
72*9880d681SAndroid Build Coastguard Worker                          int64_t Offset) const override;
73*9880d681SAndroid Build Coastguard Worker 
74*9880d681SAndroid Build Coastguard Worker   bool isFrameOffsetLegal(const MachineInstr *MI, unsigned BaseReg,
75*9880d681SAndroid Build Coastguard Worker                           int64_t Offset) const override;
76*9880d681SAndroid Build Coastguard Worker 
77*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *getPointerRegClass(
78*9880d681SAndroid Build Coastguard Worker     const MachineFunction &MF, unsigned Kind = 0) const override;
79*9880d681SAndroid Build Coastguard Worker 
80*9880d681SAndroid Build Coastguard Worker   void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
81*9880d681SAndroid Build Coastguard Worker                            unsigned FIOperandNum,
82*9880d681SAndroid Build Coastguard Worker                            RegScavenger *RS) const override;
83*9880d681SAndroid Build Coastguard Worker 
getHWRegIndexfinal84*9880d681SAndroid Build Coastguard Worker   unsigned getHWRegIndex(unsigned Reg) const {
85*9880d681SAndroid Build Coastguard Worker     return getEncodingValue(Reg) & 0xff;
86*9880d681SAndroid Build Coastguard Worker   }
87*9880d681SAndroid Build Coastguard Worker 
88*9880d681SAndroid Build Coastguard Worker   /// \brief Return the 'base' register class for this register.
89*9880d681SAndroid Build Coastguard Worker   /// e.g. SGPR0 => SReg_32, VGPR => VGPR_32 SGPR0_SGPR1 -> SReg_32, etc.
90*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *getPhysRegClass(unsigned Reg) const;
91*9880d681SAndroid Build Coastguard Worker 
92*9880d681SAndroid Build Coastguard Worker   /// \returns true if this class contains only SGPR registers
isSGPRClassfinal93*9880d681SAndroid Build Coastguard Worker   bool isSGPRClass(const TargetRegisterClass *RC) const {
94*9880d681SAndroid Build Coastguard Worker     return !hasVGPRs(RC);
95*9880d681SAndroid Build Coastguard Worker   }
96*9880d681SAndroid Build Coastguard Worker 
97*9880d681SAndroid Build Coastguard Worker   /// \returns true if this class ID contains only SGPR registers
isSGPRClassIDfinal98*9880d681SAndroid Build Coastguard Worker   bool isSGPRClassID(unsigned RCID) const {
99*9880d681SAndroid Build Coastguard Worker     return isSGPRClass(getRegClass(RCID));
100*9880d681SAndroid Build Coastguard Worker   }
101*9880d681SAndroid Build Coastguard Worker 
isSGPRRegfinal102*9880d681SAndroid Build Coastguard Worker   bool isSGPRReg(const MachineRegisterInfo &MRI, unsigned Reg) const {
103*9880d681SAndroid Build Coastguard Worker     const TargetRegisterClass *RC;
104*9880d681SAndroid Build Coastguard Worker     if (TargetRegisterInfo::isVirtualRegister(Reg))
105*9880d681SAndroid Build Coastguard Worker       RC = MRI.getRegClass(Reg);
106*9880d681SAndroid Build Coastguard Worker     else
107*9880d681SAndroid Build Coastguard Worker       RC = getPhysRegClass(Reg);
108*9880d681SAndroid Build Coastguard Worker     return isSGPRClass(RC);
109*9880d681SAndroid Build Coastguard Worker   }
110*9880d681SAndroid Build Coastguard Worker 
111*9880d681SAndroid Build Coastguard Worker   /// \returns true if this class contains VGPR registers.
112*9880d681SAndroid Build Coastguard Worker   bool hasVGPRs(const TargetRegisterClass *RC) const;
113*9880d681SAndroid Build Coastguard Worker 
114*9880d681SAndroid Build Coastguard Worker   /// returns true if this is a pseudoregister class combination of VGPRs and
115*9880d681SAndroid Build Coastguard Worker   /// SGPRs for operand modeling. FIXME: We should set isAllocatable = 0 on
116*9880d681SAndroid Build Coastguard Worker   /// them.
isPseudoRegClassfinal117*9880d681SAndroid Build Coastguard Worker   static bool isPseudoRegClass(const TargetRegisterClass *RC) {
118*9880d681SAndroid Build Coastguard Worker     return RC == &AMDGPU::VS_32RegClass || RC == &AMDGPU::VS_64RegClass;
119*9880d681SAndroid Build Coastguard Worker   }
120*9880d681SAndroid Build Coastguard Worker 
121*9880d681SAndroid Build Coastguard Worker   /// \returns A VGPR reg class with the same width as \p SRC
122*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *getEquivalentVGPRClass(
123*9880d681SAndroid Build Coastguard Worker                                           const TargetRegisterClass *SRC) const;
124*9880d681SAndroid Build Coastguard Worker 
125*9880d681SAndroid Build Coastguard Worker   /// \returns A SGPR reg class with the same width as \p SRC
126*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *getEquivalentSGPRClass(
127*9880d681SAndroid Build Coastguard Worker                                            const TargetRegisterClass *VRC) const;
128*9880d681SAndroid Build Coastguard Worker 
129*9880d681SAndroid Build Coastguard Worker   /// \returns The register class that is used for a sub-register of \p RC for
130*9880d681SAndroid Build Coastguard Worker   /// the given \p SubIdx.  If \p SubIdx equals NoSubRegister, \p RC will
131*9880d681SAndroid Build Coastguard Worker   /// be returned.
132*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *getSubRegClass(const TargetRegisterClass *RC,
133*9880d681SAndroid Build Coastguard Worker                                             unsigned SubIdx) const;
134*9880d681SAndroid Build Coastguard Worker 
135*9880d681SAndroid Build Coastguard Worker   bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
136*9880d681SAndroid Build Coastguard Worker                             unsigned DefSubReg,
137*9880d681SAndroid Build Coastguard Worker                             const TargetRegisterClass *SrcRC,
138*9880d681SAndroid Build Coastguard Worker                             unsigned SrcSubReg) const override;
139*9880d681SAndroid Build Coastguard Worker 
140*9880d681SAndroid Build Coastguard Worker   /// \p Channel This is the register channel (e.g. a value from 0-16), not the
141*9880d681SAndroid Build Coastguard Worker   ///            SubReg index.
142*9880d681SAndroid Build Coastguard Worker   /// \returns The sub-register of Reg that is in Channel.
143*9880d681SAndroid Build Coastguard Worker   unsigned getPhysRegSubReg(unsigned Reg, const TargetRegisterClass *SubRC,
144*9880d681SAndroid Build Coastguard Worker                             unsigned Channel) const;
145*9880d681SAndroid Build Coastguard Worker 
146*9880d681SAndroid Build Coastguard Worker   /// \returns True if operands defined with this operand type can accept
147*9880d681SAndroid Build Coastguard Worker   /// a literal constant (i.e. any 32-bit immediate).
148*9880d681SAndroid Build Coastguard Worker   bool opCanUseLiteralConstant(unsigned OpType) const;
149*9880d681SAndroid Build Coastguard Worker 
150*9880d681SAndroid Build Coastguard Worker   /// \returns True if operands defined with this operand type can accept
151*9880d681SAndroid Build Coastguard Worker   /// an inline constant. i.e. An integer value in the range (-16, 64) or
152*9880d681SAndroid Build Coastguard Worker   /// -4.0f, -2.0f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 2.0f, 4.0f.
153*9880d681SAndroid Build Coastguard Worker   bool opCanUseInlineConstant(unsigned OpType) const;
154*9880d681SAndroid Build Coastguard Worker 
155*9880d681SAndroid Build Coastguard Worker   enum PreloadedValue {
156*9880d681SAndroid Build Coastguard Worker     // SGPRS:
157*9880d681SAndroid Build Coastguard Worker     PRIVATE_SEGMENT_BUFFER = 0,
158*9880d681SAndroid Build Coastguard Worker     DISPATCH_PTR        =  1,
159*9880d681SAndroid Build Coastguard Worker     QUEUE_PTR           =  2,
160*9880d681SAndroid Build Coastguard Worker     KERNARG_SEGMENT_PTR =  3,
161*9880d681SAndroid Build Coastguard Worker     DISPATCH_ID         =  4,
162*9880d681SAndroid Build Coastguard Worker     FLAT_SCRATCH_INIT   =  5,
163*9880d681SAndroid Build Coastguard Worker     WORKGROUP_ID_X      = 10,
164*9880d681SAndroid Build Coastguard Worker     WORKGROUP_ID_Y      = 11,
165*9880d681SAndroid Build Coastguard Worker     WORKGROUP_ID_Z      = 12,
166*9880d681SAndroid Build Coastguard Worker     PRIVATE_SEGMENT_WAVE_BYTE_OFFSET = 14,
167*9880d681SAndroid Build Coastguard Worker 
168*9880d681SAndroid Build Coastguard Worker     // VGPRS:
169*9880d681SAndroid Build Coastguard Worker     FIRST_VGPR_VALUE    = 15,
170*9880d681SAndroid Build Coastguard Worker     WORKITEM_ID_X       = FIRST_VGPR_VALUE,
171*9880d681SAndroid Build Coastguard Worker     WORKITEM_ID_Y       = 16,
172*9880d681SAndroid Build Coastguard Worker     WORKITEM_ID_Z       = 17
173*9880d681SAndroid Build Coastguard Worker   };
174*9880d681SAndroid Build Coastguard Worker 
175*9880d681SAndroid Build Coastguard Worker   /// \brief Returns the physical register that \p Value is stored in.
176*9880d681SAndroid Build Coastguard Worker   unsigned getPreloadedValue(const MachineFunction &MF,
177*9880d681SAndroid Build Coastguard Worker                              enum PreloadedValue Value) const;
178*9880d681SAndroid Build Coastguard Worker 
179*9880d681SAndroid Build Coastguard Worker   /// \brief Give the maximum number of VGPRs that can be used by \p WaveCount
180*9880d681SAndroid Build Coastguard Worker   ///        concurrent waves.
181*9880d681SAndroid Build Coastguard Worker   unsigned getNumVGPRsAllowed(unsigned WaveCount) const;
182*9880d681SAndroid Build Coastguard Worker 
183*9880d681SAndroid Build Coastguard Worker   /// \brief Give the maximum number of SGPRs that can be used by \p WaveCount
184*9880d681SAndroid Build Coastguard Worker   ///        concurrent waves.
185*9880d681SAndroid Build Coastguard Worker   unsigned getNumSGPRsAllowed(const SISubtarget &ST, unsigned WaveCount) const;
186*9880d681SAndroid Build Coastguard Worker 
187*9880d681SAndroid Build Coastguard Worker   unsigned findUnusedRegister(const MachineRegisterInfo &MRI,
188*9880d681SAndroid Build Coastguard Worker                               const TargetRegisterClass *RC) const;
189*9880d681SAndroid Build Coastguard Worker 
getSGPR32PressureSetfinal190*9880d681SAndroid Build Coastguard Worker   unsigned getSGPR32PressureSet() const { return SGPR32SetID; };
getVGPR32PressureSetfinal191*9880d681SAndroid Build Coastguard Worker   unsigned getVGPR32PressureSet() const { return VGPR32SetID; };
192*9880d681SAndroid Build Coastguard Worker 
193*9880d681SAndroid Build Coastguard Worker   bool isVGPR(const MachineRegisterInfo &MRI, unsigned Reg) const;
194*9880d681SAndroid Build Coastguard Worker 
195*9880d681SAndroid Build Coastguard Worker private:
196*9880d681SAndroid Build Coastguard Worker   void buildScratchLoadStore(MachineBasicBlock::iterator MI,
197*9880d681SAndroid Build Coastguard Worker                              unsigned LoadStoreOp, const MachineOperand *SrcDst,
198*9880d681SAndroid Build Coastguard Worker                              unsigned ScratchRsrcReg, unsigned ScratchOffset,
199*9880d681SAndroid Build Coastguard Worker                              int64_t Offset,
200*9880d681SAndroid Build Coastguard Worker                              RegScavenger *RS) const;
201*9880d681SAndroid Build Coastguard Worker };
202*9880d681SAndroid Build Coastguard Worker 
203*9880d681SAndroid Build Coastguard Worker } // End namespace llvm
204*9880d681SAndroid Build Coastguard Worker 
205*9880d681SAndroid Build Coastguard Worker #endif
206