1 //===-- SIRegisterInfo.h - SI Register Info Interface ----------*- C++ -*--===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 /// Interface definition for SIRegisterInfo
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_LIB_TARGET_AMDGPU_SIREGISTERINFO_H
15 #define LLVM_LIB_TARGET_AMDGPU_SIREGISTERINFO_H
17 #include "AMDGPURegisterInfo.h"
18 #include "SIDefines.h"
19 #include "llvm/CodeGen/MachineRegisterInfo.h"
25 class MachineRegisterInfo
;
26 class SIMachineFunctionInfo
;
28 class SIRegisterInfo final
: public AMDGPURegisterInfo
{
30 const GCNSubtarget
&ST
;
34 BitVector SGPRPressureSets
;
35 BitVector VGPRPressureSets
;
36 BitVector AGPRPressureSets
;
40 void classifyPressureSet(unsigned PSetID
, unsigned Reg
,
41 BitVector
&PressureSets
) const;
43 SIRegisterInfo(const GCNSubtarget
&ST
);
45 bool spillSGPRToVGPR() const {
46 return SpillSGPRToVGPR
;
49 /// Return the end register initially reserved for the scratch buffer in case
50 /// spilling is needed.
51 unsigned reservedPrivateSegmentBufferReg(const MachineFunction
&MF
) const;
53 /// Return the end register initially reserved for the scratch wave offset in
54 /// case spilling is needed.
55 unsigned reservedPrivateSegmentWaveByteOffsetReg(
56 const MachineFunction
&MF
) const;
58 BitVector
getReservedRegs(const MachineFunction
&MF
) const override
;
60 const MCPhysReg
*getCalleeSavedRegs(const MachineFunction
*MF
) const override
;
61 const MCPhysReg
*getCalleeSavedRegsViaCopy(const MachineFunction
*MF
) const;
62 const uint32_t *getCallPreservedMask(const MachineFunction
&MF
,
63 CallingConv::ID
) const override
;
65 // Stack access is very expensive. CSRs are also the high registers, and we
66 // want to minimize the number of used registers.
67 unsigned getCSRFirstUseCost() const override
{
71 Register
getFrameRegister(const MachineFunction
&MF
) const override
;
73 bool canRealignStack(const MachineFunction
&MF
) const override
;
74 bool requiresRegisterScavenging(const MachineFunction
&Fn
) const override
;
76 bool requiresFrameIndexScavenging(const MachineFunction
&MF
) const override
;
77 bool requiresFrameIndexReplacementScavenging(
78 const MachineFunction
&MF
) const override
;
79 bool requiresVirtualBaseRegisters(const MachineFunction
&Fn
) const override
;
80 bool trackLivenessAfterRegAlloc(const MachineFunction
&MF
) const override
;
82 int64_t getMUBUFInstrOffset(const MachineInstr
*MI
) const;
84 int64_t getFrameIndexInstrOffset(const MachineInstr
*MI
,
85 int Idx
) const override
;
87 bool needsFrameBaseReg(MachineInstr
*MI
, int64_t Offset
) const override
;
89 void materializeFrameBaseRegister(MachineBasicBlock
*MBB
,
90 unsigned BaseReg
, int FrameIdx
,
91 int64_t Offset
) const override
;
93 void resolveFrameIndex(MachineInstr
&MI
, unsigned BaseReg
,
94 int64_t Offset
) const override
;
96 bool isFrameOffsetLegal(const MachineInstr
*MI
, unsigned BaseReg
,
97 int64_t Offset
) const override
;
99 const TargetRegisterClass
*getPointerRegClass(
100 const MachineFunction
&MF
, unsigned Kind
= 0) const override
;
102 /// If \p OnlyToVGPR is true, this will only succeed if this
103 bool spillSGPR(MachineBasicBlock::iterator MI
,
104 int FI
, RegScavenger
*RS
,
105 bool OnlyToVGPR
= false) const;
107 bool restoreSGPR(MachineBasicBlock::iterator MI
,
108 int FI
, RegScavenger
*RS
,
109 bool OnlyToVGPR
= false) const;
111 void eliminateFrameIndex(MachineBasicBlock::iterator MI
, int SPAdj
,
112 unsigned FIOperandNum
,
113 RegScavenger
*RS
) const override
;
115 bool eliminateSGPRToVGPRSpillFrameIndex(MachineBasicBlock::iterator MI
,
116 int FI
, RegScavenger
*RS
) const;
118 StringRef
getRegAsmName(unsigned Reg
) const override
;
120 unsigned getHWRegIndex(unsigned Reg
) const {
121 return getEncodingValue(Reg
) & 0xff;
124 /// Return the 'base' register class for this register.
125 /// e.g. SGPR0 => SReg_32, VGPR => VGPR_32 SGPR0_SGPR1 -> SReg_32, etc.
126 const TargetRegisterClass
*getPhysRegClass(unsigned Reg
) const;
128 /// \returns true if this class contains only SGPR registers
129 bool isSGPRClass(const TargetRegisterClass
*RC
) const {
130 return !hasVGPRs(RC
) && !hasAGPRs(RC
);
133 /// \returns true if this class ID contains only SGPR registers
134 bool isSGPRClassID(unsigned RCID
) const {
135 return isSGPRClass(getRegClass(RCID
));
138 bool isSGPRReg(const MachineRegisterInfo
&MRI
, unsigned Reg
) const {
139 const TargetRegisterClass
*RC
;
140 if (Register::isVirtualRegister(Reg
))
141 RC
= MRI
.getRegClass(Reg
);
143 RC
= getPhysRegClass(Reg
);
144 return isSGPRClass(RC
);
147 /// \returns true if this class contains VGPR registers.
148 bool hasVGPRs(const TargetRegisterClass
*RC
) const;
150 /// \returns true if this class contains AGPR registers.
151 bool hasAGPRs(const TargetRegisterClass
*RC
) const;
153 /// \returns true if this class contains any vector registers.
154 bool hasVectorRegisters(const TargetRegisterClass
*RC
) const {
155 return hasVGPRs(RC
) || hasAGPRs(RC
);
158 /// \returns A VGPR reg class with the same width as \p SRC
159 const TargetRegisterClass
*getEquivalentVGPRClass(
160 const TargetRegisterClass
*SRC
) const;
162 /// \returns An AGPR reg class with the same width as \p SRC
163 const TargetRegisterClass
*getEquivalentAGPRClass(
164 const TargetRegisterClass
*SRC
) const;
166 /// \returns A SGPR reg class with the same width as \p SRC
167 const TargetRegisterClass
*getEquivalentSGPRClass(
168 const TargetRegisterClass
*VRC
) const;
170 /// \returns The register class that is used for a sub-register of \p RC for
171 /// the given \p SubIdx. If \p SubIdx equals NoSubRegister, \p RC will
173 const TargetRegisterClass
*getSubRegClass(const TargetRegisterClass
*RC
,
174 unsigned SubIdx
) const;
176 bool shouldRewriteCopySrc(const TargetRegisterClass
*DefRC
,
178 const TargetRegisterClass
*SrcRC
,
179 unsigned SrcSubReg
) const override
;
181 /// \returns True if operands defined with this operand type can accept
182 /// a literal constant (i.e. any 32-bit immediate).
183 bool opCanUseLiteralConstant(unsigned OpType
) const {
184 // TODO: 64-bit operands have extending behavior from 32-bit literal.
185 return OpType
>= AMDGPU::OPERAND_REG_IMM_FIRST
&&
186 OpType
<= AMDGPU::OPERAND_REG_IMM_LAST
;
189 /// \returns True if operands defined with this operand type can accept
190 /// an inline constant. i.e. An integer value in the range (-16, 64) or
191 /// -4.0f, -2.0f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 2.0f, 4.0f.
192 bool opCanUseInlineConstant(unsigned OpType
) const;
194 unsigned findUnusedRegister(const MachineRegisterInfo
&MRI
,
195 const TargetRegisterClass
*RC
,
196 const MachineFunction
&MF
) const;
198 unsigned getSGPRPressureSet() const { return SGPRSetID
; };
199 unsigned getVGPRPressureSet() const { return VGPRSetID
; };
200 unsigned getAGPRPressureSet() const { return AGPRSetID
; };
202 const TargetRegisterClass
*getRegClassForReg(const MachineRegisterInfo
&MRI
,
204 bool isVGPR(const MachineRegisterInfo
&MRI
, unsigned Reg
) const;
205 bool isAGPR(const MachineRegisterInfo
&MRI
, unsigned Reg
) const;
206 bool isVectorRegister(const MachineRegisterInfo
&MRI
, unsigned Reg
) const {
207 return isVGPR(MRI
, Reg
) || isAGPR(MRI
, Reg
);
211 isDivergentRegClass(const TargetRegisterClass
*RC
) const override
{
212 return !isSGPRClass(RC
);
215 bool isSGPRPressureSet(unsigned SetID
) const {
216 return SGPRPressureSets
.test(SetID
) && !VGPRPressureSets
.test(SetID
) &&
217 !AGPRPressureSets
.test(SetID
);
219 bool isVGPRPressureSet(unsigned SetID
) const {
220 return VGPRPressureSets
.test(SetID
) && !SGPRPressureSets
.test(SetID
) &&
221 !AGPRPressureSets
.test(SetID
);
223 bool isAGPRPressureSet(unsigned SetID
) const {
224 return AGPRPressureSets
.test(SetID
) && !SGPRPressureSets
.test(SetID
) &&
225 !VGPRPressureSets
.test(SetID
);
228 ArrayRef
<int16_t> getRegSplitParts(const TargetRegisterClass
*RC
,
229 unsigned EltSize
) const;
231 bool shouldCoalesce(MachineInstr
*MI
,
232 const TargetRegisterClass
*SrcRC
,
234 const TargetRegisterClass
*DstRC
,
236 const TargetRegisterClass
*NewRC
,
237 LiveIntervals
&LIS
) const override
;
239 unsigned getRegPressureLimit(const TargetRegisterClass
*RC
,
240 MachineFunction
&MF
) const override
;
242 unsigned getRegPressureSetLimit(const MachineFunction
&MF
,
243 unsigned Idx
) const override
;
245 const int *getRegUnitPressureSets(unsigned RegUnit
) const override
;
247 unsigned getReturnAddressReg(const MachineFunction
&MF
) const;
249 const TargetRegisterClass
*
250 getRegClassForSizeOnBank(unsigned Size
,
251 const RegisterBank
&Bank
,
252 const MachineRegisterInfo
&MRI
) const;
254 const TargetRegisterClass
*
255 getRegClassForTypeOnBank(LLT Ty
,
256 const RegisterBank
&Bank
,
257 const MachineRegisterInfo
&MRI
) const {
258 return getRegClassForSizeOnBank(Ty
.getSizeInBits(), Bank
, MRI
);
261 const TargetRegisterClass
*
262 getConstrainedRegClassForOperand(const MachineOperand
&MO
,
263 const MachineRegisterInfo
&MRI
) const override
;
265 const TargetRegisterClass
*getBoolRC() const {
266 return isWave32
? &AMDGPU::SReg_32RegClass
267 : &AMDGPU::SReg_64RegClass
;
270 const TargetRegisterClass
*getWaveMaskRegClass() const {
271 return isWave32
? &AMDGPU::SReg_32_XM0_XEXECRegClass
272 : &AMDGPU::SReg_64_XEXECRegClass
;
275 unsigned getVCC() const;
277 const TargetRegisterClass
*getRegClass(unsigned RCID
) const;
279 // Find reaching register definition
280 MachineInstr
*findReachingDef(unsigned Reg
, unsigned SubReg
,
282 MachineRegisterInfo
&MRI
,
283 LiveIntervals
*LIS
) const;
285 const uint32_t *getAllVGPRRegMask() const;
286 const uint32_t *getAllAllocatableSRegMask() const;
289 void buildSpillLoadStore(MachineBasicBlock::iterator MI
,
290 unsigned LoadStoreOp
,
294 unsigned ScratchRsrcReg
,
295 unsigned ScratchOffsetReg
,
297 MachineMemOperand
*MMO
,
298 RegScavenger
*RS
) const;
301 } // End namespace llvm