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