SIRegisterInfo.h revision 360784
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
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_LIB_TARGET_AMDGPU_SIREGISTERINFO_H
15#define LLVM_LIB_TARGET_AMDGPU_SIREGISTERINFO_H
16
17#include "AMDGPURegisterInfo.h"
18#include "SIDefines.h"
19#include "llvm/CodeGen/MachineRegisterInfo.h"
20
21namespace llvm {
22
23class GCNSubtarget;
24class LiveIntervals;
25class MachineRegisterInfo;
26class SIMachineFunctionInfo;
27
28class SIRegisterInfo final : public AMDGPURegisterInfo {
29private:
30  const GCNSubtarget &ST;
31  unsigned SGPRSetID;
32  unsigned VGPRSetID;
33  unsigned AGPRSetID;
34  BitVector SGPRPressureSets;
35  BitVector VGPRPressureSets;
36  BitVector AGPRPressureSets;
37  bool SpillSGPRToVGPR;
38  bool isWave32;
39
40  void classifyPressureSet(unsigned PSetID, unsigned Reg,
41                           BitVector &PressureSets) const;
42public:
43  SIRegisterInfo(const GCNSubtarget &ST);
44
45  bool spillSGPRToVGPR() const {
46    return SpillSGPRToVGPR;
47  }
48
49  /// Return the end register initially reserved for the scratch buffer in case
50  /// spilling is needed.
51  unsigned reservedPrivateSegmentBufferReg(const MachineFunction &MF) const;
52
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;
57
58  BitVector getReservedRegs(const MachineFunction &MF) const override;
59
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;
64
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 {
68    return 100;
69  }
70
71  Register getFrameRegister(const MachineFunction &MF) const override;
72
73  bool canRealignStack(const MachineFunction &MF) const override;
74  bool requiresRegisterScavenging(const MachineFunction &Fn) const override;
75
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;
81
82  int64_t getMUBUFInstrOffset(const MachineInstr *MI) const;
83
84  int64_t getFrameIndexInstrOffset(const MachineInstr *MI,
85                                   int Idx) const override;
86
87  bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override;
88
89  void materializeFrameBaseRegister(MachineBasicBlock *MBB,
90                                    unsigned BaseReg, int FrameIdx,
91                                    int64_t Offset) const override;
92
93  void resolveFrameIndex(MachineInstr &MI, unsigned BaseReg,
94                         int64_t Offset) const override;
95
96  bool isFrameOffsetLegal(const MachineInstr *MI, unsigned BaseReg,
97                          int64_t Offset) const override;
98
99  const TargetRegisterClass *getPointerRegClass(
100    const MachineFunction &MF, unsigned Kind = 0) const override;
101
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;
106
107  bool restoreSGPR(MachineBasicBlock::iterator MI,
108                   int FI, RegScavenger *RS,
109                   bool OnlyToVGPR = false) const;
110
111  void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
112                           unsigned FIOperandNum,
113                           RegScavenger *RS) const override;
114
115  bool eliminateSGPRToVGPRSpillFrameIndex(MachineBasicBlock::iterator MI,
116                                          int FI, RegScavenger *RS) const;
117
118  StringRef getRegAsmName(unsigned Reg) const override;
119
120  unsigned getHWRegIndex(unsigned Reg) const {
121    return getEncodingValue(Reg) & 0xff;
122  }
123
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;
127
128  /// \returns true if this class contains only SGPR registers
129  bool isSGPRClass(const TargetRegisterClass *RC) const {
130    return !hasVGPRs(RC) && !hasAGPRs(RC);
131  }
132
133  /// \returns true if this class ID contains only SGPR registers
134  bool isSGPRClassID(unsigned RCID) const {
135    return isSGPRClass(getRegClass(RCID));
136  }
137
138  bool isSGPRReg(const MachineRegisterInfo &MRI, unsigned Reg) const {
139    const TargetRegisterClass *RC;
140    if (Register::isVirtualRegister(Reg))
141      RC = MRI.getRegClass(Reg);
142    else
143      RC = getPhysRegClass(Reg);
144    return isSGPRClass(RC);
145  }
146
147  /// \returns true if this class contains only AGPR registers
148  bool isAGPRClass(const TargetRegisterClass *RC) const {
149    return hasAGPRs(RC) && !hasVGPRs(RC);
150  }
151
152  /// \returns true if this class contains VGPR registers.
153  bool hasVGPRs(const TargetRegisterClass *RC) const;
154
155  /// \returns true if this class contains AGPR registers.
156  bool hasAGPRs(const TargetRegisterClass *RC) const;
157
158  /// \returns true if this class contains any vector registers.
159  bool hasVectorRegisters(const TargetRegisterClass *RC) const {
160    return hasVGPRs(RC) || hasAGPRs(RC);
161  }
162
163  /// \returns A VGPR reg class with the same width as \p SRC
164  const TargetRegisterClass *getEquivalentVGPRClass(
165                                          const TargetRegisterClass *SRC) const;
166
167  /// \returns An AGPR reg class with the same width as \p SRC
168  const TargetRegisterClass *getEquivalentAGPRClass(
169                                          const TargetRegisterClass *SRC) const;
170
171  /// \returns A SGPR reg class with the same width as \p SRC
172  const TargetRegisterClass *getEquivalentSGPRClass(
173                                           const TargetRegisterClass *VRC) const;
174
175  /// \returns The register class that is used for a sub-register of \p RC for
176  /// the given \p SubIdx.  If \p SubIdx equals NoSubRegister, \p RC will
177  /// be returned.
178  const TargetRegisterClass *getSubRegClass(const TargetRegisterClass *RC,
179                                            unsigned SubIdx) const;
180
181  bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
182                            unsigned DefSubReg,
183                            const TargetRegisterClass *SrcRC,
184                            unsigned SrcSubReg) const override;
185
186  /// \returns True if operands defined with this operand type can accept
187  /// a literal constant (i.e. any 32-bit immediate).
188  bool opCanUseLiteralConstant(unsigned OpType) const {
189    // TODO: 64-bit operands have extending behavior from 32-bit literal.
190    return OpType >= AMDGPU::OPERAND_REG_IMM_FIRST &&
191           OpType <= AMDGPU::OPERAND_REG_IMM_LAST;
192  }
193
194  /// \returns True if operands defined with this operand type can accept
195  /// an inline constant. i.e. An integer value in the range (-16, 64) or
196  /// -4.0f, -2.0f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 2.0f, 4.0f.
197  bool opCanUseInlineConstant(unsigned OpType) const;
198
199  unsigned findUnusedRegister(const MachineRegisterInfo &MRI,
200                              const TargetRegisterClass *RC,
201                              const MachineFunction &MF) const;
202
203  unsigned getSGPRPressureSet() const { return SGPRSetID; };
204  unsigned getVGPRPressureSet() const { return VGPRSetID; };
205  unsigned getAGPRPressureSet() const { return AGPRSetID; };
206
207  const TargetRegisterClass *getRegClassForReg(const MachineRegisterInfo &MRI,
208                                               unsigned Reg) const;
209  bool isVGPR(const MachineRegisterInfo &MRI, unsigned Reg) const;
210  bool isAGPR(const MachineRegisterInfo &MRI, unsigned Reg) const;
211  bool isVectorRegister(const MachineRegisterInfo &MRI, unsigned Reg) const {
212    return isVGPR(MRI, Reg) || isAGPR(MRI, Reg);
213  }
214
215  virtual bool
216  isDivergentRegClass(const TargetRegisterClass *RC) const override {
217    return !isSGPRClass(RC);
218  }
219
220  bool isSGPRPressureSet(unsigned SetID) const {
221    return SGPRPressureSets.test(SetID) && !VGPRPressureSets.test(SetID) &&
222           !AGPRPressureSets.test(SetID);
223  }
224  bool isVGPRPressureSet(unsigned SetID) const {
225    return VGPRPressureSets.test(SetID) && !SGPRPressureSets.test(SetID) &&
226           !AGPRPressureSets.test(SetID);
227  }
228  bool isAGPRPressureSet(unsigned SetID) const {
229    return AGPRPressureSets.test(SetID) && !SGPRPressureSets.test(SetID) &&
230           !VGPRPressureSets.test(SetID);
231  }
232
233  ArrayRef<int16_t> getRegSplitParts(const TargetRegisterClass *RC,
234                                     unsigned EltSize) const;
235
236  bool shouldCoalesce(MachineInstr *MI,
237                      const TargetRegisterClass *SrcRC,
238                      unsigned SubReg,
239                      const TargetRegisterClass *DstRC,
240                      unsigned DstSubReg,
241                      const TargetRegisterClass *NewRC,
242                      LiveIntervals &LIS) const override;
243
244  unsigned getRegPressureLimit(const TargetRegisterClass *RC,
245                               MachineFunction &MF) const override;
246
247  unsigned getRegPressureSetLimit(const MachineFunction &MF,
248                                  unsigned Idx) const override;
249
250  const int *getRegUnitPressureSets(unsigned RegUnit) const override;
251
252  unsigned getReturnAddressReg(const MachineFunction &MF) const;
253
254  const TargetRegisterClass *
255  getRegClassForSizeOnBank(unsigned Size,
256                           const RegisterBank &Bank,
257                           const MachineRegisterInfo &MRI) const;
258
259  const TargetRegisterClass *
260  getRegClassForTypeOnBank(LLT Ty,
261                           const RegisterBank &Bank,
262                           const MachineRegisterInfo &MRI) const {
263    return getRegClassForSizeOnBank(Ty.getSizeInBits(), Bank, MRI);
264  }
265
266  const TargetRegisterClass *
267  getConstrainedRegClassForOperand(const MachineOperand &MO,
268                                 const MachineRegisterInfo &MRI) const override;
269
270  const TargetRegisterClass *getBoolRC() const {
271    return isWave32 ? &AMDGPU::SReg_32RegClass
272                    : &AMDGPU::SReg_64RegClass;
273  }
274
275  const TargetRegisterClass *getWaveMaskRegClass() const {
276    return isWave32 ? &AMDGPU::SReg_32_XM0_XEXECRegClass
277                    : &AMDGPU::SReg_64_XEXECRegClass;
278  }
279
280  unsigned getVCC() const;
281
282  const TargetRegisterClass *getRegClass(unsigned RCID) const;
283
284  // Find reaching register definition
285  MachineInstr *findReachingDef(unsigned Reg, unsigned SubReg,
286                                MachineInstr &Use,
287                                MachineRegisterInfo &MRI,
288                                LiveIntervals *LIS) const;
289
290  const uint32_t *getAllVGPRRegMask() const;
291  const uint32_t *getAllAllocatableSRegMask() const;
292
293private:
294  void buildSpillLoadStore(MachineBasicBlock::iterator MI,
295                           unsigned LoadStoreOp,
296                           int Index,
297                           unsigned ValueReg,
298                           bool ValueIsKill,
299                           unsigned ScratchRsrcReg,
300                           unsigned ScratchOffsetReg,
301                           int64_t InstrOffset,
302                           MachineMemOperand *MMO,
303                           RegScavenger *RS) const;
304};
305
306} // End namespace llvm
307
308#endif
309