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 namespace llvm {
21 
22 class GCNSubtarget;
23 class LiveIntervals;
24 class LivePhysRegs;
25 class RegisterBank;
26 struct SGPRSpillBuilder;
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 
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.
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 shouldRealignStack(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   Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx,
100                                         int64_t Offset) const override;
101 
102   void resolveFrameIndex(MachineInstr &MI, Register BaseReg,
103                          int64_t Offset) const override;
104 
105   bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg,
106                           int64_t Offset) const override;
107 
108   const TargetRegisterClass *getPointerRegClass(
109     const MachineFunction &MF, unsigned Kind = 0) const override;
110 
111   void buildVGPRSpillLoadStore(SGPRSpillBuilder &SB, int Index, int Offset,
112                                bool IsLoad, bool IsKill = true) const;
113 
114   /// If \p OnlyToVGPR is true, this will only succeed if this
115   bool spillSGPR(MachineBasicBlock::iterator MI,
116                  int FI, RegScavenger *RS,
117                  LiveIntervals *LIS = nullptr,
118                  bool OnlyToVGPR = false) const;
119 
120   bool restoreSGPR(MachineBasicBlock::iterator MI,
121                    int FI, RegScavenger *RS,
122                    LiveIntervals *LIS = nullptr,
123                    bool OnlyToVGPR = false) const;
124 
125   void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
126                            unsigned FIOperandNum,
127                            RegScavenger *RS) const override;
128 
129   bool eliminateSGPRToVGPRSpillFrameIndex(MachineBasicBlock::iterator MI,
130                                           int FI, RegScavenger *RS,
131                                           LiveIntervals *LIS = nullptr) const;
132 
133   StringRef getRegAsmName(MCRegister Reg) const override;
134 
135   // Pseudo regs are not allowed
136   unsigned getHWRegIndex(MCRegister Reg) const {
137     return getEncodingValue(Reg) & 0xff;
138   }
139 
140   LLVM_READONLY
141   const TargetRegisterClass *getVGPRClassForBitWidth(unsigned BitWidth) const;
142 
143   LLVM_READONLY
144   const TargetRegisterClass *getAGPRClassForBitWidth(unsigned BitWidth) const;
145 
146   LLVM_READONLY
147   static const TargetRegisterClass *getSGPRClassForBitWidth(unsigned BitWidth);
148 
149   /// Return the 'base' register class for this register.
150   /// e.g. SGPR0 => SReg_32, VGPR => VGPR_32 SGPR0_SGPR1 -> SReg_32, etc.
151   const TargetRegisterClass *getPhysRegClass(MCRegister Reg) const;
152 
153   /// \returns true if this class contains only SGPR registers
154   bool isSGPRClass(const TargetRegisterClass *RC) const {
155     return !hasVGPRs(RC) && !hasAGPRs(RC);
156   }
157 
158   /// \returns true if this class ID contains only SGPR registers
159   bool isSGPRClassID(unsigned RCID) const {
160     return isSGPRClass(getRegClass(RCID));
161   }
162 
163   bool isSGPRReg(const MachineRegisterInfo &MRI, Register Reg) const;
164 
165   /// \returns true if this class contains only AGPR registers
166   bool isAGPRClass(const TargetRegisterClass *RC) const {
167     return hasAGPRs(RC) && !hasVGPRs(RC);
168   }
169 
170   /// \returns true if this class contains VGPR registers.
171   bool hasVGPRs(const TargetRegisterClass *RC) const;
172 
173   /// \returns true if this class contains AGPR registers.
174   bool hasAGPRs(const TargetRegisterClass *RC) const;
175 
176   /// \returns true if this class contains any vector registers.
177   bool hasVectorRegisters(const TargetRegisterClass *RC) const {
178     return hasVGPRs(RC) || hasAGPRs(RC);
179   }
180 
181   /// \returns A VGPR reg class with the same width as \p SRC
182   const TargetRegisterClass *
183   getEquivalentVGPRClass(const TargetRegisterClass *SRC) const;
184 
185   /// \returns An AGPR reg class with the same width as \p SRC
186   const TargetRegisterClass *
187   getEquivalentAGPRClass(const TargetRegisterClass *SRC) const;
188 
189   /// \returns A SGPR reg class with the same width as \p SRC
190   const TargetRegisterClass *
191   getEquivalentSGPRClass(const TargetRegisterClass *VRC) const;
192 
193   /// \returns The canonical register class that is used for a sub-register of
194   /// \p RC for the given \p SubIdx.  If \p SubIdx equals NoSubRegister, \p RC
195   /// will be returned.
196   const TargetRegisterClass *getSubRegClass(const TargetRegisterClass *RC,
197                                             unsigned SubIdx) const;
198 
199   /// Returns a register class which is compatible with \p SuperRC, such that a
200   /// subregister exists with class \p SubRC with subregister index \p
201   /// SubIdx. If this is impossible (e.g., an unaligned subregister index within
202   /// a register tuple), return null.
203   const TargetRegisterClass *
204   getCompatibleSubRegClass(const TargetRegisterClass *SuperRC,
205                            const TargetRegisterClass *SubRC,
206                            unsigned SubIdx) const;
207 
208   bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
209                             unsigned DefSubReg,
210                             const TargetRegisterClass *SrcRC,
211                             unsigned SrcSubReg) const override;
212 
213   /// \returns True if operands defined with this operand type can accept
214   /// a literal constant (i.e. any 32-bit immediate).
215   bool opCanUseLiteralConstant(unsigned OpType) const;
216 
217   /// \returns True if operands defined with this operand type can accept
218   /// an inline constant. i.e. An integer value in the range (-16, 64) or
219   /// -4.0f, -2.0f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 2.0f, 4.0f.
220   bool opCanUseInlineConstant(unsigned OpType) const;
221 
222   MCRegister findUnusedRegister(const MachineRegisterInfo &MRI,
223                                 const TargetRegisterClass *RC,
224                                 const MachineFunction &MF,
225                                 bool ReserveHighestVGPR = false) const;
226 
227   const TargetRegisterClass *getRegClassForReg(const MachineRegisterInfo &MRI,
228                                                Register Reg) const;
229   bool isVGPR(const MachineRegisterInfo &MRI, Register Reg) const;
230   bool isAGPR(const MachineRegisterInfo &MRI, Register Reg) const;
231   bool isVectorRegister(const MachineRegisterInfo &MRI, Register Reg) const {
232     return isVGPR(MRI, Reg) || isAGPR(MRI, Reg);
233   }
234 
235   bool isConstantPhysReg(MCRegister PhysReg) const override;
236 
237   bool isDivergentRegClass(const TargetRegisterClass *RC) const override {
238     return !isSGPRClass(RC);
239   }
240 
241   ArrayRef<int16_t> getRegSplitParts(const TargetRegisterClass *RC,
242                                      unsigned EltSize) const;
243 
244   bool shouldCoalesce(MachineInstr *MI,
245                       const TargetRegisterClass *SrcRC,
246                       unsigned SubReg,
247                       const TargetRegisterClass *DstRC,
248                       unsigned DstSubReg,
249                       const TargetRegisterClass *NewRC,
250                       LiveIntervals &LIS) const override;
251 
252   unsigned getRegPressureLimit(const TargetRegisterClass *RC,
253                                MachineFunction &MF) const override;
254 
255   unsigned getRegPressureSetLimit(const MachineFunction &MF,
256                                   unsigned Idx) const override;
257 
258   const int *getRegUnitPressureSets(unsigned RegUnit) const override;
259 
260   MCRegister getReturnAddressReg(const MachineFunction &MF) const;
261 
262   const TargetRegisterClass *
263   getRegClassForSizeOnBank(unsigned Size,
264                            const RegisterBank &Bank,
265                            const MachineRegisterInfo &MRI) const;
266 
267   const TargetRegisterClass *
268   getRegClassForTypeOnBank(LLT Ty,
269                            const RegisterBank &Bank,
270                            const MachineRegisterInfo &MRI) const {
271     return getRegClassForSizeOnBank(Ty.getSizeInBits(), Bank, MRI);
272   }
273 
274   const TargetRegisterClass *
275   getConstrainedRegClassForOperand(const MachineOperand &MO,
276                                  const MachineRegisterInfo &MRI) const override;
277 
278   const TargetRegisterClass *getBoolRC() const {
279     return isWave32 ? &AMDGPU::SReg_32RegClass
280                     : &AMDGPU::SReg_64RegClass;
281   }
282 
283   const TargetRegisterClass *getWaveMaskRegClass() const {
284     return isWave32 ? &AMDGPU::SReg_32_XM0_XEXECRegClass
285                     : &AMDGPU::SReg_64_XEXECRegClass;
286   }
287 
288   // Return the appropriate register class to use for 64-bit VGPRs for the
289   // subtarget.
290   const TargetRegisterClass *getVGPR64Class() const;
291 
292   MCRegister getVCC() const;
293 
294   const TargetRegisterClass *getRegClass(unsigned RCID) const;
295 
296   // Find reaching register definition
297   MachineInstr *findReachingDef(Register Reg, unsigned SubReg,
298                                 MachineInstr &Use,
299                                 MachineRegisterInfo &MRI,
300                                 LiveIntervals *LIS) const;
301 
302   const uint32_t *getAllVGPRRegMask() const;
303   const uint32_t *getAllAGPRRegMask() const;
304   const uint32_t *getAllVectorRegMask() const;
305   const uint32_t *getAllAllocatableSRegMask() const;
306 
307   // \returns number of 32 bit registers covered by a \p LM
308   static unsigned getNumCoveredRegs(LaneBitmask LM) {
309     // The assumption is that every lo16 subreg is an even bit and every hi16
310     // is an adjacent odd bit or vice versa.
311     uint64_t Mask = LM.getAsInteger();
312     uint64_t Even = Mask & 0xAAAAAAAAAAAAAAAAULL;
313     Mask = (Even >> 1) | Mask;
314     uint64_t Odd = Mask & 0x5555555555555555ULL;
315     return countPopulation(Odd);
316   }
317 
318   // \returns a DWORD offset of a \p SubReg
319   unsigned getChannelFromSubReg(unsigned SubReg) const {
320     return SubReg ? (getSubRegIdxOffset(SubReg) + 31) / 32 : 0;
321   }
322 
323   // \returns a DWORD size of a \p SubReg
324   unsigned getNumChannelsFromSubReg(unsigned SubReg) const {
325     return getNumCoveredRegs(getSubRegIndexLaneMask(SubReg));
326   }
327 
328   // For a given 16 bit \p Reg \returns a 32 bit register holding it.
329   // \returns \p Reg otherwise.
330   MCPhysReg get32BitRegister(MCPhysReg Reg) const;
331 
332   // Returns true if a given register class is properly aligned for
333   // the subtarget.
334   bool isProperlyAlignedRC(const TargetRegisterClass &RC) const;
335 
336   /// Return all SGPR128 which satisfy the waves per execution unit requirement
337   /// of the subtarget.
338   ArrayRef<MCPhysReg> getAllSGPR128(const MachineFunction &MF) const;
339 
340   /// Return all SGPR64 which satisfy the waves per execution unit requirement
341   /// of the subtarget.
342   ArrayRef<MCPhysReg> getAllSGPR64(const MachineFunction &MF) const;
343 
344   /// Return all SGPR32 which satisfy the waves per execution unit requirement
345   /// of the subtarget.
346   ArrayRef<MCPhysReg> getAllSGPR32(const MachineFunction &MF) const;
347 
348   // Insert spill or restore instructions.
349   // When lowering spill pseudos, the RegScavenger should be set.
350   // For creating spill instructions during frame lowering, where no scavenger
351   // is available, LiveRegs can be used.
352   void buildSpillLoadStore(MachineBasicBlock &MBB,
353                            MachineBasicBlock::iterator MI, unsigned LoadStoreOp,
354                            int Index, Register ValueReg, bool ValueIsKill,
355                            MCRegister ScratchOffsetReg, int64_t InstrOffset,
356                            MachineMemOperand *MMO, RegScavenger *RS,
357                            LivePhysRegs *LiveRegs = nullptr) const;
358 };
359 
360 } // End namespace llvm
361 
362 #endif
363