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   struct SpilledReg {
55     Register VGPR;
56     int Lane = -1;
57 
58     SpilledReg() = default;
59     SpilledReg(Register R, int L) : VGPR(R), Lane(L) {}
60 
61     bool hasLane() { return Lane != -1; }
62     bool hasReg() { return VGPR != 0; }
63   };
64 
65   /// \returns the sub reg enum value for the given \p Channel
66   /// (e.g. getSubRegFromChannel(0) -> AMDGPU::sub0)
67   static unsigned getSubRegFromChannel(unsigned Channel, unsigned NumRegs = 1);
68 
69   bool spillSGPRToVGPR() const {
70     return SpillSGPRToVGPR;
71   }
72 
73   /// Return the largest available SGPR aligned to \p Align for the register
74   /// class \p RC.
75   MCRegister getAlignedHighSGPRForRC(const MachineFunction &MF,
76                                      const unsigned Align,
77                                      const TargetRegisterClass *RC) const;
78 
79   /// Return the end register initially reserved for the scratch buffer in case
80   /// spilling is needed.
81   MCRegister reservedPrivateSegmentBufferReg(const MachineFunction &MF) const;
82 
83   BitVector getReservedRegs(const MachineFunction &MF) const override;
84   bool isAsmClobberable(const MachineFunction &MF,
85                         MCRegister PhysReg) const override;
86 
87   const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
88   const MCPhysReg *getCalleeSavedRegsViaCopy(const MachineFunction *MF) const;
89   const uint32_t *getCallPreservedMask(const MachineFunction &MF,
90                                        CallingConv::ID) const override;
91   const uint32_t *getNoPreservedMask() const override;
92 
93   // Stack access is very expensive. CSRs are also the high registers, and we
94   // want to minimize the number of used registers.
95   unsigned getCSRFirstUseCost() const override {
96     return 100;
97   }
98 
99   const TargetRegisterClass *
100   getLargestLegalSuperClass(const TargetRegisterClass *RC,
101                             const MachineFunction &MF) const override;
102 
103   Register getFrameRegister(const MachineFunction &MF) const override;
104 
105   bool hasBasePointer(const MachineFunction &MF) const;
106   Register getBaseRegister() const;
107 
108   bool shouldRealignStack(const MachineFunction &MF) const override;
109   bool requiresRegisterScavenging(const MachineFunction &Fn) const override;
110 
111   bool requiresFrameIndexScavenging(const MachineFunction &MF) const override;
112   bool requiresFrameIndexReplacementScavenging(
113     const MachineFunction &MF) const override;
114   bool requiresVirtualBaseRegisters(const MachineFunction &Fn) const override;
115 
116   int64_t getScratchInstrOffset(const MachineInstr *MI) const;
117 
118   int64_t getFrameIndexInstrOffset(const MachineInstr *MI,
119                                    int Idx) const override;
120 
121   bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override;
122 
123   Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx,
124                                         int64_t Offset) const override;
125 
126   void resolveFrameIndex(MachineInstr &MI, Register BaseReg,
127                          int64_t Offset) const override;
128 
129   bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg,
130                           int64_t Offset) const override;
131 
132   const TargetRegisterClass *getPointerRegClass(
133     const MachineFunction &MF, unsigned Kind = 0) const override;
134 
135   /// Returns a legal register class to copy a register in the specified class
136   /// to or from. If it is possible to copy the register directly without using
137   /// a cross register class copy, return the specified RC. Returns NULL if it
138   /// is not possible to copy between two registers of the specified class.
139   const TargetRegisterClass *
140   getCrossCopyRegClass(const TargetRegisterClass *RC) const override;
141 
142   void buildVGPRSpillLoadStore(SGPRSpillBuilder &SB, int Index, int Offset,
143                                bool IsLoad, bool IsKill = true) const;
144 
145   /// If \p OnlyToVGPR is true, this will only succeed if this manages to find a
146   /// free VGPR lane to spill.
147   bool spillSGPR(MachineBasicBlock::iterator MI, int FI, RegScavenger *RS,
148                  SlotIndexes *Indexes = nullptr, LiveIntervals *LIS = nullptr,
149                  bool OnlyToVGPR = false,
150                  bool SpillToPhysVGPRLane = false) const;
151 
152   bool restoreSGPR(MachineBasicBlock::iterator MI, int FI, RegScavenger *RS,
153                    SlotIndexes *Indexes = nullptr, LiveIntervals *LIS = nullptr,
154                    bool OnlyToVGPR = false,
155                    bool SpillToPhysVGPRLane = false) const;
156 
157   bool spillEmergencySGPR(MachineBasicBlock::iterator MI,
158                           MachineBasicBlock &RestoreMBB, Register SGPR,
159                           RegScavenger *RS) const;
160 
161   bool supportsBackwardScavenger() const override {
162     return true;
163   }
164 
165   bool eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
166                            unsigned FIOperandNum,
167                            RegScavenger *RS) const override;
168 
169   bool eliminateSGPRToVGPRSpillFrameIndex(
170       MachineBasicBlock::iterator MI, int FI, RegScavenger *RS,
171       SlotIndexes *Indexes = nullptr, LiveIntervals *LIS = nullptr,
172       bool SpillToPhysVGPRLane = false) const;
173 
174   StringRef getRegAsmName(MCRegister Reg) const override;
175 
176   // Pseudo regs are not allowed
177   unsigned getHWRegIndex(MCRegister Reg) const {
178     return getEncodingValue(Reg) & 0xff;
179   }
180 
181   LLVM_READONLY
182   const TargetRegisterClass *getVGPRClassForBitWidth(unsigned BitWidth) const;
183 
184   LLVM_READONLY
185   const TargetRegisterClass *getAGPRClassForBitWidth(unsigned BitWidth) const;
186 
187   LLVM_READONLY
188   const TargetRegisterClass *
189   getVectorSuperClassForBitWidth(unsigned BitWidth) const;
190 
191   LLVM_READONLY
192   static const TargetRegisterClass *getSGPRClassForBitWidth(unsigned BitWidth);
193 
194   /// \returns true if this class contains only SGPR registers
195   static bool isSGPRClass(const TargetRegisterClass *RC) {
196     return hasSGPRs(RC) && !hasVGPRs(RC) && !hasAGPRs(RC);
197   }
198 
199   /// \returns true if this class ID contains only SGPR registers
200   bool isSGPRClassID(unsigned RCID) const {
201     return isSGPRClass(getRegClass(RCID));
202   }
203 
204   bool isSGPRReg(const MachineRegisterInfo &MRI, Register Reg) const;
205 
206   /// \returns true if this class contains only VGPR registers
207   static bool isVGPRClass(const TargetRegisterClass *RC) {
208     return hasVGPRs(RC) && !hasAGPRs(RC) && !hasSGPRs(RC);
209   }
210 
211   /// \returns true if this class contains only AGPR registers
212   static bool isAGPRClass(const TargetRegisterClass *RC) {
213     return hasAGPRs(RC) && !hasVGPRs(RC) && !hasSGPRs(RC);
214   }
215 
216   /// \returns true only if this class contains both VGPR and AGPR registers
217   bool isVectorSuperClass(const TargetRegisterClass *RC) const {
218     return hasVGPRs(RC) && hasAGPRs(RC) && !hasSGPRs(RC);
219   }
220 
221   /// \returns true only if this class contains both VGPR and SGPR registers
222   bool isVSSuperClass(const TargetRegisterClass *RC) const {
223     return hasVGPRs(RC) && hasSGPRs(RC) && !hasAGPRs(RC);
224   }
225 
226   /// \returns true if this class contains VGPR registers.
227   static bool hasVGPRs(const TargetRegisterClass *RC) {
228     return RC->TSFlags & SIRCFlags::HasVGPR;
229   }
230 
231   /// \returns true if this class contains AGPR registers.
232   static bool hasAGPRs(const TargetRegisterClass *RC) {
233     return RC->TSFlags & SIRCFlags::HasAGPR;
234   }
235 
236   /// \returns true if this class contains SGPR registers.
237   static bool hasSGPRs(const TargetRegisterClass *RC) {
238     return RC->TSFlags & SIRCFlags::HasSGPR;
239   }
240 
241   /// \returns true if this class contains any vector registers.
242   static bool hasVectorRegisters(const TargetRegisterClass *RC) {
243     return hasVGPRs(RC) || hasAGPRs(RC);
244   }
245 
246   /// \returns A VGPR reg class with the same width as \p SRC
247   const TargetRegisterClass *
248   getEquivalentVGPRClass(const TargetRegisterClass *SRC) const;
249 
250   /// \returns An AGPR reg class with the same width as \p SRC
251   const TargetRegisterClass *
252   getEquivalentAGPRClass(const TargetRegisterClass *SRC) const;
253 
254   /// \returns A SGPR reg class with the same width as \p SRC
255   const TargetRegisterClass *
256   getEquivalentSGPRClass(const TargetRegisterClass *VRC) const;
257 
258   /// Returns a register class which is compatible with \p SuperRC, such that a
259   /// subregister exists with class \p SubRC with subregister index \p
260   /// SubIdx. If this is impossible (e.g., an unaligned subregister index within
261   /// a register tuple), return null.
262   const TargetRegisterClass *
263   getCompatibleSubRegClass(const TargetRegisterClass *SuperRC,
264                            const TargetRegisterClass *SubRC,
265                            unsigned SubIdx) const;
266 
267   bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
268                             unsigned DefSubReg,
269                             const TargetRegisterClass *SrcRC,
270                             unsigned SrcSubReg) const override;
271 
272   /// \returns True if operands defined with this operand type can accept
273   /// a literal constant (i.e. any 32-bit immediate).
274   bool opCanUseLiteralConstant(unsigned OpType) const;
275 
276   /// \returns True if operands defined with this operand type can accept
277   /// an inline constant. i.e. An integer value in the range (-16, 64) or
278   /// -4.0f, -2.0f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 2.0f, 4.0f.
279   bool opCanUseInlineConstant(unsigned OpType) const;
280 
281   MCRegister findUnusedRegister(const MachineRegisterInfo &MRI,
282                                 const TargetRegisterClass *RC,
283                                 const MachineFunction &MF,
284                                 bool ReserveHighestVGPR = false) const;
285 
286   const TargetRegisterClass *getRegClassForReg(const MachineRegisterInfo &MRI,
287                                                Register Reg) const;
288   const TargetRegisterClass *
289   getRegClassForOperandReg(const MachineRegisterInfo &MRI,
290                            const MachineOperand &MO) const;
291 
292   bool isVGPR(const MachineRegisterInfo &MRI, Register Reg) const;
293   bool isAGPR(const MachineRegisterInfo &MRI, Register Reg) const;
294   bool isVectorRegister(const MachineRegisterInfo &MRI, Register Reg) const {
295     return isVGPR(MRI, Reg) || isAGPR(MRI, Reg);
296   }
297 
298   // FIXME: SGPRs are assumed to be uniform, but this is not true for i1 SGPRs
299   // (such as VCC) which hold a wave-wide vector of boolean values. Examining
300   // just the register class is not suffcient; it needs to be combined with a
301   // value type. The next predicate isUniformReg() does this correctly.
302   bool isDivergentRegClass(const TargetRegisterClass *RC) const override {
303     return !isSGPRClass(RC);
304   }
305 
306   bool isUniformReg(const MachineRegisterInfo &MRI, const RegisterBankInfo &RBI,
307                     Register Reg) const override;
308 
309   ArrayRef<int16_t> getRegSplitParts(const TargetRegisterClass *RC,
310                                      unsigned EltSize) const;
311 
312   bool shouldCoalesce(MachineInstr *MI,
313                       const TargetRegisterClass *SrcRC,
314                       unsigned SubReg,
315                       const TargetRegisterClass *DstRC,
316                       unsigned DstSubReg,
317                       const TargetRegisterClass *NewRC,
318                       LiveIntervals &LIS) const override;
319 
320   unsigned getRegPressureLimit(const TargetRegisterClass *RC,
321                                MachineFunction &MF) const override;
322 
323   unsigned getRegPressureSetLimit(const MachineFunction &MF,
324                                   unsigned Idx) const override;
325 
326   const int *getRegUnitPressureSets(unsigned RegUnit) const override;
327 
328   MCRegister getReturnAddressReg(const MachineFunction &MF) const;
329 
330   const TargetRegisterClass *
331   getRegClassForSizeOnBank(unsigned Size, const RegisterBank &Bank) const;
332 
333   const TargetRegisterClass *
334   getRegClassForTypeOnBank(LLT Ty, const RegisterBank &Bank) const {
335     return getRegClassForSizeOnBank(Ty.getSizeInBits(), Bank);
336   }
337 
338   const TargetRegisterClass *
339   getConstrainedRegClassForOperand(const MachineOperand &MO,
340                                  const MachineRegisterInfo &MRI) const override;
341 
342   const TargetRegisterClass *getBoolRC() const {
343     return isWave32 ? &AMDGPU::SReg_32RegClass
344                     : &AMDGPU::SReg_64RegClass;
345   }
346 
347   const TargetRegisterClass *getWaveMaskRegClass() const {
348     return isWave32 ? &AMDGPU::SReg_32_XM0_XEXECRegClass
349                     : &AMDGPU::SReg_64_XEXECRegClass;
350   }
351 
352   // Return the appropriate register class to use for 64-bit VGPRs for the
353   // subtarget.
354   const TargetRegisterClass *getVGPR64Class() const;
355 
356   MCRegister getVCC() const;
357 
358   MCRegister getExec() const;
359 
360   const TargetRegisterClass *getRegClass(unsigned RCID) const;
361 
362   // Find reaching register definition
363   MachineInstr *findReachingDef(Register Reg, unsigned SubReg,
364                                 MachineInstr &Use,
365                                 MachineRegisterInfo &MRI,
366                                 LiveIntervals *LIS) const;
367 
368   const uint32_t *getAllVGPRRegMask() const;
369   const uint32_t *getAllAGPRRegMask() const;
370   const uint32_t *getAllVectorRegMask() const;
371   const uint32_t *getAllAllocatableSRegMask() const;
372 
373   // \returns number of 32 bit registers covered by a \p LM
374   static unsigned getNumCoveredRegs(LaneBitmask LM) {
375     // The assumption is that every lo16 subreg is an even bit and every hi16
376     // is an adjacent odd bit or vice versa.
377     uint64_t Mask = LM.getAsInteger();
378     uint64_t Even = Mask & 0xAAAAAAAAAAAAAAAAULL;
379     Mask = (Even >> 1) | Mask;
380     uint64_t Odd = Mask & 0x5555555555555555ULL;
381     return llvm::popcount(Odd);
382   }
383 
384   // \returns a DWORD offset of a \p SubReg
385   unsigned getChannelFromSubReg(unsigned SubReg) const {
386     return SubReg ? (getSubRegIdxOffset(SubReg) + 31) / 32 : 0;
387   }
388 
389   // \returns a DWORD size of a \p SubReg
390   unsigned getNumChannelsFromSubReg(unsigned SubReg) const {
391     return getNumCoveredRegs(getSubRegIndexLaneMask(SubReg));
392   }
393 
394   // For a given 16 bit \p Reg \returns a 32 bit register holding it.
395   // \returns \p Reg otherwise.
396   MCPhysReg get32BitRegister(MCPhysReg Reg) const;
397 
398   // Returns true if a given register class is properly aligned for
399   // the subtarget.
400   bool isProperlyAlignedRC(const TargetRegisterClass &RC) const;
401 
402   // Given \p RC returns corresponding aligned register class if required
403   // by the subtarget.
404   const TargetRegisterClass *
405   getProperlyAlignedRC(const TargetRegisterClass *RC) const;
406 
407   /// Return all SGPR128 which satisfy the waves per execution unit requirement
408   /// of the subtarget.
409   ArrayRef<MCPhysReg> getAllSGPR128(const MachineFunction &MF) const;
410 
411   /// Return all SGPR64 which satisfy the waves per execution unit requirement
412   /// of the subtarget.
413   ArrayRef<MCPhysReg> getAllSGPR64(const MachineFunction &MF) const;
414 
415   /// Return all SGPR32 which satisfy the waves per execution unit requirement
416   /// of the subtarget.
417   ArrayRef<MCPhysReg> getAllSGPR32(const MachineFunction &MF) const;
418 
419   // Insert spill or restore instructions.
420   // When lowering spill pseudos, the RegScavenger should be set.
421   // For creating spill instructions during frame lowering, where no scavenger
422   // is available, LiveRegs can be used.
423   void buildSpillLoadStore(MachineBasicBlock &MBB,
424                            MachineBasicBlock::iterator MI, const DebugLoc &DL,
425                            unsigned LoadStoreOp, int Index, Register ValueReg,
426                            bool ValueIsKill, MCRegister ScratchOffsetReg,
427                            int64_t InstrOffset, MachineMemOperand *MMO,
428                            RegScavenger *RS,
429                            LivePhysRegs *LiveRegs = nullptr) const;
430 
431   // Return alignment in register file of first register in a register tuple.
432   unsigned getRegClassAlignmentNumBits(const TargetRegisterClass *RC) const {
433     return (RC->TSFlags & SIRCFlags::RegTupleAlignUnitsMask) * 32;
434   }
435 
436   // Check if register class RC has required alignment.
437   bool isRegClassAligned(const TargetRegisterClass *RC,
438                          unsigned AlignNumBits) const {
439     assert(AlignNumBits != 0);
440     unsigned RCAlign = getRegClassAlignmentNumBits(RC);
441     return RCAlign == AlignNumBits ||
442            (RCAlign > AlignNumBits && (RCAlign % AlignNumBits) == 0);
443   }
444 
445   // Return alignment of a SubReg relative to start of a register in RC class.
446   // No check if the subreg is supported by the current RC is made.
447   unsigned getSubRegAlignmentNumBits(const TargetRegisterClass *RC,
448                                      unsigned SubReg) const;
449 };
450 
451 } // End namespace llvm
452 
453 #endif
454