]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/lib/Target/AMDGPU/SIRegisterInfo.h
Merge r357864 from the clang1000-import branch:
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / lib / Target / AMDGPU / SIRegisterInfo.h
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 #include "AMDGPURegisterInfo.h"
18 #include "SIDefines.h"
19 #include "llvm/CodeGen/MachineRegisterInfo.h"
20
21 namespace llvm {
22
23 class GCNSubtarget;
24 class LiveIntervals;
25 class MachineRegisterInfo;
26 class SIMachineFunctionInfo;
27
28 class SIRegisterInfo final : public AMDGPURegisterInfo {
29 private:
30   unsigned SGPRSetID;
31   unsigned VGPRSetID;
32   unsigned AGPRSetID;
33   BitVector SGPRPressureSets;
34   BitVector VGPRPressureSets;
35   BitVector AGPRPressureSets;
36   bool SpillSGPRToVGPR;
37   bool SpillSGPRToSMEM;
38   bool isWave32;
39
40   void classifyPressureSet(unsigned PSetID, unsigned Reg,
41                            BitVector &PressureSets) const;
42 public:
43   SIRegisterInfo(const GCNSubtarget &ST);
44
45   bool spillSGPRToVGPR() const {
46     return SpillSGPRToVGPR;
47   }
48
49   bool spillSGPRToSMEM() const {
50     return SpillSGPRToSMEM;
51   }
52
53   /// Return the end register initially reserved for the scratch buffer in case
54   /// spilling is needed.
55   unsigned reservedPrivateSegmentBufferReg(const MachineFunction &MF) const;
56
57   /// Return the end register initially reserved for the scratch wave offset in
58   /// case spilling is needed.
59   unsigned reservedPrivateSegmentWaveByteOffsetReg(
60     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.
71   unsigned getCSRFirstUseCost() const override {
72     return 100;
73   }
74
75   Register getFrameRegister(const MachineFunction &MF) const override;
76
77   bool canRealignStack(const MachineFunction &MF) const override;
78   bool requiresRegisterScavenging(const MachineFunction &Fn) const override;
79
80   bool requiresFrameIndexScavenging(const MachineFunction &MF) const override;
81   bool requiresFrameIndexReplacementScavenging(
82     const MachineFunction &MF) const override;
83   bool requiresVirtualBaseRegisters(const MachineFunction &Fn) const override;
84   bool trackLivenessAfterRegAlloc(const MachineFunction &MF) const override;
85
86   int64_t getMUBUFInstrOffset(const MachineInstr *MI) const;
87
88   int64_t getFrameIndexInstrOffset(const MachineInstr *MI,
89                                    int Idx) const override;
90
91   bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override;
92
93   void materializeFrameBaseRegister(MachineBasicBlock *MBB,
94                                     unsigned BaseReg, int FrameIdx,
95                                     int64_t Offset) const override;
96
97   void resolveFrameIndex(MachineInstr &MI, unsigned BaseReg,
98                          int64_t Offset) const override;
99
100   bool isFrameOffsetLegal(const MachineInstr *MI, unsigned BaseReg,
101                           int64_t Offset) const override;
102
103   const TargetRegisterClass *getPointerRegClass(
104     const MachineFunction &MF, unsigned Kind = 0) const override;
105
106   /// If \p OnlyToVGPR is true, this will only succeed if this
107   bool spillSGPR(MachineBasicBlock::iterator MI,
108                  int FI, RegScavenger *RS,
109                  bool OnlyToVGPR = false) const;
110
111   bool restoreSGPR(MachineBasicBlock::iterator MI,
112                    int FI, RegScavenger *RS,
113                    bool OnlyToVGPR = false) const;
114
115   void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj,
116                            unsigned FIOperandNum,
117                            RegScavenger *RS) const override;
118
119   bool eliminateSGPRToVGPRSpillFrameIndex(MachineBasicBlock::iterator MI,
120                                           int FI, RegScavenger *RS) const;
121
122   StringRef getRegAsmName(unsigned Reg) const override;
123
124   unsigned getHWRegIndex(unsigned Reg) const {
125     return getEncodingValue(Reg) & 0xff;
126   }
127
128   /// Return the 'base' register class for this register.
129   /// e.g. SGPR0 => SReg_32, VGPR => VGPR_32 SGPR0_SGPR1 -> SReg_32, etc.
130   const TargetRegisterClass *getPhysRegClass(unsigned Reg) const;
131
132   /// \returns true if this class contains only SGPR registers
133   bool isSGPRClass(const TargetRegisterClass *RC) const {
134     return !hasVGPRs(RC) && !hasAGPRs(RC);
135   }
136
137   /// \returns true if this class ID contains only SGPR registers
138   bool isSGPRClassID(unsigned RCID) const {
139     return isSGPRClass(getRegClass(RCID));
140   }
141
142   bool isSGPRReg(const MachineRegisterInfo &MRI, unsigned Reg) const {
143     const TargetRegisterClass *RC;
144     if (TargetRegisterInfo::isVirtualRegister(Reg))
145       RC = MRI.getRegClass(Reg);
146     else
147       RC = getPhysRegClass(Reg);
148     return isSGPRClass(RC);
149   }
150
151   /// \returns true if this class contains VGPR registers.
152   bool hasVGPRs(const TargetRegisterClass *RC) const;
153
154   /// \returns true if this class contains AGPR registers.
155   bool hasAGPRs(const TargetRegisterClass *RC) const;
156
157   /// \returns true if this class contains any vector registers.
158   bool hasVectorRegisters(const TargetRegisterClass *RC) const {
159     return hasVGPRs(RC) || hasAGPRs(RC);
160   }
161
162   /// \returns A VGPR reg class with the same width as \p SRC
163   const TargetRegisterClass *getEquivalentVGPRClass(
164                                           const TargetRegisterClass *SRC) const;
165
166   /// \returns An AGPR reg class with the same width as \p SRC
167   const TargetRegisterClass *getEquivalentAGPRClass(
168                                           const TargetRegisterClass *SRC) const;
169
170   /// \returns A SGPR reg class with the same width as \p SRC
171   const TargetRegisterClass *getEquivalentSGPRClass(
172                                            const TargetRegisterClass *VRC) const;
173
174   /// \returns The register class that is used for a sub-register of \p RC for
175   /// the given \p SubIdx.  If \p SubIdx equals NoSubRegister, \p RC will
176   /// be returned.
177   const TargetRegisterClass *getSubRegClass(const TargetRegisterClass *RC,
178                                             unsigned SubIdx) const;
179
180   bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC,
181                             unsigned DefSubReg,
182                             const TargetRegisterClass *SrcRC,
183                             unsigned SrcSubReg) const override;
184
185   /// \returns True if operands defined with this operand type can accept
186   /// a literal constant (i.e. any 32-bit immediate).
187   bool opCanUseLiteralConstant(unsigned OpType) const {
188     // TODO: 64-bit operands have extending behavior from 32-bit literal.
189     return OpType >= AMDGPU::OPERAND_REG_IMM_FIRST &&
190            OpType <= AMDGPU::OPERAND_REG_IMM_LAST;
191   }
192
193   /// \returns True if operands defined with this operand type can accept
194   /// an inline constant. i.e. An integer value in the range (-16, 64) or
195   /// -4.0f, -2.0f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 2.0f, 4.0f.
196   bool opCanUseInlineConstant(unsigned OpType) const {
197     return OpType >= AMDGPU::OPERAND_SRC_FIRST &&
198            OpType <= AMDGPU::OPERAND_SRC_LAST;
199   }
200
201   unsigned findUnusedRegister(const MachineRegisterInfo &MRI,
202                               const TargetRegisterClass *RC,
203                               const MachineFunction &MF) const;
204
205   unsigned getSGPRPressureSet() const { return SGPRSetID; };
206   unsigned getVGPRPressureSet() const { return VGPRSetID; };
207   unsigned getAGPRPressureSet() const { return AGPRSetID; };
208
209   const TargetRegisterClass *getRegClassForReg(const MachineRegisterInfo &MRI,
210                                                unsigned Reg) const;
211   bool isVGPR(const MachineRegisterInfo &MRI, unsigned Reg) const;
212   bool isAGPR(const MachineRegisterInfo &MRI, unsigned Reg) const;
213   bool isVectorRegister(const MachineRegisterInfo &MRI, unsigned Reg) const {
214     return isVGPR(MRI, Reg) || isAGPR(MRI, Reg);
215   }
216
217   virtual bool
218   isDivergentRegClass(const TargetRegisterClass *RC) const override {
219     return !isSGPRClass(RC);
220   }
221
222   bool isSGPRPressureSet(unsigned SetID) const {
223     return SGPRPressureSets.test(SetID) && !VGPRPressureSets.test(SetID) &&
224            !AGPRPressureSets.test(SetID);
225   }
226   bool isVGPRPressureSet(unsigned SetID) const {
227     return VGPRPressureSets.test(SetID) && !SGPRPressureSets.test(SetID) &&
228            !AGPRPressureSets.test(SetID);
229   }
230   bool isAGPRPressureSet(unsigned SetID) const {
231     return AGPRPressureSets.test(SetID) && !SGPRPressureSets.test(SetID) &&
232            !VGPRPressureSets.test(SetID);
233   }
234
235   ArrayRef<int16_t> getRegSplitParts(const TargetRegisterClass *RC,
236                                      unsigned EltSize) const;
237
238   bool shouldCoalesce(MachineInstr *MI,
239                       const TargetRegisterClass *SrcRC,
240                       unsigned SubReg,
241                       const TargetRegisterClass *DstRC,
242                       unsigned DstSubReg,
243                       const TargetRegisterClass *NewRC,
244                       LiveIntervals &LIS) const override;
245
246   unsigned getRegPressureLimit(const TargetRegisterClass *RC,
247                                MachineFunction &MF) const override;
248
249   unsigned getRegPressureSetLimit(const MachineFunction &MF,
250                                   unsigned Idx) const override;
251
252   const int *getRegUnitPressureSets(unsigned RegUnit) const override;
253
254   unsigned getReturnAddressReg(const MachineFunction &MF) const;
255
256   const TargetRegisterClass *
257   getRegClassForSizeOnBank(unsigned Size,
258                            const RegisterBank &Bank,
259                            const MachineRegisterInfo &MRI) const;
260
261   const TargetRegisterClass *
262   getRegClassForTypeOnBank(LLT Ty,
263                            const RegisterBank &Bank,
264                            const MachineRegisterInfo &MRI) const {
265     return getRegClassForSizeOnBank(Ty.getSizeInBits(), Bank, MRI);
266   }
267
268   const TargetRegisterClass *
269   getConstrainedRegClassForOperand(const MachineOperand &MO,
270                                  const MachineRegisterInfo &MRI) const override;
271
272   const TargetRegisterClass *getBoolRC() const {
273     return isWave32 ? &AMDGPU::SReg_32_XM0RegClass
274                     : &AMDGPU::SReg_64RegClass;
275   }
276
277   const TargetRegisterClass *getWaveMaskRegClass() const {
278     return isWave32 ? &AMDGPU::SReg_32_XM0_XEXECRegClass
279                     : &AMDGPU::SReg_64_XEXECRegClass;
280   }
281
282   unsigned getVCC() const;
283
284   const TargetRegisterClass *getRegClass(unsigned RCID) const;
285
286   // Find reaching register definition
287   MachineInstr *findReachingDef(unsigned Reg, unsigned SubReg,
288                                 MachineInstr &Use,
289                                 MachineRegisterInfo &MRI,
290                                 LiveIntervals *LIS) const;
291
292   const uint32_t *getAllVGPRRegMask() const;
293   const uint32_t *getAllAllocatableSRegMask() const;
294
295 private:
296   void buildSpillLoadStore(MachineBasicBlock::iterator MI,
297                            unsigned LoadStoreOp,
298                            int Index,
299                            unsigned ValueReg,
300                            bool ValueIsKill,
301                            unsigned ScratchRsrcReg,
302                            unsigned ScratchOffsetReg,
303                            int64_t InstrOffset,
304                            MachineMemOperand *MMO,
305                            RegScavenger *RS) const;
306 };
307
308 } // End namespace llvm
309
310 #endif