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