• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
21 namespace llvm {
22 
23 class GCNSubtarget;
24 class LiveIntervals;
25 class MachineRegisterInfo;
26 class SIMachineFunctionInfo;
27 
28 class SIRegisterInfo final : public AMDGPURegisterInfo {
29 private:
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;
42 public:
43   SIRegisterInfo(const GCNSubtarget &ST);
44 
spillSGPRToVGPR()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.
getCSRFirstUseCost()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 
getHWRegIndex(unsigned Reg)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
isSGPRClass(const TargetRegisterClass * RC)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
isSGPRClassID(unsigned RCID)134   bool isSGPRClassID(unsigned RCID) const {
135     return isSGPRClass(getRegClass(RCID));
136   }
137 
isSGPRReg(const MachineRegisterInfo & MRI,unsigned Reg)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
isAGPRClass(const TargetRegisterClass * RC)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.
hasVectorRegisters(const TargetRegisterClass * RC)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).
opCanUseLiteralConstant(unsigned OpType)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 
getSGPRPressureSet()203   unsigned getSGPRPressureSet() const { return SGPRSetID; };
getVGPRPressureSet()204   unsigned getVGPRPressureSet() const { return VGPRSetID; };
getAGPRPressureSet()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;
isVectorRegister(const MachineRegisterInfo & MRI,unsigned Reg)211   bool isVectorRegister(const MachineRegisterInfo &MRI, unsigned Reg) const {
212     return isVGPR(MRI, Reg) || isAGPR(MRI, Reg);
213   }
214 
215   virtual bool
isDivergentRegClass(const TargetRegisterClass * RC)216   isDivergentRegClass(const TargetRegisterClass *RC) const override {
217     return !isSGPRClass(RC);
218   }
219 
isSGPRPressureSet(unsigned SetID)220   bool isSGPRPressureSet(unsigned SetID) const {
221     return SGPRPressureSets.test(SetID) && !VGPRPressureSets.test(SetID) &&
222            !AGPRPressureSets.test(SetID);
223   }
isVGPRPressureSet(unsigned SetID)224   bool isVGPRPressureSet(unsigned SetID) const {
225     return VGPRPressureSets.test(SetID) && !SGPRPressureSets.test(SetID) &&
226            !AGPRPressureSets.test(SetID);
227   }
isAGPRPressureSet(unsigned SetID)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 *
getRegClassForTypeOnBank(LLT Ty,const RegisterBank & Bank,const MachineRegisterInfo & MRI)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 
getBoolRC()270   const TargetRegisterClass *getBoolRC() const {
271     return isWave32 ? &AMDGPU::SReg_32RegClass
272                     : &AMDGPU::SReg_64RegClass;
273   }
274 
getWaveMaskRegClass()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 
293 private:
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