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 spillSGPRToVGPR()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. getCSRFirstUseCost()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 getHWRegIndex(unsigned Reg)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 isSGPRClass(const TargetRegisterClass * RC)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 isSGPRClassID(unsigned RCID)134 bool isSGPRClassID(unsigned RCID) const { 135 return isSGPRClass(getRegClass(RCID)); 136 } 137 isSGPRReg(const MachineRegisterInfo & MRI,unsigned Reg)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 only AGPR registers isAGPRClass(const TargetRegisterClass * RC)148 bool isAGPRClass(const TargetRegisterClass *RC) const { 149 return hasAGPRs(RC) && !hasVGPRs(RC); 150 } 151 152 /// \returns true if this class contains VGPR registers. 153 bool hasVGPRs(const TargetRegisterClass *RC) const; 154 155 /// \returns true if this class contains AGPR registers. 156 bool hasAGPRs(const TargetRegisterClass *RC) const; 157 158 /// \returns true if this class contains any vector registers. hasVectorRegisters(const TargetRegisterClass * RC)159 bool hasVectorRegisters(const TargetRegisterClass *RC) const { 160 return hasVGPRs(RC) || hasAGPRs(RC); 161 } 162 163 /// \returns A VGPR reg class with the same width as \p SRC 164 const TargetRegisterClass *getEquivalentVGPRClass( 165 const TargetRegisterClass *SRC) const; 166 167 /// \returns An AGPR reg class with the same width as \p SRC 168 const TargetRegisterClass *getEquivalentAGPRClass( 169 const TargetRegisterClass *SRC) const; 170 171 /// \returns A SGPR reg class with the same width as \p SRC 172 const TargetRegisterClass *getEquivalentSGPRClass( 173 const TargetRegisterClass *VRC) const; 174 175 /// \returns The register class that is used for a sub-register of \p RC for 176 /// the given \p SubIdx. If \p SubIdx equals NoSubRegister, \p RC will 177 /// be returned. 178 const TargetRegisterClass *getSubRegClass(const TargetRegisterClass *RC, 179 unsigned SubIdx) const; 180 181 bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC, 182 unsigned DefSubReg, 183 const TargetRegisterClass *SrcRC, 184 unsigned SrcSubReg) const override; 185 186 /// \returns True if operands defined with this operand type can accept 187 /// a literal constant (i.e. any 32-bit immediate). opCanUseLiteralConstant(unsigned OpType)188 bool opCanUseLiteralConstant(unsigned OpType) const { 189 // TODO: 64-bit operands have extending behavior from 32-bit literal. 190 return OpType >= AMDGPU::OPERAND_REG_IMM_FIRST && 191 OpType <= AMDGPU::OPERAND_REG_IMM_LAST; 192 } 193 194 /// \returns True if operands defined with this operand type can accept 195 /// an inline constant. i.e. An integer value in the range (-16, 64) or 196 /// -4.0f, -2.0f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 2.0f, 4.0f. 197 bool opCanUseInlineConstant(unsigned OpType) const; 198 199 unsigned findUnusedRegister(const MachineRegisterInfo &MRI, 200 const TargetRegisterClass *RC, 201 const MachineFunction &MF) const; 202 getSGPRPressureSet()203 unsigned getSGPRPressureSet() const { return SGPRSetID; }; getVGPRPressureSet()204 unsigned getVGPRPressureSet() const { return VGPRSetID; }; getAGPRPressureSet()205 unsigned getAGPRPressureSet() const { return AGPRSetID; }; 206 207 const TargetRegisterClass *getRegClassForReg(const MachineRegisterInfo &MRI, 208 unsigned Reg) const; 209 bool isVGPR(const MachineRegisterInfo &MRI, unsigned Reg) const; 210 bool isAGPR(const MachineRegisterInfo &MRI, unsigned Reg) const; isVectorRegister(const MachineRegisterInfo & MRI,unsigned Reg)211 bool isVectorRegister(const MachineRegisterInfo &MRI, unsigned Reg) const { 212 return isVGPR(MRI, Reg) || isAGPR(MRI, Reg); 213 } 214 215 virtual bool isDivergentRegClass(const TargetRegisterClass * RC)216 isDivergentRegClass(const TargetRegisterClass *RC) const override { 217 return !isSGPRClass(RC); 218 } 219 isSGPRPressureSet(unsigned SetID)220 bool isSGPRPressureSet(unsigned SetID) const { 221 return SGPRPressureSets.test(SetID) && !VGPRPressureSets.test(SetID) && 222 !AGPRPressureSets.test(SetID); 223 } isVGPRPressureSet(unsigned SetID)224 bool isVGPRPressureSet(unsigned SetID) const { 225 return VGPRPressureSets.test(SetID) && !SGPRPressureSets.test(SetID) && 226 !AGPRPressureSets.test(SetID); 227 } isAGPRPressureSet(unsigned SetID)228 bool isAGPRPressureSet(unsigned SetID) const { 229 return AGPRPressureSets.test(SetID) && !SGPRPressureSets.test(SetID) && 230 !VGPRPressureSets.test(SetID); 231 } 232 233 ArrayRef<int16_t> getRegSplitParts(const TargetRegisterClass *RC, 234 unsigned EltSize) const; 235 236 bool shouldCoalesce(MachineInstr *MI, 237 const TargetRegisterClass *SrcRC, 238 unsigned SubReg, 239 const TargetRegisterClass *DstRC, 240 unsigned DstSubReg, 241 const TargetRegisterClass *NewRC, 242 LiveIntervals &LIS) const override; 243 244 unsigned getRegPressureLimit(const TargetRegisterClass *RC, 245 MachineFunction &MF) const override; 246 247 unsigned getRegPressureSetLimit(const MachineFunction &MF, 248 unsigned Idx) const override; 249 250 const int *getRegUnitPressureSets(unsigned RegUnit) const override; 251 252 unsigned getReturnAddressReg(const MachineFunction &MF) const; 253 254 const TargetRegisterClass * 255 getRegClassForSizeOnBank(unsigned Size, 256 const RegisterBank &Bank, 257 const MachineRegisterInfo &MRI) const; 258 259 const TargetRegisterClass * getRegClassForTypeOnBank(LLT Ty,const RegisterBank & Bank,const MachineRegisterInfo & MRI)260 getRegClassForTypeOnBank(LLT Ty, 261 const RegisterBank &Bank, 262 const MachineRegisterInfo &MRI) const { 263 return getRegClassForSizeOnBank(Ty.getSizeInBits(), Bank, MRI); 264 } 265 266 const TargetRegisterClass * 267 getConstrainedRegClassForOperand(const MachineOperand &MO, 268 const MachineRegisterInfo &MRI) const override; 269 getBoolRC()270 const TargetRegisterClass *getBoolRC() const { 271 return isWave32 ? &AMDGPU::SReg_32RegClass 272 : &AMDGPU::SReg_64RegClass; 273 } 274 getWaveMaskRegClass()275 const TargetRegisterClass *getWaveMaskRegClass() const { 276 return isWave32 ? &AMDGPU::SReg_32_XM0_XEXECRegClass 277 : &AMDGPU::SReg_64_XEXECRegClass; 278 } 279 280 unsigned getVCC() const; 281 282 const TargetRegisterClass *getRegClass(unsigned RCID) const; 283 284 // Find reaching register definition 285 MachineInstr *findReachingDef(unsigned Reg, unsigned SubReg, 286 MachineInstr &Use, 287 MachineRegisterInfo &MRI, 288 LiveIntervals *LIS) const; 289 290 const uint32_t *getAllVGPRRegMask() const; 291 const uint32_t *getAllAllocatableSRegMask() const; 292 293 private: 294 void buildSpillLoadStore(MachineBasicBlock::iterator MI, 295 unsigned LoadStoreOp, 296 int Index, 297 unsigned ValueReg, 298 bool ValueIsKill, 299 unsigned ScratchRsrcReg, 300 unsigned ScratchOffsetReg, 301 int64_t InstrOffset, 302 MachineMemOperand *MMO, 303 RegScavenger *RS) const; 304 }; 305 306 } // End namespace llvm 307 308 #endif 309