• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- SIRegisterInfo.h - SI Register Info Interface ----------*- C++ -*--===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 /// \file
11 /// Interface definition for SIRegisterInfo
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_LIB_TARGET_AMDGPU_SIREGISTERINFO_H
16 #define LLVM_LIB_TARGET_AMDGPU_SIREGISTERINFO_H
17 
18 #include "AMDGPURegisterInfo.h"
19 #include "SIDefines.h"
20 #include "llvm/CodeGen/MachineRegisterInfo.h"
21 
22 namespace llvm {
23 
24 class GCNSubtarget;
25 class LiveIntervals;
26 class MachineRegisterInfo;
27 class SIMachineFunctionInfo;
28 
29 class SIRegisterInfo final : public AMDGPURegisterInfo {
30 private:
31   unsigned SGPRSetID;
32   unsigned VGPRSetID;
33   BitVector SGPRPressureSets;
34   BitVector VGPRPressureSets;
35   bool SpillSGPRToVGPR;
36   bool SpillSGPRToSMEM;
37 
38   void classifyPressureSet(unsigned PSetID, unsigned Reg,
39                            BitVector &PressureSets) const;
40 public:
41   SIRegisterInfo(const GCNSubtarget &ST);
42 
spillSGPRToVGPR()43   bool spillSGPRToVGPR() const {
44     return SpillSGPRToVGPR;
45   }
46 
spillSGPRToSMEM()47   bool spillSGPRToSMEM() const {
48     return SpillSGPRToSMEM;
49   }
50 
51   /// Return the end register initially reserved for the scratch buffer in case
52   /// spilling is needed.
53   unsigned reservedPrivateSegmentBufferReg(const MachineFunction &MF) const;
54 
55   /// Return the end register initially reserved for the scratch wave offset in
56   /// case spilling is needed.
57   unsigned reservedPrivateSegmentWaveByteOffsetReg(
58     const MachineFunction &MF) const;
59 
60   unsigned reservedStackPtrOffsetReg(const MachineFunction &MF) const;
61 
62   BitVector getReservedRegs(const MachineFunction &MF) const override;
63 
64   const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
65   const MCPhysReg *getCalleeSavedRegsViaCopy(const MachineFunction *MF) const;
66   const uint32_t *getCallPreservedMask(const MachineFunction &MF,
67                                        CallingConv::ID) const override;
68 
69   // Stack access is very expensive. CSRs are also the high registers, and we
70   // want to minimize the number of used registers.
getCSRFirstUseCost()71   unsigned getCSRFirstUseCost() const override {
72     return 100;
73   }
74 
75   unsigned getFrameRegister(const MachineFunction &MF) const override;
76 
77   bool requiresRegisterScavenging(const MachineFunction &Fn) const override;
78 
79   bool requiresFrameIndexScavenging(const MachineFunction &MF) const override;
80   bool requiresFrameIndexReplacementScavenging(
81     const MachineFunction &MF) const override;
82   bool requiresVirtualBaseRegisters(const MachineFunction &Fn) const override;
83   bool trackLivenessAfterRegAlloc(const MachineFunction &MF) const override;
84 
85   int64_t getMUBUFInstrOffset(const MachineInstr *MI) const;
86 
87   int64_t getFrameIndexInstrOffset(const MachineInstr *MI,
88                                    int Idx) const override;
89 
90   bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override;
91 
92   void materializeFrameBaseRegister(MachineBasicBlock *MBB,
93                                     unsigned BaseReg, int FrameIdx,
94                                     int64_t Offset) const override;
95 
96   void resolveFrameIndex(MachineInstr &MI, unsigned BaseReg,
97                          int64_t Offset) const override;
98 
99   bool isFrameOffsetLegal(const MachineInstr *MI, unsigned BaseReg,
100                           int64_t Offset) const override;
101 
102   const TargetRegisterClass *getPointerRegClass(
103     const MachineFunction &MF, unsigned Kind = 0) const override;
104 
105   /// If \p OnlyToVGPR is true, this will only succeed if this
106   bool spillSGPR(MachineBasicBlock::iterator MI,
107                  int FI, RegScavenger *RS,
108                  bool OnlyToVGPR = false) const;
109 
110   bool restoreSGPR(MachineBasicBlock::iterator MI,
111                    int FI, RegScavenger *RS,
112                    bool OnlyToVGPR = false) const;
113 
114   void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
115                            unsigned FIOperandNum,
116                            RegScavenger *RS) const override;
117 
118   bool eliminateSGPRToVGPRSpillFrameIndex(MachineBasicBlock::iterator MI,
119                                           int FI, RegScavenger *RS) const;
120 
121   StringRef getRegAsmName(unsigned Reg) const override;
122 
getHWRegIndex(unsigned Reg)123   unsigned getHWRegIndex(unsigned Reg) const {
124     return getEncodingValue(Reg) & 0xff;
125   }
126 
127   /// Return the 'base' register class for this register.
128   /// e.g. SGPR0 => SReg_32, VGPR => VGPR_32 SGPR0_SGPR1 -> SReg_32, etc.
129   const TargetRegisterClass *getPhysRegClass(unsigned Reg) const;
130 
131   /// \returns true if this class contains only SGPR registers
isSGPRClass(const TargetRegisterClass * RC)132   bool isSGPRClass(const TargetRegisterClass *RC) const {
133     return !hasVGPRs(RC);
134   }
135 
136   /// \returns true if this class ID contains only SGPR registers
isSGPRClassID(unsigned RCID)137   bool isSGPRClassID(unsigned RCID) const {
138     return isSGPRClass(getRegClass(RCID));
139   }
140 
isSGPRReg(const MachineRegisterInfo & MRI,unsigned Reg)141   bool isSGPRReg(const MachineRegisterInfo &MRI, unsigned Reg) const {
142     const TargetRegisterClass *RC;
143     if (TargetRegisterInfo::isVirtualRegister(Reg))
144       RC = MRI.getRegClass(Reg);
145     else
146       RC = getPhysRegClass(Reg);
147     return isSGPRClass(RC);
148   }
149 
150   /// \returns true if this class contains VGPR registers.
151   bool hasVGPRs(const TargetRegisterClass *RC) const;
152 
153   /// \returns A VGPR reg class with the same width as \p SRC
154   const TargetRegisterClass *getEquivalentVGPRClass(
155                                           const TargetRegisterClass *SRC) const;
156 
157   /// \returns A SGPR reg class with the same width as \p SRC
158   const TargetRegisterClass *getEquivalentSGPRClass(
159                                            const TargetRegisterClass *VRC) const;
160 
161   /// \returns The register class that is used for a sub-register of \p RC for
162   /// the given \p SubIdx.  If \p SubIdx equals NoSubRegister, \p RC will
163   /// be returned.
164   const TargetRegisterClass *getSubRegClass(const TargetRegisterClass *RC,
165                                             unsigned SubIdx) const;
166 
167   bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
168                             unsigned DefSubReg,
169                             const TargetRegisterClass *SrcRC,
170                             unsigned SrcSubReg) const override;
171 
172   /// \returns True if operands defined with this operand type can accept
173   /// a literal constant (i.e. any 32-bit immediate).
opCanUseLiteralConstant(unsigned OpType)174   bool opCanUseLiteralConstant(unsigned OpType) const {
175     // TODO: 64-bit operands have extending behavior from 32-bit literal.
176     return OpType >= AMDGPU::OPERAND_REG_IMM_FIRST &&
177            OpType <= AMDGPU::OPERAND_REG_IMM_LAST;
178   }
179 
180   /// \returns True if operands defined with this operand type can accept
181   /// an inline constant. i.e. An integer value in the range (-16, 64) or
182   /// -4.0f, -2.0f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 2.0f, 4.0f.
opCanUseInlineConstant(unsigned OpType)183   bool opCanUseInlineConstant(unsigned OpType) const {
184     return OpType >= AMDGPU::OPERAND_SRC_FIRST &&
185            OpType <= AMDGPU::OPERAND_SRC_LAST;
186   }
187 
188   unsigned findUnusedRegister(const MachineRegisterInfo &MRI,
189                               const TargetRegisterClass *RC,
190                               const MachineFunction &MF) const;
191 
getSGPRPressureSet()192   unsigned getSGPRPressureSet() const { return SGPRSetID; };
getVGPRPressureSet()193   unsigned getVGPRPressureSet() const { return VGPRSetID; };
194 
195   const TargetRegisterClass *getRegClassForReg(const MachineRegisterInfo &MRI,
196                                                unsigned Reg) const;
197   bool isVGPR(const MachineRegisterInfo &MRI, unsigned Reg) const;
198 
isSGPRPressureSet(unsigned SetID)199   bool isSGPRPressureSet(unsigned SetID) const {
200     return SGPRPressureSets.test(SetID) && !VGPRPressureSets.test(SetID);
201   }
isVGPRPressureSet(unsigned SetID)202   bool isVGPRPressureSet(unsigned SetID) const {
203     return VGPRPressureSets.test(SetID) && !SGPRPressureSets.test(SetID);
204   }
205 
206   ArrayRef<int16_t> getRegSplitParts(const TargetRegisterClass *RC,
207                                      unsigned EltSize) const;
208 
209   bool shouldCoalesce(MachineInstr *MI,
210                       const TargetRegisterClass *SrcRC,
211                       unsigned SubReg,
212                       const TargetRegisterClass *DstRC,
213                       unsigned DstSubReg,
214                       const TargetRegisterClass *NewRC,
215                       LiveIntervals &LIS) const override;
216 
217   unsigned getRegPressureLimit(const TargetRegisterClass *RC,
218                                MachineFunction &MF) const override;
219 
220   unsigned getRegPressureSetLimit(const MachineFunction &MF,
221                                   unsigned Idx) const override;
222 
223   const int *getRegUnitPressureSets(unsigned RegUnit) const override;
224 
225   unsigned getReturnAddressReg(const MachineFunction &MF) const;
226 
227   const TargetRegisterClass *
228   getConstrainedRegClassForOperand(const MachineOperand &MO,
229                                  const MachineRegisterInfo &MRI) const override;
230 
231 private:
232   void buildSpillLoadStore(MachineBasicBlock::iterator MI,
233                            unsigned LoadStoreOp,
234                            int Index,
235                            unsigned ValueReg,
236                            bool ValueIsKill,
237                            unsigned ScratchRsrcReg,
238                            unsigned ScratchOffsetReg,
239                            int64_t InstrOffset,
240                            MachineMemOperand *MMO,
241                            RegScavenger *RS) const;
242 };
243 
244 } // End namespace llvm
245 
246 #endif
247