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
146   bool spillSGPR(MachineBasicBlock::iterator MI, int FI, RegScavenger *RS,
147                  SlotIndexes *Indexes = nullptr, LiveIntervals *LIS = nullptr,
148                  bool OnlyToVGPR = false) const;
149 
150   bool restoreSGPR(MachineBasicBlock::iterator MI, int FI, RegScavenger *RS,
151                    SlotIndexes *Indexes = nullptr, LiveIntervals *LIS = nullptr,
152                    bool OnlyToVGPR = false) const;
153 
154   bool spillEmergencySGPR(MachineBasicBlock::iterator MI,
155                           MachineBasicBlock &RestoreMBB, Register SGPR,
156                           RegScavenger *RS) const;
157 
158   bool supportsBackwardScavenger() const override {
159     return true;
160   }
161 
162   bool eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
163                            unsigned FIOperandNum,
164                            RegScavenger *RS) const override;
165 
166   bool eliminateSGPRToVGPRSpillFrameIndex(MachineBasicBlock::iterator MI,
167                                           int FI, RegScavenger *RS,
168                                           SlotIndexes *Indexes = nullptr,
169                                           LiveIntervals *LIS = nullptr) const;
170 
171   StringRef getRegAsmName(MCRegister Reg) const override;
172 
173   // Pseudo regs are not allowed
174   unsigned getHWRegIndex(MCRegister Reg) const {
175     return getEncodingValue(Reg) & 0xff;
176   }
177 
178   LLVM_READONLY
179   const TargetRegisterClass *getVGPRClassForBitWidth(unsigned BitWidth) const;
180 
181   LLVM_READONLY
182   const TargetRegisterClass *getAGPRClassForBitWidth(unsigned BitWidth) const;
183 
184   LLVM_READONLY
185   const TargetRegisterClass *
186   getVectorSuperClassForBitWidth(unsigned BitWidth) const;
187 
188   LLVM_READONLY
189   static const TargetRegisterClass *getSGPRClassForBitWidth(unsigned BitWidth);
190 
191   /// \returns true if this class contains only SGPR registers
192   static bool isSGPRClass(const TargetRegisterClass *RC) {
193     return hasSGPRs(RC) && !hasVGPRs(RC) && !hasAGPRs(RC);
194   }
195 
196   /// \returns true if this class ID contains only SGPR registers
197   bool isSGPRClassID(unsigned RCID) const {
198     return isSGPRClass(getRegClass(RCID));
199   }
200 
201   bool isSGPRReg(const MachineRegisterInfo &MRI, Register Reg) const;
202 
203   /// \returns true if this class contains only VGPR registers
204   static bool isVGPRClass(const TargetRegisterClass *RC) {
205     return hasVGPRs(RC) && !hasAGPRs(RC) && !hasSGPRs(RC);
206   }
207 
208   /// \returns true if this class contains only AGPR registers
209   static bool isAGPRClass(const TargetRegisterClass *RC) {
210     return hasAGPRs(RC) && !hasVGPRs(RC) && !hasSGPRs(RC);
211   }
212 
213   /// \returns true only if this class contains both VGPR and AGPR registers
214   bool isVectorSuperClass(const TargetRegisterClass *RC) const {
215     return hasVGPRs(RC) && hasAGPRs(RC) && !hasSGPRs(RC);
216   }
217 
218   /// \returns true only if this class contains both VGPR and SGPR registers
219   bool isVSSuperClass(const TargetRegisterClass *RC) const {
220     return hasVGPRs(RC) && hasSGPRs(RC) && !hasAGPRs(RC);
221   }
222 
223   /// \returns true if this class contains VGPR registers.
224   static bool hasVGPRs(const TargetRegisterClass *RC) {
225     return RC->TSFlags & SIRCFlags::HasVGPR;
226   }
227 
228   /// \returns true if this class contains AGPR registers.
229   static bool hasAGPRs(const TargetRegisterClass *RC) {
230     return RC->TSFlags & SIRCFlags::HasAGPR;
231   }
232 
233   /// \returns true if this class contains SGPR registers.
234   static bool hasSGPRs(const TargetRegisterClass *RC) {
235     return RC->TSFlags & SIRCFlags::HasSGPR;
236   }
237 
238   /// \returns true if this class contains any vector registers.
239   static bool hasVectorRegisters(const TargetRegisterClass *RC) {
240     return hasVGPRs(RC) || hasAGPRs(RC);
241   }
242 
243   /// \returns A VGPR reg class with the same width as \p SRC
244   const TargetRegisterClass *
245   getEquivalentVGPRClass(const TargetRegisterClass *SRC) const;
246 
247   /// \returns An AGPR reg class with the same width as \p SRC
248   const TargetRegisterClass *
249   getEquivalentAGPRClass(const TargetRegisterClass *SRC) const;
250 
251   /// \returns A SGPR reg class with the same width as \p SRC
252   const TargetRegisterClass *
253   getEquivalentSGPRClass(const TargetRegisterClass *VRC) const;
254 
255   /// Returns a register class which is compatible with \p SuperRC, such that a
256   /// subregister exists with class \p SubRC with subregister index \p
257   /// SubIdx. If this is impossible (e.g., an unaligned subregister index within
258   /// a register tuple), return null.
259   const TargetRegisterClass *
260   getCompatibleSubRegClass(const TargetRegisterClass *SuperRC,
261                            const TargetRegisterClass *SubRC,
262                            unsigned SubIdx) const;
263 
264   bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
265                             unsigned DefSubReg,
266                             const TargetRegisterClass *SrcRC,
267                             unsigned SrcSubReg) const override;
268 
269   /// \returns True if operands defined with this operand type can accept
270   /// a literal constant (i.e. any 32-bit immediate).
271   bool opCanUseLiteralConstant(unsigned OpType) const;
272 
273   /// \returns True if operands defined with this operand type can accept
274   /// an inline constant. i.e. An integer value in the range (-16, 64) or
275   /// -4.0f, -2.0f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 2.0f, 4.0f.
276   bool opCanUseInlineConstant(unsigned OpType) const;
277 
278   MCRegister findUnusedRegister(const MachineRegisterInfo &MRI,
279                                 const TargetRegisterClass *RC,
280                                 const MachineFunction &MF,
281                                 bool ReserveHighestVGPR = false) const;
282 
283   const TargetRegisterClass *getRegClassForReg(const MachineRegisterInfo &MRI,
284                                                Register Reg) const;
285   const TargetRegisterClass *
286   getRegClassForOperandReg(const MachineRegisterInfo &MRI,
287                            const MachineOperand &MO) const;
288 
289   bool isVGPR(const MachineRegisterInfo &MRI, Register Reg) const;
290   bool isAGPR(const MachineRegisterInfo &MRI, Register Reg) const;
291   bool isVectorRegister(const MachineRegisterInfo &MRI, Register Reg) const {
292     return isVGPR(MRI, Reg) || isAGPR(MRI, Reg);
293   }
294 
295   // FIXME: SGPRs are assumed to be uniform, but this is not true for i1 SGPRs
296   // (such as VCC) which hold a wave-wide vector of boolean values. Examining
297   // just the register class is not suffcient; it needs to be combined with a
298   // value type. The next predicate isUniformReg() does this correctly.
299   bool isDivergentRegClass(const TargetRegisterClass *RC) const override {
300     return !isSGPRClass(RC);
301   }
302 
303   bool isUniformReg(const MachineRegisterInfo &MRI, const RegisterBankInfo &RBI,
304                     Register Reg) const override;
305 
306   ArrayRef<int16_t> getRegSplitParts(const TargetRegisterClass *RC,
307                                      unsigned EltSize) const;
308 
309   bool shouldCoalesce(MachineInstr *MI,
310                       const TargetRegisterClass *SrcRC,
311                       unsigned SubReg,
312                       const TargetRegisterClass *DstRC,
313                       unsigned DstSubReg,
314                       const TargetRegisterClass *NewRC,
315                       LiveIntervals &LIS) const override;
316 
317   unsigned getRegPressureLimit(const TargetRegisterClass *RC,
318                                MachineFunction &MF) const override;
319 
320   unsigned getRegPressureSetLimit(const MachineFunction &MF,
321                                   unsigned Idx) const override;
322 
323   const int *getRegUnitPressureSets(unsigned RegUnit) const override;
324 
325   MCRegister getReturnAddressReg(const MachineFunction &MF) const;
326 
327   const TargetRegisterClass *
328   getRegClassForSizeOnBank(unsigned Size, const RegisterBank &Bank) const;
329 
330   const TargetRegisterClass *
331   getRegClassForTypeOnBank(LLT Ty, const RegisterBank &Bank) const {
332     return getRegClassForSizeOnBank(Ty.getSizeInBits(), Bank);
333   }
334 
335   const TargetRegisterClass *
336   getConstrainedRegClassForOperand(const MachineOperand &MO,
337                                  const MachineRegisterInfo &MRI) const override;
338 
339   const TargetRegisterClass *getBoolRC() const {
340     return isWave32 ? &AMDGPU::SReg_32RegClass
341                     : &AMDGPU::SReg_64RegClass;
342   }
343 
344   const TargetRegisterClass *getWaveMaskRegClass() const {
345     return isWave32 ? &AMDGPU::SReg_32_XM0_XEXECRegClass
346                     : &AMDGPU::SReg_64_XEXECRegClass;
347   }
348 
349   // Return the appropriate register class to use for 64-bit VGPRs for the
350   // subtarget.
351   const TargetRegisterClass *getVGPR64Class() const;
352 
353   MCRegister getVCC() const;
354 
355   MCRegister getExec() const;
356 
357   const TargetRegisterClass *getRegClass(unsigned RCID) const;
358 
359   // Find reaching register definition
360   MachineInstr *findReachingDef(Register Reg, unsigned SubReg,
361                                 MachineInstr &Use,
362                                 MachineRegisterInfo &MRI,
363                                 LiveIntervals *LIS) const;
364 
365   const uint32_t *getAllVGPRRegMask() const;
366   const uint32_t *getAllAGPRRegMask() const;
367   const uint32_t *getAllVectorRegMask() const;
368   const uint32_t *getAllAllocatableSRegMask() const;
369 
370   // \returns number of 32 bit registers covered by a \p LM
371   static unsigned getNumCoveredRegs(LaneBitmask LM) {
372     // The assumption is that every lo16 subreg is an even bit and every hi16
373     // is an adjacent odd bit or vice versa.
374     uint64_t Mask = LM.getAsInteger();
375     uint64_t Even = Mask & 0xAAAAAAAAAAAAAAAAULL;
376     Mask = (Even >> 1) | Mask;
377     uint64_t Odd = Mask & 0x5555555555555555ULL;
378     return llvm::popcount(Odd);
379   }
380 
381   // \returns a DWORD offset of a \p SubReg
382   unsigned getChannelFromSubReg(unsigned SubReg) const {
383     return SubReg ? (getSubRegIdxOffset(SubReg) + 31) / 32 : 0;
384   }
385 
386   // \returns a DWORD size of a \p SubReg
387   unsigned getNumChannelsFromSubReg(unsigned SubReg) const {
388     return getNumCoveredRegs(getSubRegIndexLaneMask(SubReg));
389   }
390 
391   // For a given 16 bit \p Reg \returns a 32 bit register holding it.
392   // \returns \p Reg otherwise.
393   MCPhysReg get32BitRegister(MCPhysReg Reg) const;
394 
395   // Returns true if a given register class is properly aligned for
396   // the subtarget.
397   bool isProperlyAlignedRC(const TargetRegisterClass &RC) const;
398 
399   // Given \p RC returns corresponding aligned register class if required
400   // by the subtarget.
401   const TargetRegisterClass *
402   getProperlyAlignedRC(const TargetRegisterClass *RC) const;
403 
404   /// Return all SGPR128 which satisfy the waves per execution unit requirement
405   /// of the subtarget.
406   ArrayRef<MCPhysReg> getAllSGPR128(const MachineFunction &MF) const;
407 
408   /// Return all SGPR64 which satisfy the waves per execution unit requirement
409   /// of the subtarget.
410   ArrayRef<MCPhysReg> getAllSGPR64(const MachineFunction &MF) const;
411 
412   /// Return all SGPR32 which satisfy the waves per execution unit requirement
413   /// of the subtarget.
414   ArrayRef<MCPhysReg> getAllSGPR32(const MachineFunction &MF) const;
415 
416   // Insert spill or restore instructions.
417   // When lowering spill pseudos, the RegScavenger should be set.
418   // For creating spill instructions during frame lowering, where no scavenger
419   // is available, LiveRegs can be used.
420   void buildSpillLoadStore(MachineBasicBlock &MBB,
421                            MachineBasicBlock::iterator MI, const DebugLoc &DL,
422                            unsigned LoadStoreOp, int Index, Register ValueReg,
423                            bool ValueIsKill, MCRegister ScratchOffsetReg,
424                            int64_t InstrOffset, MachineMemOperand *MMO,
425                            RegScavenger *RS,
426                            LivePhysRegs *LiveRegs = nullptr) const;
427 
428   // Return alignment in register file of first register in a register tuple.
429   unsigned getRegClassAlignmentNumBits(const TargetRegisterClass *RC) const {
430     return (RC->TSFlags & SIRCFlags::RegTupleAlignUnitsMask) * 32;
431   }
432 
433   // Check if register class RC has required alignment.
434   bool isRegClassAligned(const TargetRegisterClass *RC,
435                          unsigned AlignNumBits) const {
436     assert(AlignNumBits != 0);
437     unsigned RCAlign = getRegClassAlignmentNumBits(RC);
438     return RCAlign == AlignNumBits ||
439            (RCAlign > AlignNumBits && (RCAlign % AlignNumBits) == 0);
440   }
441 
442   // Return alignment of a SubReg relative to start of a register in RC class.
443   // No check if the subreg is supported by the current RC is made.
444   unsigned getSubRegAlignmentNumBits(const TargetRegisterClass *RC,
445                                      unsigned SubReg) const;
446 };
447 
448 } // End namespace llvm
449 
450 #endif
451