xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AMDGPU/SIRegisterInfo.h (revision 04eeddc0aa8e0a417a16eaf9d7d095207f4a8623)
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 
22 namespace llvm {
23 
24 class GCNSubtarget;
25 class LiveIntervals;
26 class LivePhysRegs;
27 class RegisterBank;
28 struct SGPRSpillBuilder;
29 
30 class SIRegisterInfo final : public AMDGPUGenRegisterInfo {
31 private:
32   const GCNSubtarget &ST;
33   bool SpillSGPRToVGPR;
34   bool isWave32;
35   BitVector RegPressureIgnoredUnits;
36 
37   /// Sub reg indexes for getRegSplitParts.
38   /// First index represents subreg size from 1 to 16 DWORDs.
39   /// The inner vector is sorted by bit offset.
40   /// Provided a register can be fully split with given subregs,
41   /// all elements of the inner vector combined give a full lane mask.
42   static std::array<std::vector<int16_t>, 16> RegSplitParts;
43 
44   // Table representing sub reg of given width and offset.
45   // First index is subreg size: 32, 64, 96, 128, 160, 192, 224, 256, 512.
46   // Second index is 32 different dword offsets.
47   static std::array<std::array<uint16_t, 32>, 9> SubRegFromChannelTable;
48 
49   void reserveRegisterTuples(BitVector &, MCRegister Reg) const;
50 
51 public:
52   SIRegisterInfo(const GCNSubtarget &ST);
53 
54   /// \returns the sub reg enum value for the given \p Channel
55   /// (e.g. getSubRegFromChannel(0) -> AMDGPU::sub0)
56   static unsigned getSubRegFromChannel(unsigned Channel, unsigned NumRegs = 1);
57 
58   bool spillSGPRToVGPR() const {
59     return SpillSGPRToVGPR;
60   }
61 
62   /// Return the end register initially reserved for the scratch buffer in case
63   /// spilling is needed.
64   MCRegister reservedPrivateSegmentBufferReg(const MachineFunction &MF) const;
65 
66   BitVector getReservedRegs(const MachineFunction &MF) const override;
67 
68   const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
69   const MCPhysReg *getCalleeSavedRegsViaCopy(const MachineFunction *MF) const;
70   const uint32_t *getCallPreservedMask(const MachineFunction &MF,
71                                        CallingConv::ID) const override;
72   const uint32_t *getNoPreservedMask() const override;
73 
74   // Stack access is very expensive. CSRs are also the high registers, and we
75   // want to minimize the number of used registers.
76   unsigned getCSRFirstUseCost() const override {
77     return 100;
78   }
79 
80   const TargetRegisterClass *
81   getLargestLegalSuperClass(const TargetRegisterClass *RC,
82                             const MachineFunction &MF) const override;
83 
84   Register getFrameRegister(const MachineFunction &MF) const override;
85 
86   bool hasBasePointer(const MachineFunction &MF) const;
87   Register getBaseRegister() const;
88 
89   bool shouldRealignStack(const MachineFunction &MF) const override;
90   bool requiresRegisterScavenging(const MachineFunction &Fn) const override;
91 
92   bool requiresFrameIndexScavenging(const MachineFunction &MF) const override;
93   bool requiresFrameIndexReplacementScavenging(
94     const MachineFunction &MF) const override;
95   bool requiresVirtualBaseRegisters(const MachineFunction &Fn) const override;
96 
97   int64_t getScratchInstrOffset(const MachineInstr *MI) const;
98 
99   int64_t getFrameIndexInstrOffset(const MachineInstr *MI,
100                                    int Idx) const override;
101 
102   bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override;
103 
104   Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx,
105                                         int64_t Offset) const override;
106 
107   void resolveFrameIndex(MachineInstr &MI, Register BaseReg,
108                          int64_t Offset) const override;
109 
110   bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg,
111                           int64_t Offset) const override;
112 
113   const TargetRegisterClass *getPointerRegClass(
114     const MachineFunction &MF, unsigned Kind = 0) const override;
115 
116   /// Returns a legal register class to copy a register in the specified class
117   /// to or from. If it is possible to copy the register directly without using
118   /// a cross register class copy, return the specified RC. Returns NULL if it
119   /// is not possible to copy between two registers of the specified class.
120   const TargetRegisterClass *
121   getCrossCopyRegClass(const TargetRegisterClass *RC) const override;
122 
123   void buildVGPRSpillLoadStore(SGPRSpillBuilder &SB, int Index, int Offset,
124                                bool IsLoad, bool IsKill = true) const;
125 
126   /// If \p OnlyToVGPR is true, this will only succeed if this
127   bool spillSGPR(MachineBasicBlock::iterator MI,
128                  int FI, RegScavenger *RS,
129                  LiveIntervals *LIS = nullptr,
130                  bool OnlyToVGPR = false) const;
131 
132   bool restoreSGPR(MachineBasicBlock::iterator MI,
133                    int FI, RegScavenger *RS,
134                    LiveIntervals *LIS = nullptr,
135                    bool OnlyToVGPR = false) const;
136 
137   bool spillEmergencySGPR(MachineBasicBlock::iterator MI,
138                           MachineBasicBlock &RestoreMBB, Register SGPR,
139                           RegScavenger *RS) const;
140 
141   void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
142                            unsigned FIOperandNum,
143                            RegScavenger *RS) const override;
144 
145   bool eliminateSGPRToVGPRSpillFrameIndex(MachineBasicBlock::iterator MI,
146                                           int FI, RegScavenger *RS,
147                                           LiveIntervals *LIS = nullptr) const;
148 
149   StringRef getRegAsmName(MCRegister Reg) const override;
150 
151   // Pseudo regs are not allowed
152   unsigned getHWRegIndex(MCRegister Reg) const {
153     return getEncodingValue(Reg) & 0xff;
154   }
155 
156   LLVM_READONLY
157   const TargetRegisterClass *getVGPRClassForBitWidth(unsigned BitWidth) const;
158 
159   LLVM_READONLY
160   const TargetRegisterClass *getAGPRClassForBitWidth(unsigned BitWidth) const;
161 
162   LLVM_READONLY
163   const TargetRegisterClass *
164   getVectorSuperClassForBitWidth(unsigned BitWidth) const;
165 
166   LLVM_READONLY
167   static const TargetRegisterClass *getSGPRClassForBitWidth(unsigned BitWidth);
168 
169   /// Return the 'base' register class for this register.
170   /// e.g. SGPR0 => SReg_32, VGPR => VGPR_32 SGPR0_SGPR1 -> SReg_32, etc.
171   const TargetRegisterClass *getPhysRegClass(MCRegister Reg) const;
172 
173   /// \returns true if this class contains only SGPR registers
174   static bool isSGPRClass(const TargetRegisterClass *RC) {
175     return hasSGPRs(RC) && !hasVGPRs(RC) && !hasAGPRs(RC);
176   }
177 
178   /// \returns true if this class ID contains only SGPR registers
179   bool isSGPRClassID(unsigned RCID) const {
180     return isSGPRClass(getRegClass(RCID));
181   }
182 
183   bool isSGPRReg(const MachineRegisterInfo &MRI, Register Reg) const;
184 
185   /// \returns true if this class contains only VGPR registers
186   static bool isVGPRClass(const TargetRegisterClass *RC) {
187     return hasVGPRs(RC) && !hasAGPRs(RC) && !hasSGPRs(RC);
188   }
189 
190   /// \returns true if this class contains only AGPR registers
191   static bool isAGPRClass(const TargetRegisterClass *RC) {
192     return hasAGPRs(RC) && !hasVGPRs(RC) && !hasSGPRs(RC);
193   }
194 
195   /// \returns true only if this class contains both VGPR and AGPR registers
196   bool isVectorSuperClass(const TargetRegisterClass *RC) const {
197     return hasVGPRs(RC) && hasAGPRs(RC) && !hasSGPRs(RC);
198   }
199 
200   /// \returns true only if this class contains both VGPR and SGPR registers
201   bool isVSSuperClass(const TargetRegisterClass *RC) const {
202     return hasVGPRs(RC) && hasSGPRs(RC) && !hasAGPRs(RC);
203   }
204 
205   /// \returns true if this class contains VGPR registers.
206   static bool hasVGPRs(const TargetRegisterClass *RC) {
207     return RC->TSFlags & SIRCFlags::HasVGPR;
208   }
209 
210   /// \returns true if this class contains AGPR registers.
211   static bool hasAGPRs(const TargetRegisterClass *RC) {
212     return RC->TSFlags & SIRCFlags::HasAGPR;
213   }
214 
215   /// \returns true if this class contains SGPR registers.
216   static bool hasSGPRs(const TargetRegisterClass *RC) {
217     return RC->TSFlags & SIRCFlags::HasSGPR;
218   }
219 
220   /// \returns true if this class contains any vector registers.
221   static bool hasVectorRegisters(const TargetRegisterClass *RC) {
222     return hasVGPRs(RC) || hasAGPRs(RC);
223   }
224 
225   /// \returns A VGPR reg class with the same width as \p SRC
226   const TargetRegisterClass *
227   getEquivalentVGPRClass(const TargetRegisterClass *SRC) const;
228 
229   /// \returns An AGPR reg class with the same width as \p SRC
230   const TargetRegisterClass *
231   getEquivalentAGPRClass(const TargetRegisterClass *SRC) const;
232 
233   /// \returns A SGPR reg class with the same width as \p SRC
234   const TargetRegisterClass *
235   getEquivalentSGPRClass(const TargetRegisterClass *VRC) const;
236 
237   /// \returns The canonical register class that is used for a sub-register of
238   /// \p RC for the given \p SubIdx.  If \p SubIdx equals NoSubRegister, \p RC
239   /// will be returned.
240   const TargetRegisterClass *getSubRegClass(const TargetRegisterClass *RC,
241                                             unsigned SubIdx) const;
242 
243   /// Returns a register class which is compatible with \p SuperRC, such that a
244   /// subregister exists with class \p SubRC with subregister index \p
245   /// SubIdx. If this is impossible (e.g., an unaligned subregister index within
246   /// a register tuple), return null.
247   const TargetRegisterClass *
248   getCompatibleSubRegClass(const TargetRegisterClass *SuperRC,
249                            const TargetRegisterClass *SubRC,
250                            unsigned SubIdx) const;
251 
252   bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
253                             unsigned DefSubReg,
254                             const TargetRegisterClass *SrcRC,
255                             unsigned SrcSubReg) const override;
256 
257   /// \returns True if operands defined with this operand type can accept
258   /// a literal constant (i.e. any 32-bit immediate).
259   bool opCanUseLiteralConstant(unsigned OpType) const;
260 
261   /// \returns True if operands defined with this operand type can accept
262   /// an inline constant. i.e. An integer value in the range (-16, 64) or
263   /// -4.0f, -2.0f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 2.0f, 4.0f.
264   bool opCanUseInlineConstant(unsigned OpType) const;
265 
266   MCRegister findUnusedRegister(const MachineRegisterInfo &MRI,
267                                 const TargetRegisterClass *RC,
268                                 const MachineFunction &MF,
269                                 bool ReserveHighestVGPR = false) const;
270 
271   const TargetRegisterClass *getRegClassForReg(const MachineRegisterInfo &MRI,
272                                                Register Reg) const;
273   bool isVGPR(const MachineRegisterInfo &MRI, Register Reg) const;
274   bool isAGPR(const MachineRegisterInfo &MRI, Register Reg) const;
275   bool isVectorRegister(const MachineRegisterInfo &MRI, Register Reg) const {
276     return isVGPR(MRI, Reg) || isAGPR(MRI, Reg);
277   }
278 
279   bool isConstantPhysReg(MCRegister PhysReg) const override;
280 
281   bool isDivergentRegClass(const TargetRegisterClass *RC) const override {
282     return !isSGPRClass(RC);
283   }
284 
285   ArrayRef<int16_t> getRegSplitParts(const TargetRegisterClass *RC,
286                                      unsigned EltSize) const;
287 
288   bool shouldCoalesce(MachineInstr *MI,
289                       const TargetRegisterClass *SrcRC,
290                       unsigned SubReg,
291                       const TargetRegisterClass *DstRC,
292                       unsigned DstSubReg,
293                       const TargetRegisterClass *NewRC,
294                       LiveIntervals &LIS) const override;
295 
296   unsigned getRegPressureLimit(const TargetRegisterClass *RC,
297                                MachineFunction &MF) const override;
298 
299   unsigned getRegPressureSetLimit(const MachineFunction &MF,
300                                   unsigned Idx) const override;
301 
302   const int *getRegUnitPressureSets(unsigned RegUnit) const override;
303 
304   MCRegister getReturnAddressReg(const MachineFunction &MF) const;
305 
306   const TargetRegisterClass *
307   getRegClassForSizeOnBank(unsigned Size,
308                            const RegisterBank &Bank,
309                            const MachineRegisterInfo &MRI) const;
310 
311   const TargetRegisterClass *
312   getRegClassForTypeOnBank(LLT Ty,
313                            const RegisterBank &Bank,
314                            const MachineRegisterInfo &MRI) const {
315     return getRegClassForSizeOnBank(Ty.getSizeInBits(), Bank, MRI);
316   }
317 
318   const TargetRegisterClass *
319   getConstrainedRegClassForOperand(const MachineOperand &MO,
320                                  const MachineRegisterInfo &MRI) const override;
321 
322   const TargetRegisterClass *getBoolRC() const {
323     return isWave32 ? &AMDGPU::SReg_32RegClass
324                     : &AMDGPU::SReg_64RegClass;
325   }
326 
327   const TargetRegisterClass *getWaveMaskRegClass() const {
328     return isWave32 ? &AMDGPU::SReg_32_XM0_XEXECRegClass
329                     : &AMDGPU::SReg_64_XEXECRegClass;
330   }
331 
332   // Return the appropriate register class to use for 64-bit VGPRs for the
333   // subtarget.
334   const TargetRegisterClass *getVGPR64Class() const;
335 
336   MCRegister getVCC() const;
337 
338   const TargetRegisterClass *getRegClass(unsigned RCID) const;
339 
340   // Find reaching register definition
341   MachineInstr *findReachingDef(Register Reg, unsigned SubReg,
342                                 MachineInstr &Use,
343                                 MachineRegisterInfo &MRI,
344                                 LiveIntervals *LIS) const;
345 
346   const uint32_t *getAllVGPRRegMask() const;
347   const uint32_t *getAllAGPRRegMask() const;
348   const uint32_t *getAllVectorRegMask() const;
349   const uint32_t *getAllAllocatableSRegMask() const;
350 
351   // \returns number of 32 bit registers covered by a \p LM
352   static unsigned getNumCoveredRegs(LaneBitmask LM) {
353     // The assumption is that every lo16 subreg is an even bit and every hi16
354     // is an adjacent odd bit or vice versa.
355     uint64_t Mask = LM.getAsInteger();
356     uint64_t Even = Mask & 0xAAAAAAAAAAAAAAAAULL;
357     Mask = (Even >> 1) | Mask;
358     uint64_t Odd = Mask & 0x5555555555555555ULL;
359     return countPopulation(Odd);
360   }
361 
362   // \returns a DWORD offset of a \p SubReg
363   unsigned getChannelFromSubReg(unsigned SubReg) const {
364     return SubReg ? (getSubRegIdxOffset(SubReg) + 31) / 32 : 0;
365   }
366 
367   // \returns a DWORD size of a \p SubReg
368   unsigned getNumChannelsFromSubReg(unsigned SubReg) const {
369     return getNumCoveredRegs(getSubRegIndexLaneMask(SubReg));
370   }
371 
372   // For a given 16 bit \p Reg \returns a 32 bit register holding it.
373   // \returns \p Reg otherwise.
374   MCPhysReg get32BitRegister(MCPhysReg Reg) const;
375 
376   // Returns true if a given register class is properly aligned for
377   // the subtarget.
378   bool isProperlyAlignedRC(const TargetRegisterClass &RC) const;
379 
380   /// Return all SGPR128 which satisfy the waves per execution unit requirement
381   /// of the subtarget.
382   ArrayRef<MCPhysReg> getAllSGPR128(const MachineFunction &MF) const;
383 
384   /// Return all SGPR64 which satisfy the waves per execution unit requirement
385   /// of the subtarget.
386   ArrayRef<MCPhysReg> getAllSGPR64(const MachineFunction &MF) const;
387 
388   /// Return all SGPR32 which satisfy the waves per execution unit requirement
389   /// of the subtarget.
390   ArrayRef<MCPhysReg> getAllSGPR32(const MachineFunction &MF) const;
391 
392   // Insert spill or restore instructions.
393   // When lowering spill pseudos, the RegScavenger should be set.
394   // For creating spill instructions during frame lowering, where no scavenger
395   // is available, LiveRegs can be used.
396   void buildSpillLoadStore(MachineBasicBlock &MBB,
397                            MachineBasicBlock::iterator MI, const DebugLoc &DL,
398                            unsigned LoadStoreOp, int Index, Register ValueReg,
399                            bool ValueIsKill, MCRegister ScratchOffsetReg,
400                            int64_t InstrOffset, MachineMemOperand *MMO,
401                            RegScavenger *RS,
402                            LivePhysRegs *LiveRegs = nullptr) const;
403 };
404 
405 } // End namespace llvm
406 
407 #endif
408