[ARM] Better patterns for fp <> predicate vectors
[llvm-complete.git] / lib / Target / AMDGPU / SIRegisterInfo.h
blob34487c96e72e519da81ea390317b55751f63558f
1 //===-- SIRegisterInfo.h - SI Register Info Interface ----------*- C++ -*--===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file
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"
21 namespace llvm {
23 class GCNSubtarget;
24 class LiveIntervals;
25 class MachineRegisterInfo;
26 class SIMachineFunctionInfo;
28 class SIRegisterInfo final : public AMDGPURegisterInfo {
29 private:
30 unsigned SGPRSetID;
31 unsigned VGPRSetID;
32 unsigned AGPRSetID;
33 BitVector SGPRPressureSets;
34 BitVector VGPRPressureSets;
35 BitVector AGPRPressureSets;
36 bool SpillSGPRToVGPR;
37 bool SpillSGPRToSMEM;
38 bool isWave32;
40 void classifyPressureSet(unsigned PSetID, unsigned Reg,
41 BitVector &PressureSets) const;
42 public:
43 SIRegisterInfo(const GCNSubtarget &ST);
45 bool spillSGPRToVGPR() const {
46 return SpillSGPRToVGPR;
49 bool spillSGPRToSMEM() const {
50 return SpillSGPRToSMEM;
53 /// Return the end register initially reserved for the scratch buffer in case
54 /// spilling is needed.
55 unsigned reservedPrivateSegmentBufferReg(const MachineFunction &MF) const;
57 /// Return the end register initially reserved for the scratch wave offset in
58 /// case spilling is needed.
59 unsigned reservedPrivateSegmentWaveByteOffsetReg(
60 const MachineFunction &MF) const;
62 BitVector getReservedRegs(const MachineFunction &MF) const override;
64 const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
65 const MCPhysReg *getCalleeSavedRegsViaCopy(const MachineFunction *MF) const;
66 const uint32_t *getCallPreservedMask(const MachineFunction &MF,
67 CallingConv::ID) const override;
69 // Stack access is very expensive. CSRs are also the high registers, and we
70 // want to minimize the number of used registers.
71 unsigned getCSRFirstUseCost() const override {
72 return 100;
75 Register getFrameRegister(const MachineFunction &MF) const override;
77 bool canRealignStack(const MachineFunction &MF) const override;
78 bool requiresRegisterScavenging(const MachineFunction &Fn) const override;
80 bool requiresFrameIndexScavenging(const MachineFunction &MF) const override;
81 bool requiresFrameIndexReplacementScavenging(
82 const MachineFunction &MF) const override;
83 bool requiresVirtualBaseRegisters(const MachineFunction &Fn) const override;
84 bool trackLivenessAfterRegAlloc(const MachineFunction &MF) 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,
94 unsigned BaseReg, int FrameIdx,
95 int64_t Offset) const override;
97 void resolveFrameIndex(MachineInstr &MI, unsigned BaseReg,
98 int64_t Offset) const override;
100 bool isFrameOffsetLegal(const MachineInstr *MI, unsigned BaseReg,
101 int64_t Offset) const override;
103 const TargetRegisterClass *getPointerRegClass(
104 const MachineFunction &MF, unsigned Kind = 0) const override;
106 /// If \p OnlyToVGPR is true, this will only succeed if this
107 bool spillSGPR(MachineBasicBlock::iterator MI,
108 int FI, RegScavenger *RS,
109 bool OnlyToVGPR = false) const;
111 bool restoreSGPR(MachineBasicBlock::iterator MI,
112 int FI, RegScavenger *RS,
113 bool OnlyToVGPR = false) const;
115 void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
116 unsigned FIOperandNum,
117 RegScavenger *RS) const override;
119 bool eliminateSGPRToVGPRSpillFrameIndex(MachineBasicBlock::iterator MI,
120 int FI, RegScavenger *RS) const;
122 StringRef getRegAsmName(unsigned Reg) const override;
124 unsigned getHWRegIndex(unsigned Reg) const {
125 return getEncodingValue(Reg) & 0xff;
128 /// Return the 'base' register class for this register.
129 /// e.g. SGPR0 => SReg_32, VGPR => VGPR_32 SGPR0_SGPR1 -> SReg_32, etc.
130 const TargetRegisterClass *getPhysRegClass(unsigned Reg) const;
132 /// \returns true if this class contains only SGPR registers
133 bool isSGPRClass(const TargetRegisterClass *RC) const {
134 return !hasVGPRs(RC) && !hasAGPRs(RC);
137 /// \returns true if this class ID contains only SGPR registers
138 bool isSGPRClassID(unsigned RCID) const {
139 return isSGPRClass(getRegClass(RCID));
142 bool isSGPRReg(const MachineRegisterInfo &MRI, unsigned Reg) const {
143 const TargetRegisterClass *RC;
144 if (TargetRegisterInfo::isVirtualRegister(Reg))
145 RC = MRI.getRegClass(Reg);
146 else
147 RC = getPhysRegClass(Reg);
148 return isSGPRClass(RC);
151 /// \returns true if this class contains VGPR registers.
152 bool hasVGPRs(const TargetRegisterClass *RC) const;
154 /// \returns true if this class contains AGPR registers.
155 bool hasAGPRs(const TargetRegisterClass *RC) const;
157 /// \returns true if this class contains any vector registers.
158 bool hasVectorRegisters(const TargetRegisterClass *RC) const {
159 return hasVGPRs(RC) || hasAGPRs(RC);
162 /// \returns A VGPR reg class with the same width as \p SRC
163 const TargetRegisterClass *getEquivalentVGPRClass(
164 const TargetRegisterClass *SRC) const;
166 /// \returns An AGPR reg class with the same width as \p SRC
167 const TargetRegisterClass *getEquivalentAGPRClass(
168 const TargetRegisterClass *SRC) const;
170 /// \returns A SGPR reg class with the same width as \p SRC
171 const TargetRegisterClass *getEquivalentSGPRClass(
172 const TargetRegisterClass *VRC) const;
174 /// \returns The register class that is used for a sub-register of \p RC for
175 /// the given \p SubIdx. If \p SubIdx equals NoSubRegister, \p RC will
176 /// be returned.
177 const TargetRegisterClass *getSubRegClass(const TargetRegisterClass *RC,
178 unsigned SubIdx) const;
180 bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
181 unsigned DefSubReg,
182 const TargetRegisterClass *SrcRC,
183 unsigned SrcSubReg) const override;
185 /// \returns True if operands defined with this operand type can accept
186 /// a literal constant (i.e. any 32-bit immediate).
187 bool opCanUseLiteralConstant(unsigned OpType) const {
188 // TODO: 64-bit operands have extending behavior from 32-bit literal.
189 return OpType >= AMDGPU::OPERAND_REG_IMM_FIRST &&
190 OpType <= AMDGPU::OPERAND_REG_IMM_LAST;
193 /// \returns True if operands defined with this operand type can accept
194 /// an inline constant. i.e. An integer value in the range (-16, 64) or
195 /// -4.0f, -2.0f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 2.0f, 4.0f.
196 bool opCanUseInlineConstant(unsigned OpType) const {
197 return OpType >= AMDGPU::OPERAND_SRC_FIRST &&
198 OpType <= AMDGPU::OPERAND_SRC_LAST;
201 unsigned findUnusedRegister(const MachineRegisterInfo &MRI,
202 const TargetRegisterClass *RC,
203 const MachineFunction &MF) const;
205 unsigned getSGPRPressureSet() const { return SGPRSetID; };
206 unsigned getVGPRPressureSet() const { return VGPRSetID; };
207 unsigned getAGPRPressureSet() const { return AGPRSetID; };
209 const TargetRegisterClass *getRegClassForReg(const MachineRegisterInfo &MRI,
210 unsigned Reg) const;
211 bool isVGPR(const MachineRegisterInfo &MRI, unsigned Reg) const;
212 bool isAGPR(const MachineRegisterInfo &MRI, unsigned Reg) const;
213 bool isVectorRegister(const MachineRegisterInfo &MRI, unsigned Reg) const {
214 return isVGPR(MRI, Reg) || isAGPR(MRI, Reg);
217 virtual bool
218 isDivergentRegClass(const TargetRegisterClass *RC) const override {
219 return !isSGPRClass(RC);
222 bool isSGPRPressureSet(unsigned SetID) const {
223 return SGPRPressureSets.test(SetID) && !VGPRPressureSets.test(SetID) &&
224 !AGPRPressureSets.test(SetID);
226 bool isVGPRPressureSet(unsigned SetID) const {
227 return VGPRPressureSets.test(SetID) && !SGPRPressureSets.test(SetID) &&
228 !AGPRPressureSets.test(SetID);
230 bool isAGPRPressureSet(unsigned SetID) const {
231 return AGPRPressureSets.test(SetID) && !SGPRPressureSets.test(SetID) &&
232 !VGPRPressureSets.test(SetID);
235 ArrayRef<int16_t> getRegSplitParts(const TargetRegisterClass *RC,
236 unsigned EltSize) const;
238 bool shouldCoalesce(MachineInstr *MI,
239 const TargetRegisterClass *SrcRC,
240 unsigned SubReg,
241 const TargetRegisterClass *DstRC,
242 unsigned DstSubReg,
243 const TargetRegisterClass *NewRC,
244 LiveIntervals &LIS) const override;
246 unsigned getRegPressureLimit(const TargetRegisterClass *RC,
247 MachineFunction &MF) const override;
249 unsigned getRegPressureSetLimit(const MachineFunction &MF,
250 unsigned Idx) const override;
252 const int *getRegUnitPressureSets(unsigned RegUnit) const override;
254 unsigned getReturnAddressReg(const MachineFunction &MF) const;
256 const TargetRegisterClass *
257 getRegClassForSizeOnBank(unsigned Size,
258 const RegisterBank &Bank,
259 const MachineRegisterInfo &MRI) const;
261 const TargetRegisterClass *
262 getRegClassForTypeOnBank(LLT Ty,
263 const RegisterBank &Bank,
264 const MachineRegisterInfo &MRI) const {
265 return getRegClassForSizeOnBank(Ty.getSizeInBits(), Bank, MRI);
268 const TargetRegisterClass *
269 getConstrainedRegClassForOperand(const MachineOperand &MO,
270 const MachineRegisterInfo &MRI) const override;
272 const TargetRegisterClass *getBoolRC() const {
273 return isWave32 ? &AMDGPU::SReg_32_XM0RegClass
274 : &AMDGPU::SReg_64RegClass;
277 const TargetRegisterClass *getWaveMaskRegClass() const {
278 return isWave32 ? &AMDGPU::SReg_32_XM0_XEXECRegClass
279 : &AMDGPU::SReg_64_XEXECRegClass;
282 unsigned getVCC() const;
284 const TargetRegisterClass *getRegClass(unsigned RCID) const;
286 // Find reaching register definition
287 MachineInstr *findReachingDef(unsigned Reg, unsigned SubReg,
288 MachineInstr &Use,
289 MachineRegisterInfo &MRI,
290 LiveIntervals *LIS) const;
292 const uint32_t *getAllVGPRRegMask() const;
293 const uint32_t *getAllAllocatableSRegMask() const;
295 private:
296 void buildSpillLoadStore(MachineBasicBlock::iterator MI,
297 unsigned LoadStoreOp,
298 int Index,
299 unsigned ValueReg,
300 bool ValueIsKill,
301 unsigned ScratchRsrcReg,
302 unsigned ScratchOffsetReg,
303 int64_t InstrOffset,
304 MachineMemOperand *MMO,
305 RegScavenger *RS) const;
308 } // End namespace llvm
310 #endif