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 #define GET_REGINFO_HEADER
18 #include "AMDGPUGenRegisterInfo.inc"
20 #include "SIDefines.h"
21 #include "llvm/CodeGen/MachineRegisterInfo.h"
27 class SIMachineFunctionInfo;
29 class SIRegisterInfo final : public AMDGPUGenRegisterInfo {
31 const GCNSubtarget &ST;
34 BitVector RegPressureIgnoredUnits;
36 /// Sub reg indexes for getRegSplitParts.
37 /// First index represents subreg size from 1 to 16 DWORDs.
38 /// The inner vector is sorted by bit offset.
39 /// Provided a register can be fully split with given subregs,
40 /// all elements of the inner vector combined give a full lane mask.
41 static std::array<std::vector<int16_t>, 16> RegSplitParts;
43 void reserveRegisterTuples(BitVector &, MCRegister Reg) const;
46 SIRegisterInfo(const GCNSubtarget &ST);
48 /// \returns the sub reg enum value for the given \p Channel
49 /// (e.g. getSubRegFromChannel(0) -> AMDGPU::sub0)
50 static unsigned getSubRegFromChannel(unsigned Channel, unsigned NumRegs = 1);
52 bool spillSGPRToVGPR() const {
53 return SpillSGPRToVGPR;
56 /// Return the end register initially reserved for the scratch buffer in case
57 /// spilling is needed.
58 MCRegister reservedPrivateSegmentBufferReg(const MachineFunction &MF) const;
60 BitVector getReservedRegs(const MachineFunction &MF) const override;
62 const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
63 const MCPhysReg *getCalleeSavedRegsViaCopy(const MachineFunction *MF) const;
64 const uint32_t *getCallPreservedMask(const MachineFunction &MF,
65 CallingConv::ID) const override;
67 // Stack access is very expensive. CSRs are also the high registers, and we
68 // want to minimize the number of used registers.
69 unsigned getCSRFirstUseCost() const override {
73 Register getFrameRegister(const MachineFunction &MF) const override;
75 bool hasBasePointer(const MachineFunction &MF) const;
76 Register getBaseRegister() const;
78 bool canRealignStack(const MachineFunction &MF) const override;
79 bool requiresRegisterScavenging(const MachineFunction &Fn) const override;
81 bool requiresFrameIndexScavenging(const MachineFunction &MF) const override;
82 bool requiresFrameIndexReplacementScavenging(
83 const MachineFunction &MF) const override;
84 bool requiresVirtualBaseRegisters(const MachineFunction &Fn) const override;
86 int64_t getMUBUFInstrOffset(const MachineInstr *MI) const;
88 int64_t getFrameIndexInstrOffset(const MachineInstr *MI,
89 int Idx) const override;
91 bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override;
93 void materializeFrameBaseRegister(MachineBasicBlock *MBB, Register BaseReg,
95 int64_t Offset) const override;
97 void resolveFrameIndex(MachineInstr &MI, Register BaseReg,
98 int64_t Offset) const override;
100 bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg,
101 int64_t Offset) const override;
103 const TargetRegisterClass *getPointerRegClass(
104 const MachineFunction &MF, unsigned Kind = 0) const override;
106 void buildSGPRSpillLoadStore(MachineBasicBlock::iterator MI, int Index,
107 int Offset, unsigned EltSize, Register VGPR,
108 int64_t VGPRLanes, RegScavenger *RS,
111 /// If \p OnlyToVGPR is true, this will only succeed if this
112 bool spillSGPR(MachineBasicBlock::iterator MI,
113 int FI, RegScavenger *RS,
114 bool OnlyToVGPR = false) const;
116 bool restoreSGPR(MachineBasicBlock::iterator MI,
117 int FI, RegScavenger *RS,
118 bool OnlyToVGPR = false) const;
120 void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
121 unsigned FIOperandNum,
122 RegScavenger *RS) const override;
124 bool eliminateSGPRToVGPRSpillFrameIndex(MachineBasicBlock::iterator MI,
125 int FI, RegScavenger *RS) const;
127 StringRef getRegAsmName(MCRegister Reg) const override;
129 unsigned getHWRegIndex(MCRegister Reg) const {
130 return getEncodingValue(Reg) & 0xff;
133 static const TargetRegisterClass *getVGPRClassForBitWidth(unsigned BitWidth);
134 static const TargetRegisterClass *getAGPRClassForBitWidth(unsigned BitWidth);
135 static const TargetRegisterClass *getSGPRClassForBitWidth(unsigned BitWidth);
137 /// Return the 'base' register class for this register.
138 /// e.g. SGPR0 => SReg_32, VGPR => VGPR_32 SGPR0_SGPR1 -> SReg_32, etc.
139 const TargetRegisterClass *getPhysRegClass(MCRegister Reg) const;
141 /// \returns true if this class contains only SGPR registers
142 bool isSGPRClass(const TargetRegisterClass *RC) const {
143 return !hasVGPRs(RC) && !hasAGPRs(RC);
146 /// \returns true if this class ID contains only SGPR registers
147 bool isSGPRClassID(unsigned RCID) const {
148 return isSGPRClass(getRegClass(RCID));
151 bool isSGPRReg(const MachineRegisterInfo &MRI, Register Reg) const {
152 const TargetRegisterClass *RC;
154 RC = MRI.getRegClass(Reg);
156 RC = getPhysRegClass(Reg);
157 return isSGPRClass(RC);
160 /// \returns true if this class contains only AGPR registers
161 bool isAGPRClass(const TargetRegisterClass *RC) const {
162 return hasAGPRs(RC) && !hasVGPRs(RC);
165 /// \returns true if this class contains VGPR registers.
166 bool hasVGPRs(const TargetRegisterClass *RC) const;
168 /// \returns true if this class contains AGPR registers.
169 bool hasAGPRs(const TargetRegisterClass *RC) const;
171 /// \returns true if this class contains any vector registers.
172 bool hasVectorRegisters(const TargetRegisterClass *RC) const {
173 return hasVGPRs(RC) || hasAGPRs(RC);
176 /// \returns A VGPR reg class with the same width as \p SRC
177 const TargetRegisterClass *
178 getEquivalentVGPRClass(const TargetRegisterClass *SRC) const;
180 /// \returns An AGPR reg class with the same width as \p SRC
181 const TargetRegisterClass *
182 getEquivalentAGPRClass(const TargetRegisterClass *SRC) const;
184 /// \returns A SGPR reg class with the same width as \p SRC
185 const TargetRegisterClass *
186 getEquivalentSGPRClass(const TargetRegisterClass *VRC) const;
188 /// \returns The register class that is used for a sub-register of \p RC for
189 /// the given \p SubIdx. If \p SubIdx equals NoSubRegister, \p RC will
191 const TargetRegisterClass *getSubRegClass(const TargetRegisterClass *RC,
192 unsigned SubIdx) const;
194 bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
196 const TargetRegisterClass *SrcRC,
197 unsigned SrcSubReg) const override;
199 /// \returns True if operands defined with this operand type can accept
200 /// a literal constant (i.e. any 32-bit immediate).
201 bool opCanUseLiteralConstant(unsigned OpType) const {
202 // TODO: 64-bit operands have extending behavior from 32-bit literal.
203 return OpType >= AMDGPU::OPERAND_REG_IMM_FIRST &&
204 OpType <= AMDGPU::OPERAND_REG_IMM_LAST;
207 /// \returns True if operands defined with this operand type can accept
208 /// an inline constant. i.e. An integer value in the range (-16, 64) or
209 /// -4.0f, -2.0f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 2.0f, 4.0f.
210 bool opCanUseInlineConstant(unsigned OpType) const;
212 MCRegister findUnusedRegister(const MachineRegisterInfo &MRI,
213 const TargetRegisterClass *RC,
214 const MachineFunction &MF,
215 bool ReserveHighestVGPR = false) const;
217 const TargetRegisterClass *getRegClassForReg(const MachineRegisterInfo &MRI,
219 bool isVGPR(const MachineRegisterInfo &MRI, Register Reg) const;
220 bool isAGPR(const MachineRegisterInfo &MRI, Register Reg) const;
221 bool isVectorRegister(const MachineRegisterInfo &MRI, Register Reg) const {
222 return isVGPR(MRI, Reg) || isAGPR(MRI, Reg);
225 bool isConstantPhysReg(MCRegister PhysReg) const override;
227 bool isDivergentRegClass(const TargetRegisterClass *RC) const override {
228 return !isSGPRClass(RC);
231 ArrayRef<int16_t> getRegSplitParts(const TargetRegisterClass *RC,
232 unsigned EltSize) const;
234 bool shouldCoalesce(MachineInstr *MI,
235 const TargetRegisterClass *SrcRC,
237 const TargetRegisterClass *DstRC,
239 const TargetRegisterClass *NewRC,
240 LiveIntervals &LIS) const override;
242 unsigned getRegPressureLimit(const TargetRegisterClass *RC,
243 MachineFunction &MF) const override;
245 unsigned getRegPressureSetLimit(const MachineFunction &MF,
246 unsigned Idx) const override;
248 const int *getRegUnitPressureSets(unsigned RegUnit) const override;
250 MCRegister getReturnAddressReg(const MachineFunction &MF) const;
252 const TargetRegisterClass *
253 getRegClassForSizeOnBank(unsigned Size,
254 const RegisterBank &Bank,
255 const MachineRegisterInfo &MRI) const;
257 const TargetRegisterClass *
258 getRegClassForTypeOnBank(LLT Ty,
259 const RegisterBank &Bank,
260 const MachineRegisterInfo &MRI) const {
261 return getRegClassForSizeOnBank(Ty.getSizeInBits(), Bank, MRI);
264 const TargetRegisterClass *
265 getConstrainedRegClassForOperand(const MachineOperand &MO,
266 const MachineRegisterInfo &MRI) const override;
268 const TargetRegisterClass *getBoolRC() const {
269 return isWave32 ? &AMDGPU::SReg_32RegClass
270 : &AMDGPU::SReg_64RegClass;
273 const TargetRegisterClass *getWaveMaskRegClass() const {
274 return isWave32 ? &AMDGPU::SReg_32_XM0_XEXECRegClass
275 : &AMDGPU::SReg_64_XEXECRegClass;
278 MCRegister getVCC() const;
280 const TargetRegisterClass *getRegClass(unsigned RCID) const;
282 // Find reaching register definition
283 MachineInstr *findReachingDef(Register Reg, unsigned SubReg,
285 MachineRegisterInfo &MRI,
286 LiveIntervals *LIS) const;
288 const uint32_t *getAllVGPRRegMask() const;
289 const uint32_t *getAllAllocatableSRegMask() const;
291 // \returns number of 32 bit registers covered by a \p LM
292 static unsigned getNumCoveredRegs(LaneBitmask LM) {
293 // The assumption is that every lo16 subreg is an even bit and every hi16
294 // is an adjacent odd bit or vice versa.
295 uint64_t Mask = LM.getAsInteger();
296 uint64_t Even = Mask & 0xAAAAAAAAAAAAAAAAULL;
297 Mask = (Even >> 1) | Mask;
298 uint64_t Odd = Mask & 0x5555555555555555ULL;
299 return countPopulation(Odd);
302 // \returns a DWORD offset of a \p SubReg
303 unsigned getChannelFromSubReg(unsigned SubReg) const {
304 return SubReg ? (getSubRegIdxOffset(SubReg) + 31) / 32 : 0;
307 // \returns a DWORD size of a \p SubReg
308 unsigned getNumChannelsFromSubReg(unsigned SubReg) const {
309 return getNumCoveredRegs(getSubRegIndexLaneMask(SubReg));
312 // For a given 16 bit \p Reg \returns a 32 bit register holding it.
313 // \returns \p Reg otherwise.
314 MCPhysReg get32BitRegister(MCPhysReg Reg) const;
316 /// Return all SGPR128 which satisfy the waves per execution unit requirement
317 /// of the subtarget.
318 ArrayRef<MCPhysReg> getAllSGPR128(const MachineFunction &MF) const;
320 /// Return all SGPR32 which satisfy the waves per execution unit requirement
321 /// of the subtarget.
322 ArrayRef<MCPhysReg> getAllSGPR32(const MachineFunction &MF) const;
324 /// Return all VGPR32 which satisfy the waves per execution unit requirement
325 /// of the subtarget.
326 ArrayRef<MCPhysReg> getAllVGPR32(const MachineFunction &MF) const;
329 void buildSpillLoadStore(MachineBasicBlock::iterator MI,
330 unsigned LoadStoreOp,
334 MCRegister ScratchRsrcReg,
335 MCRegister ScratchOffsetReg,
337 MachineMemOperand *MMO,
338 RegScavenger *RS) const;
341 } // End namespace llvm