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 #define GET_REGINFO_HEADER
18 #include "AMDGPUGenRegisterInfo.inc"
19 
20 #include "SIDefines.h"
21 #include "llvm/CodeGen/MachineRegisterInfo.h"
22 
23 namespace llvm {
24 
25 class GCNSubtarget;
26 class LiveIntervals;
27 class SIMachineFunctionInfo;
28 
29 class SIRegisterInfo final : public AMDGPUGenRegisterInfo {
30 private:
31   const GCNSubtarget &ST;
32   bool SpillSGPRToVGPR;
33   bool isWave32;
34   BitVector RegPressureIgnoredUnits;
35 
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;
42 
43   void reserveRegisterTuples(BitVector &, MCRegister Reg) const;
44 
45 public:
46   SIRegisterInfo(const GCNSubtarget &ST);
47 
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);
51 
52   bool spillSGPRToVGPR() const {
53     return SpillSGPRToVGPR;
54   }
55 
56   /// Return the end register initially reserved for the scratch buffer in case
57   /// spilling is needed.
58   MCRegister reservedPrivateSegmentBufferReg(const MachineFunction &MF) const;
59 
60   BitVector getReservedRegs(const MachineFunction &MF) const override;
61 
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;
66 
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 {
70     return 100;
71   }
72 
73   Register getFrameRegister(const MachineFunction &MF) const override;
74 
75   bool hasBasePointer(const MachineFunction &MF) const;
76   Register getBaseRegister() const;
77 
78   bool canRealignStack(const MachineFunction &MF) const override;
79   bool requiresRegisterScavenging(const MachineFunction &Fn) const override;
80 
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;
85 
86   int64_t getMUBUFInstrOffset(const MachineInstr *MI) const;
87 
88   int64_t getFrameIndexInstrOffset(const MachineInstr *MI,
89                                    int Idx) const override;
90 
91   bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override;
92 
93   void materializeFrameBaseRegister(MachineBasicBlock *MBB, Register BaseReg,
94                                     int FrameIdx,
95                                     int64_t Offset) const override;
96 
97   void resolveFrameIndex(MachineInstr &MI, Register BaseReg,
98                          int64_t Offset) const override;
99 
100   bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg,
101                           int64_t Offset) const override;
102 
103   const TargetRegisterClass *getPointerRegClass(
104     const MachineFunction &MF, unsigned Kind = 0) const override;
105 
106   void buildSGPRSpillLoadStore(MachineBasicBlock::iterator MI, int Index,
107                                int Offset, unsigned EltSize, Register VGPR,
108                                int64_t VGPRLanes, RegScavenger *RS,
109                                bool IsLoad) const;
110 
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;
115 
116   bool restoreSGPR(MachineBasicBlock::iterator MI,
117                    int FI, RegScavenger *RS,
118                    bool OnlyToVGPR = false) const;
119 
120   void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
121                            unsigned FIOperandNum,
122                            RegScavenger *RS) const override;
123 
124   bool eliminateSGPRToVGPRSpillFrameIndex(MachineBasicBlock::iterator MI,
125                                           int FI, RegScavenger *RS) const;
126 
127   StringRef getRegAsmName(MCRegister Reg) const override;
128 
129   unsigned getHWRegIndex(MCRegister Reg) const {
130     return getEncodingValue(Reg) & 0xff;
131   }
132 
133   static const TargetRegisterClass *getVGPRClassForBitWidth(unsigned BitWidth);
134   static const TargetRegisterClass *getAGPRClassForBitWidth(unsigned BitWidth);
135   static const TargetRegisterClass *getSGPRClassForBitWidth(unsigned BitWidth);
136 
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;
140 
141   /// \returns true if this class contains only SGPR registers
142   bool isSGPRClass(const TargetRegisterClass *RC) const {
143     return !hasVGPRs(RC) && !hasAGPRs(RC);
144   }
145 
146   /// \returns true if this class ID contains only SGPR registers
147   bool isSGPRClassID(unsigned RCID) const {
148     return isSGPRClass(getRegClass(RCID));
149   }
150 
151   bool isSGPRReg(const MachineRegisterInfo &MRI, Register Reg) const {
152     const TargetRegisterClass *RC;
153     if (Reg.isVirtual())
154       RC = MRI.getRegClass(Reg);
155     else
156       RC = getPhysRegClass(Reg);
157     return isSGPRClass(RC);
158   }
159 
160   /// \returns true if this class contains only AGPR registers
161   bool isAGPRClass(const TargetRegisterClass *RC) const {
162     return hasAGPRs(RC) && !hasVGPRs(RC);
163   }
164 
165   /// \returns true if this class contains VGPR registers.
166   bool hasVGPRs(const TargetRegisterClass *RC) const;
167 
168   /// \returns true if this class contains AGPR registers.
169   bool hasAGPRs(const TargetRegisterClass *RC) const;
170 
171   /// \returns true if this class contains any vector registers.
172   bool hasVectorRegisters(const TargetRegisterClass *RC) const {
173     return hasVGPRs(RC) || hasAGPRs(RC);
174   }
175 
176   /// \returns A VGPR reg class with the same width as \p SRC
177   const TargetRegisterClass *
178   getEquivalentVGPRClass(const TargetRegisterClass *SRC) const;
179 
180   /// \returns An AGPR reg class with the same width as \p SRC
181   const TargetRegisterClass *
182   getEquivalentAGPRClass(const TargetRegisterClass *SRC) const;
183 
184   /// \returns A SGPR reg class with the same width as \p SRC
185   const TargetRegisterClass *
186   getEquivalentSGPRClass(const TargetRegisterClass *VRC) const;
187 
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
190   /// be returned.
191   const TargetRegisterClass *getSubRegClass(const TargetRegisterClass *RC,
192                                             unsigned SubIdx) const;
193 
194   bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
195                             unsigned DefSubReg,
196                             const TargetRegisterClass *SrcRC,
197                             unsigned SrcSubReg) const override;
198 
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;
205   }
206 
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;
211 
212   MCRegister findUnusedRegister(const MachineRegisterInfo &MRI,
213                                 const TargetRegisterClass *RC,
214                                 const MachineFunction &MF,
215                                 bool ReserveHighestVGPR = false) const;
216 
217   const TargetRegisterClass *getRegClassForReg(const MachineRegisterInfo &MRI,
218                                                Register Reg) const;
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);
223   }
224 
225   bool isConstantPhysReg(MCRegister PhysReg) const override;
226 
227   bool isDivergentRegClass(const TargetRegisterClass *RC) const override {
228     return !isSGPRClass(RC);
229   }
230 
231   ArrayRef<int16_t> getRegSplitParts(const TargetRegisterClass *RC,
232                                      unsigned EltSize) const;
233 
234   bool shouldCoalesce(MachineInstr *MI,
235                       const TargetRegisterClass *SrcRC,
236                       unsigned SubReg,
237                       const TargetRegisterClass *DstRC,
238                       unsigned DstSubReg,
239                       const TargetRegisterClass *NewRC,
240                       LiveIntervals &LIS) const override;
241 
242   unsigned getRegPressureLimit(const TargetRegisterClass *RC,
243                                MachineFunction &MF) const override;
244 
245   unsigned getRegPressureSetLimit(const MachineFunction &MF,
246                                   unsigned Idx) const override;
247 
248   const int *getRegUnitPressureSets(unsigned RegUnit) const override;
249 
250   MCRegister getReturnAddressReg(const MachineFunction &MF) const;
251 
252   const TargetRegisterClass *
253   getRegClassForSizeOnBank(unsigned Size,
254                            const RegisterBank &Bank,
255                            const MachineRegisterInfo &MRI) const;
256 
257   const TargetRegisterClass *
258   getRegClassForTypeOnBank(LLT Ty,
259                            const RegisterBank &Bank,
260                            const MachineRegisterInfo &MRI) const {
261     return getRegClassForSizeOnBank(Ty.getSizeInBits(), Bank, MRI);
262   }
263 
264   const TargetRegisterClass *
265   getConstrainedRegClassForOperand(const MachineOperand &MO,
266                                  const MachineRegisterInfo &MRI) const override;
267 
268   const TargetRegisterClass *getBoolRC() const {
269     return isWave32 ? &AMDGPU::SReg_32RegClass
270                     : &AMDGPU::SReg_64RegClass;
271   }
272 
273   const TargetRegisterClass *getWaveMaskRegClass() const {
274     return isWave32 ? &AMDGPU::SReg_32_XM0_XEXECRegClass
275                     : &AMDGPU::SReg_64_XEXECRegClass;
276   }
277 
278   MCRegister getVCC() const;
279 
280   const TargetRegisterClass *getRegClass(unsigned RCID) const;
281 
282   // Find reaching register definition
283   MachineInstr *findReachingDef(Register Reg, unsigned SubReg,
284                                 MachineInstr &Use,
285                                 MachineRegisterInfo &MRI,
286                                 LiveIntervals *LIS) const;
287 
288   const uint32_t *getAllVGPRRegMask() const;
289   const uint32_t *getAllAllocatableSRegMask() const;
290 
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);
300   }
301 
302   // \returns a DWORD offset of a \p SubReg
303   unsigned getChannelFromSubReg(unsigned SubReg) const {
304     return SubReg ? (getSubRegIdxOffset(SubReg) + 31) / 32 : 0;
305   }
306 
307   // \returns a DWORD size of a \p SubReg
308   unsigned getNumChannelsFromSubReg(unsigned SubReg) const {
309     return getNumCoveredRegs(getSubRegIndexLaneMask(SubReg));
310   }
311 
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;
315 
316   /// Return all SGPR128 which satisfy the waves per execution unit requirement
317   /// of the subtarget.
318   ArrayRef<MCPhysReg> getAllSGPR128(const MachineFunction &MF) const;
319 
320   /// Return all SGPR32 which satisfy the waves per execution unit requirement
321   /// of the subtarget.
322   ArrayRef<MCPhysReg> getAllSGPR32(const MachineFunction &MF) const;
323 
324   /// Return all VGPR32 which satisfy the waves per execution unit requirement
325   /// of the subtarget.
326   ArrayRef<MCPhysReg> getAllVGPR32(const MachineFunction &MF) const;
327 
328 private:
329   void buildSpillLoadStore(MachineBasicBlock::iterator MI,
330                            unsigned LoadStoreOp,
331                            int Index,
332                            Register ValueReg,
333                            bool ValueIsKill,
334                            MCRegister ScratchRsrcReg,
335                            MCRegister ScratchOffsetReg,
336                            int64_t InstrOffset,
337                            MachineMemOperand *MMO,
338                            RegScavenger *RS) const;
339 };
340 
341 } // End namespace llvm
342 
343 #endif
344