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