Line data Source code
1 : //===-- SIRegisterInfo.h - SI Register Info Interface ----------*- 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 : /// Interface definition for SIRegisterInfo
12 : //
13 : //===----------------------------------------------------------------------===//
14 :
15 : #ifndef LLVM_LIB_TARGET_AMDGPU_SIREGISTERINFO_H
16 : #define LLVM_LIB_TARGET_AMDGPU_SIREGISTERINFO_H
17 :
18 : #include "AMDGPURegisterInfo.h"
19 : #include "SIDefines.h"
20 : #include "llvm/CodeGen/MachineRegisterInfo.h"
21 :
22 : namespace llvm {
23 :
24 : class GCNSubtarget;
25 : class LiveIntervals;
26 : class MachineRegisterInfo;
27 : class SIMachineFunctionInfo;
28 :
29 : class SIRegisterInfo final : public AMDGPURegisterInfo {
30 : private:
31 : unsigned SGPRSetID;
32 : unsigned VGPRSetID;
33 : BitVector SGPRPressureSets;
34 : BitVector VGPRPressureSets;
35 : bool SpillSGPRToVGPR;
36 : bool SpillSGPRToSMEM;
37 :
38 : void classifyPressureSet(unsigned PSetID, unsigned Reg,
39 : BitVector &PressureSets) const;
40 : public:
41 : SIRegisterInfo(const GCNSubtarget &ST);
42 :
43 0 : bool spillSGPRToVGPR() const {
44 0 : return SpillSGPRToVGPR;
45 : }
46 :
47 0 : bool spillSGPRToSMEM() const {
48 0 : return SpillSGPRToSMEM;
49 : }
50 :
51 : /// Return the end register initially reserved for the scratch buffer in case
52 : /// spilling is needed.
53 : unsigned reservedPrivateSegmentBufferReg(const MachineFunction &MF) const;
54 :
55 : /// Return the end register initially reserved for the scratch wave offset in
56 : /// case spilling is needed.
57 : unsigned reservedPrivateSegmentWaveByteOffsetReg(
58 : const MachineFunction &MF) const;
59 :
60 : unsigned reservedStackPtrOffsetReg(const MachineFunction &MF) const;
61 :
62 : BitVector getReservedRegs(const MachineFunction &MF) const override;
63 :
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;
68 :
69 : // Stack access is very expensive. CSRs are also the high registers, and we
70 : // want to minimize the number of used registers.
71 19553 : unsigned getCSRFirstUseCost() const override {
72 19553 : return 100;
73 : }
74 :
75 : unsigned getFrameRegister(const MachineFunction &MF) const override;
76 :
77 : bool requiresRegisterScavenging(const MachineFunction &Fn) const override;
78 :
79 : bool requiresFrameIndexScavenging(const MachineFunction &MF) const override;
80 : bool requiresFrameIndexReplacementScavenging(
81 : const MachineFunction &MF) const override;
82 : bool requiresVirtualBaseRegisters(const MachineFunction &Fn) const override;
83 : bool trackLivenessAfterRegAlloc(const MachineFunction &MF) const override;
84 :
85 : int64_t getMUBUFInstrOffset(const MachineInstr *MI) const;
86 :
87 : int64_t getFrameIndexInstrOffset(const MachineInstr *MI,
88 : int Idx) const override;
89 :
90 : bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override;
91 :
92 : void materializeFrameBaseRegister(MachineBasicBlock *MBB,
93 : unsigned BaseReg, int FrameIdx,
94 : int64_t Offset) const override;
95 :
96 : void resolveFrameIndex(MachineInstr &MI, unsigned BaseReg,
97 : int64_t Offset) const override;
98 :
99 : bool isFrameOffsetLegal(const MachineInstr *MI, unsigned BaseReg,
100 : int64_t Offset) const override;
101 :
102 : const TargetRegisterClass *getPointerRegClass(
103 : const MachineFunction &MF, unsigned Kind = 0) const override;
104 :
105 : /// If \p OnlyToVGPR is true, this will only succeed if this
106 : bool spillSGPR(MachineBasicBlock::iterator MI,
107 : int FI, RegScavenger *RS,
108 : bool OnlyToVGPR = false) const;
109 :
110 : bool restoreSGPR(MachineBasicBlock::iterator MI,
111 : int FI, RegScavenger *RS,
112 : bool OnlyToVGPR = false) const;
113 :
114 : void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
115 : unsigned FIOperandNum,
116 : RegScavenger *RS) const override;
117 :
118 : bool eliminateSGPRToVGPRSpillFrameIndex(MachineBasicBlock::iterator MI,
119 : int FI, RegScavenger *RS) const;
120 :
121 : StringRef getRegAsmName(unsigned Reg) const override;
122 :
123 : unsigned getHWRegIndex(unsigned Reg) const {
124 120714 : return getEncodingValue(Reg) & 0xff;
125 : }
126 :
127 : /// Return the 'base' register class for this register.
128 : /// e.g. SGPR0 => SReg_32, VGPR => VGPR_32 SGPR0_SGPR1 -> SReg_32, etc.
129 : const TargetRegisterClass *getPhysRegClass(unsigned Reg) const;
130 :
131 : /// \returns true if this class contains only SGPR registers
132 : bool isSGPRClass(const TargetRegisterClass *RC) const {
133 7261312 : return !hasVGPRs(RC);
134 : }
135 :
136 : /// \returns true if this class ID contains only SGPR registers
137 : bool isSGPRClassID(unsigned RCID) const {
138 : return isSGPRClass(getRegClass(RCID));
139 : }
140 :
141 1753695 : bool isSGPRReg(const MachineRegisterInfo &MRI, unsigned Reg) const {
142 : const TargetRegisterClass *RC;
143 1753695 : if (TargetRegisterInfo::isVirtualRegister(Reg))
144 : RC = MRI.getRegClass(Reg);
145 : else
146 905890 : RC = getPhysRegClass(Reg);
147 1753695 : return isSGPRClass(RC);
148 : }
149 :
150 : /// \returns true if this class contains VGPR registers.
151 : bool hasVGPRs(const TargetRegisterClass *RC) const;
152 :
153 : /// \returns A VGPR reg class with the same width as \p SRC
154 : const TargetRegisterClass *getEquivalentVGPRClass(
155 : const TargetRegisterClass *SRC) const;
156 :
157 : /// \returns A SGPR reg class with the same width as \p SRC
158 : const TargetRegisterClass *getEquivalentSGPRClass(
159 : const TargetRegisterClass *VRC) const;
160 :
161 : /// \returns The register class that is used for a sub-register of \p RC for
162 : /// the given \p SubIdx. If \p SubIdx equals NoSubRegister, \p RC will
163 : /// be returned.
164 : const TargetRegisterClass *getSubRegClass(const TargetRegisterClass *RC,
165 : unsigned SubIdx) const;
166 :
167 : bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
168 : unsigned DefSubReg,
169 : const TargetRegisterClass *SrcRC,
170 : unsigned SrcSubReg) const override;
171 :
172 : /// \returns True if operands defined with this operand type can accept
173 : /// a literal constant (i.e. any 32-bit immediate).
174 0 : bool opCanUseLiteralConstant(unsigned OpType) const {
175 : // TODO: 64-bit operands have extending behavior from 32-bit literal.
176 28559 : return OpType >= AMDGPU::OPERAND_REG_IMM_FIRST &&
177 28559 : OpType <= AMDGPU::OPERAND_REG_IMM_LAST;
178 : }
179 :
180 : /// \returns True if operands defined with this operand type can accept
181 : /// an inline constant. i.e. An integer value in the range (-16, 64) or
182 : /// -4.0f, -2.0f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 2.0f, 4.0f.
183 0 : bool opCanUseInlineConstant(unsigned OpType) const {
184 64203 : return OpType >= AMDGPU::OPERAND_SRC_FIRST &&
185 64203 : OpType <= AMDGPU::OPERAND_SRC_LAST;
186 : }
187 :
188 : unsigned findUnusedRegister(const MachineRegisterInfo &MRI,
189 : const TargetRegisterClass *RC,
190 : const MachineFunction &MF) const;
191 :
192 0 : unsigned getSGPRPressureSet() const { return SGPRSetID; };
193 0 : unsigned getVGPRPressureSet() const { return VGPRSetID; };
194 :
195 : const TargetRegisterClass *getRegClassForReg(const MachineRegisterInfo &MRI,
196 : unsigned Reg) const;
197 : bool isVGPR(const MachineRegisterInfo &MRI, unsigned Reg) const;
198 :
199 : bool isSGPRPressureSet(unsigned SetID) const {
200 9968 : return SGPRPressureSets.test(SetID) && !VGPRPressureSets.test(SetID);
201 : }
202 : bool isVGPRPressureSet(unsigned SetID) const {
203 12460 : return VGPRPressureSets.test(SetID) && !SGPRPressureSets.test(SetID);
204 : }
205 :
206 : ArrayRef<int16_t> getRegSplitParts(const TargetRegisterClass *RC,
207 : unsigned EltSize) const;
208 :
209 : bool shouldCoalesce(MachineInstr *MI,
210 : const TargetRegisterClass *SrcRC,
211 : unsigned SubReg,
212 : const TargetRegisterClass *DstRC,
213 : unsigned DstSubReg,
214 : const TargetRegisterClass *NewRC,
215 : LiveIntervals &LIS) const override;
216 :
217 : unsigned getRegPressureLimit(const TargetRegisterClass *RC,
218 : MachineFunction &MF) const override;
219 :
220 : unsigned getRegPressureSetLimit(const MachineFunction &MF,
221 : unsigned Idx) const override;
222 :
223 : const int *getRegUnitPressureSets(unsigned RegUnit) const override;
224 :
225 : unsigned getReturnAddressReg(const MachineFunction &MF) const;
226 :
227 : const TargetRegisterClass *
228 : getConstrainedRegClassForOperand(const MachineOperand &MO,
229 : const MachineRegisterInfo &MRI) const override;
230 :
231 : private:
232 : void buildSpillLoadStore(MachineBasicBlock::iterator MI,
233 : unsigned LoadStoreOp,
234 : int Index,
235 : unsigned ValueReg,
236 : bool ValueIsKill,
237 : unsigned ScratchRsrcReg,
238 : unsigned ScratchOffsetReg,
239 : int64_t InstrOffset,
240 : MachineMemOperand *MMO,
241 : RegScavenger *RS) const;
242 : };
243 :
244 : } // End namespace llvm
245 :
246 : #endif
|