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   // Table representing sub reg of given width and offset.
44   // First index is subreg size: 32, 64, 96, 128, 160, 192, 224, 256, 512.
45   // Second index is 32 different dword offsets.
46   static std::array<std::array<uint16_t, 32>, 9> SubRegFromChannelTable;
47 
48   void reserveRegisterTuples(BitVector &, MCRegister Reg) const;
49 
50 public:
51   SIRegisterInfo(const GCNSubtarget &ST);
52 
53   /// \returns the sub reg enum value for the given \p Channel
54   /// (e.g. getSubRegFromChannel(0) -> AMDGPU::sub0)
55   static unsigned getSubRegFromChannel(unsigned Channel, unsigned NumRegs = 1);
56 
spillSGPRToVGPR()57   bool spillSGPRToVGPR() const {
58     return SpillSGPRToVGPR;
59   }
60 
61   /// Return the end register initially reserved for the scratch buffer in case
62   /// spilling is needed.
63   MCRegister reservedPrivateSegmentBufferReg(const MachineFunction &MF) const;
64 
65   BitVector getReservedRegs(const MachineFunction &MF) const override;
66 
67   const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
68   const MCPhysReg *getCalleeSavedRegsViaCopy(const MachineFunction *MF) const;
69   const uint32_t *getCallPreservedMask(const MachineFunction &MF,
70                                        CallingConv::ID) const override;
71   const uint32_t *getNoPreservedMask() const override;
72 
73   // Stack access is very expensive. CSRs are also the high registers, and we
74   // want to minimize the number of used registers.
getCSRFirstUseCost()75   unsigned getCSRFirstUseCost() const override {
76     return 100;
77   }
78 
79   Register getFrameRegister(const MachineFunction &MF) const override;
80 
81   bool hasBasePointer(const MachineFunction &MF) const;
82   Register getBaseRegister() const;
83 
84   bool canRealignStack(const MachineFunction &MF) const override;
85   bool requiresRegisterScavenging(const MachineFunction &Fn) const override;
86 
87   bool requiresFrameIndexScavenging(const MachineFunction &MF) const override;
88   bool requiresFrameIndexReplacementScavenging(
89     const MachineFunction &MF) const override;
90   bool requiresVirtualBaseRegisters(const MachineFunction &Fn) const override;
91 
92   int64_t getScratchInstrOffset(const MachineInstr *MI) const;
93 
94   int64_t getFrameIndexInstrOffset(const MachineInstr *MI,
95                                    int Idx) const override;
96 
97   bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override;
98 
99   void materializeFrameBaseRegister(MachineBasicBlock *MBB, Register BaseReg,
100                                     int FrameIdx,
101                                     int64_t Offset) const override;
102 
103   void resolveFrameIndex(MachineInstr &MI, Register BaseReg,
104                          int64_t Offset) const override;
105 
106   bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg,
107                           int64_t Offset) const override;
108 
109   const TargetRegisterClass *getPointerRegClass(
110     const MachineFunction &MF, unsigned Kind = 0) const override;
111 
112   void buildSGPRSpillLoadStore(MachineBasicBlock::iterator MI, int Index,
113                                int Offset, unsigned EltSize, Register VGPR,
114                                int64_t VGPRLanes, RegScavenger *RS,
115                                bool IsLoad) const;
116 
117   /// If \p OnlyToVGPR is true, this will only succeed if this
118   bool spillSGPR(MachineBasicBlock::iterator MI,
119                  int FI, RegScavenger *RS,
120                  bool OnlyToVGPR = false) const;
121 
122   bool restoreSGPR(MachineBasicBlock::iterator MI,
123                    int FI, RegScavenger *RS,
124                    bool OnlyToVGPR = false) const;
125 
126   void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
127                            unsigned FIOperandNum,
128                            RegScavenger *RS) const override;
129 
130   bool eliminateSGPRToVGPRSpillFrameIndex(MachineBasicBlock::iterator MI,
131                                           int FI, RegScavenger *RS) const;
132 
133   StringRef getRegAsmName(MCRegister Reg) const override;
134 
135   // Pseudo regs are not allowed
getHWRegIndex(MCRegister Reg)136   unsigned getHWRegIndex(MCRegister Reg) const {
137     return getEncodingValue(Reg) & 0xff;
138   }
139 
140   static const TargetRegisterClass *getVGPRClassForBitWidth(unsigned BitWidth);
141   static const TargetRegisterClass *getAGPRClassForBitWidth(unsigned BitWidth);
142   static const TargetRegisterClass *getSGPRClassForBitWidth(unsigned BitWidth);
143 
144   /// Return the 'base' register class for this register.
145   /// e.g. SGPR0 => SReg_32, VGPR => VGPR_32 SGPR0_SGPR1 -> SReg_32, etc.
146   const TargetRegisterClass *getPhysRegClass(MCRegister Reg) const;
147 
148   /// \returns true if this class contains only SGPR registers
isSGPRClass(const TargetRegisterClass * RC)149   bool isSGPRClass(const TargetRegisterClass *RC) const {
150     return !hasVGPRs(RC) && !hasAGPRs(RC);
151   }
152 
153   /// \returns true if this class ID contains only SGPR registers
isSGPRClassID(unsigned RCID)154   bool isSGPRClassID(unsigned RCID) const {
155     return isSGPRClass(getRegClass(RCID));
156   }
157 
isSGPRReg(const MachineRegisterInfo & MRI,Register Reg)158   bool isSGPRReg(const MachineRegisterInfo &MRI, Register Reg) const {
159     const TargetRegisterClass *RC;
160     if (Reg.isVirtual())
161       RC = MRI.getRegClass(Reg);
162     else
163       RC = getPhysRegClass(Reg);
164     return isSGPRClass(RC);
165   }
166 
167   /// \returns true if this class contains only AGPR registers
isAGPRClass(const TargetRegisterClass * RC)168   bool isAGPRClass(const TargetRegisterClass *RC) const {
169     return hasAGPRs(RC) && !hasVGPRs(RC);
170   }
171 
172   /// \returns true if this class contains VGPR registers.
173   bool hasVGPRs(const TargetRegisterClass *RC) const;
174 
175   /// \returns true if this class contains AGPR registers.
176   bool hasAGPRs(const TargetRegisterClass *RC) const;
177 
178   /// \returns true if this class contains any vector registers.
hasVectorRegisters(const TargetRegisterClass * RC)179   bool hasVectorRegisters(const TargetRegisterClass *RC) const {
180     return hasVGPRs(RC) || hasAGPRs(RC);
181   }
182 
183   /// \returns A VGPR reg class with the same width as \p SRC
184   const TargetRegisterClass *
185   getEquivalentVGPRClass(const TargetRegisterClass *SRC) const;
186 
187   /// \returns An AGPR reg class with the same width as \p SRC
188   const TargetRegisterClass *
189   getEquivalentAGPRClass(const TargetRegisterClass *SRC) const;
190 
191   /// \returns A SGPR reg class with the same width as \p SRC
192   const TargetRegisterClass *
193   getEquivalentSGPRClass(const TargetRegisterClass *VRC) const;
194 
195   /// \returns The register class that is used for a sub-register of \p RC for
196   /// the given \p SubIdx.  If \p SubIdx equals NoSubRegister, \p RC will
197   /// be returned.
198   const TargetRegisterClass *getSubRegClass(const TargetRegisterClass *RC,
199                                             unsigned SubIdx) const;
200 
201   bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
202                             unsigned DefSubReg,
203                             const TargetRegisterClass *SrcRC,
204                             unsigned SrcSubReg) const override;
205 
206   /// \returns True if operands defined with this operand type can accept
207   /// a literal constant (i.e. any 32-bit immediate).
opCanUseLiteralConstant(unsigned OpType)208   bool opCanUseLiteralConstant(unsigned OpType) const {
209     // TODO: 64-bit operands have extending behavior from 32-bit literal.
210     return OpType >= AMDGPU::OPERAND_REG_IMM_FIRST &&
211            OpType <= AMDGPU::OPERAND_REG_IMM_LAST;
212   }
213 
214   /// \returns True if operands defined with this operand type can accept
215   /// an inline constant. i.e. An integer value in the range (-16, 64) or
216   /// -4.0f, -2.0f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 2.0f, 4.0f.
217   bool opCanUseInlineConstant(unsigned OpType) const;
218 
219   MCRegister findUnusedRegister(const MachineRegisterInfo &MRI,
220                                 const TargetRegisterClass *RC,
221                                 const MachineFunction &MF,
222                                 bool ReserveHighestVGPR = false) const;
223 
224   const TargetRegisterClass *getRegClassForReg(const MachineRegisterInfo &MRI,
225                                                Register Reg) const;
226   bool isVGPR(const MachineRegisterInfo &MRI, Register Reg) const;
227   bool isAGPR(const MachineRegisterInfo &MRI, Register Reg) const;
isVectorRegister(const MachineRegisterInfo & MRI,Register Reg)228   bool isVectorRegister(const MachineRegisterInfo &MRI, Register Reg) const {
229     return isVGPR(MRI, Reg) || isAGPR(MRI, Reg);
230   }
231 
232   bool isConstantPhysReg(MCRegister PhysReg) const override;
233 
isDivergentRegClass(const TargetRegisterClass * RC)234   bool isDivergentRegClass(const TargetRegisterClass *RC) const override {
235     return !isSGPRClass(RC);
236   }
237 
238   ArrayRef<int16_t> getRegSplitParts(const TargetRegisterClass *RC,
239                                      unsigned EltSize) const;
240 
241   bool shouldCoalesce(MachineInstr *MI,
242                       const TargetRegisterClass *SrcRC,
243                       unsigned SubReg,
244                       const TargetRegisterClass *DstRC,
245                       unsigned DstSubReg,
246                       const TargetRegisterClass *NewRC,
247                       LiveIntervals &LIS) const override;
248 
249   unsigned getRegPressureLimit(const TargetRegisterClass *RC,
250                                MachineFunction &MF) const override;
251 
252   unsigned getRegPressureSetLimit(const MachineFunction &MF,
253                                   unsigned Idx) const override;
254 
255   const int *getRegUnitPressureSets(unsigned RegUnit) const override;
256 
257   MCRegister getReturnAddressReg(const MachineFunction &MF) const;
258 
259   const TargetRegisterClass *
260   getRegClassForSizeOnBank(unsigned Size,
261                            const RegisterBank &Bank,
262                            const MachineRegisterInfo &MRI) const;
263 
264   const TargetRegisterClass *
getRegClassForTypeOnBank(LLT Ty,const RegisterBank & Bank,const MachineRegisterInfo & MRI)265   getRegClassForTypeOnBank(LLT Ty,
266                            const RegisterBank &Bank,
267                            const MachineRegisterInfo &MRI) const {
268     return getRegClassForSizeOnBank(Ty.getSizeInBits(), Bank, MRI);
269   }
270 
271   const TargetRegisterClass *
272   getConstrainedRegClassForOperand(const MachineOperand &MO,
273                                  const MachineRegisterInfo &MRI) const override;
274 
getBoolRC()275   const TargetRegisterClass *getBoolRC() const {
276     return isWave32 ? &AMDGPU::SReg_32RegClass
277                     : &AMDGPU::SReg_64RegClass;
278   }
279 
getWaveMaskRegClass()280   const TargetRegisterClass *getWaveMaskRegClass() const {
281     return isWave32 ? &AMDGPU::SReg_32_XM0_XEXECRegClass
282                     : &AMDGPU::SReg_64_XEXECRegClass;
283   }
284 
285   MCRegister getVCC() const;
286 
287   const TargetRegisterClass *getRegClass(unsigned RCID) const;
288 
289   // Find reaching register definition
290   MachineInstr *findReachingDef(Register Reg, unsigned SubReg,
291                                 MachineInstr &Use,
292                                 MachineRegisterInfo &MRI,
293                                 LiveIntervals *LIS) const;
294 
295   const uint32_t *getAllVGPRRegMask() const;
296   const uint32_t *getAllAllocatableSRegMask() const;
297 
298   // \returns number of 32 bit registers covered by a \p LM
getNumCoveredRegs(LaneBitmask LM)299   static unsigned getNumCoveredRegs(LaneBitmask LM) {
300     // The assumption is that every lo16 subreg is an even bit and every hi16
301     // is an adjacent odd bit or vice versa.
302     uint64_t Mask = LM.getAsInteger();
303     uint64_t Even = Mask & 0xAAAAAAAAAAAAAAAAULL;
304     Mask = (Even >> 1) | Mask;
305     uint64_t Odd = Mask & 0x5555555555555555ULL;
306     return countPopulation(Odd);
307   }
308 
309   // \returns a DWORD offset of a \p SubReg
getChannelFromSubReg(unsigned SubReg)310   unsigned getChannelFromSubReg(unsigned SubReg) const {
311     return SubReg ? (getSubRegIdxOffset(SubReg) + 31) / 32 : 0;
312   }
313 
314   // \returns a DWORD size of a \p SubReg
getNumChannelsFromSubReg(unsigned SubReg)315   unsigned getNumChannelsFromSubReg(unsigned SubReg) const {
316     return getNumCoveredRegs(getSubRegIndexLaneMask(SubReg));
317   }
318 
319   // For a given 16 bit \p Reg \returns a 32 bit register holding it.
320   // \returns \p Reg otherwise.
321   MCPhysReg get32BitRegister(MCPhysReg Reg) const;
322 
323   /// Return all SGPR128 which satisfy the waves per execution unit requirement
324   /// of the subtarget.
325   ArrayRef<MCPhysReg> getAllSGPR128(const MachineFunction &MF) const;
326 
327   /// Return all SGPR64 which satisfy the waves per execution unit requirement
328   /// of the subtarget.
329   ArrayRef<MCPhysReg> getAllSGPR64(const MachineFunction &MF) const;
330 
331   /// Return all SGPR32 which satisfy the waves per execution unit requirement
332   /// of the subtarget.
333   ArrayRef<MCPhysReg> getAllSGPR32(const MachineFunction &MF) const;
334 
335 private:
336   void buildSpillLoadStore(MachineBasicBlock::iterator MI,
337                            unsigned LoadStoreOp,
338                            int Index,
339                            Register ValueReg,
340                            bool ValueIsKill,
341                            MCRegister ScratchOffsetReg,
342                            int64_t InstrOffset,
343                            MachineMemOperand *MMO,
344                            RegScavenger *RS) const;
345 };
346 
347 } // End namespace llvm
348 
349 #endif
350