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 #define GET_REGINFO_HEADER 18 #include "AMDGPUGenRegisterInfo.inc" 19 20 #include "SIDefines.h" 21 #include "llvm/CodeGen/MachineRegisterInfo.h" 22 23 namespace llvm { 24 25 class GCNSubtarget; 26 class LiveIntervals; 27 class SIMachineFunctionInfo; 28 29 class SIRegisterInfo final : public AMDGPUGenRegisterInfo { 30 private: 31 const GCNSubtarget &ST; 32 bool SpillSGPRToVGPR; 33 bool isWave32; 34 BitVector RegPressureIgnoredUnits; 35 36 /// Sub reg indexes for getRegSplitParts. 37 /// First index represents subreg size from 1 to 16 DWORDs. 38 /// The inner vector is sorted by bit offset. 39 /// Provided a register can be fully split with given subregs, 40 /// all elements of the inner vector combined give a full lane mask. 41 static std::array<std::vector<int16_t>, 16> RegSplitParts; 42 43 void reserveRegisterTuples(BitVector &, MCRegister Reg) const; 44 45 public: 46 SIRegisterInfo(const GCNSubtarget &ST); 47 48 /// \returns the sub reg enum value for the given \p Channel 49 /// (e.g. getSubRegFromChannel(0) -> AMDGPU::sub0) 50 static unsigned getSubRegFromChannel(unsigned Channel, unsigned NumRegs = 1); 51 52 bool spillSGPRToVGPR() const { 53 return SpillSGPRToVGPR; 54 } 55 56 /// Return the end register initially reserved for the scratch buffer in case 57 /// spilling is needed. 58 MCRegister reservedPrivateSegmentBufferReg(const MachineFunction &MF) const; 59 60 BitVector getReservedRegs(const MachineFunction &MF) const override; 61 62 const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override; 63 const MCPhysReg *getCalleeSavedRegsViaCopy(const MachineFunction *MF) const; 64 const uint32_t *getCallPreservedMask(const MachineFunction &MF, 65 CallingConv::ID) const override; 66 67 // Stack access is very expensive. CSRs are also the high registers, and we 68 // want to minimize the number of used registers. 69 unsigned getCSRFirstUseCost() const override { 70 return 100; 71 } 72 73 Register getFrameRegister(const MachineFunction &MF) const override; 74 75 bool hasBasePointer(const MachineFunction &MF) const; 76 Register getBaseRegister() const; 77 78 bool canRealignStack(const MachineFunction &MF) const override; 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 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, Register BaseReg, 94 int FrameIdx, 95 int64_t Offset) const override; 96 97 void resolveFrameIndex(MachineInstr &MI, Register BaseReg, 98 int64_t Offset) const override; 99 100 bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg, 101 int64_t Offset) const override; 102 103 const TargetRegisterClass *getPointerRegClass( 104 const MachineFunction &MF, unsigned Kind = 0) const override; 105 106 void buildSGPRSpillLoadStore(MachineBasicBlock::iterator MI, int Index, 107 int Offset, unsigned EltSize, Register VGPR, 108 int64_t VGPRLanes, RegScavenger *RS, 109 bool IsLoad) const; 110 111 /// If \p OnlyToVGPR is true, this will only succeed if this 112 bool spillSGPR(MachineBasicBlock::iterator MI, 113 int FI, RegScavenger *RS, 114 bool OnlyToVGPR = false) const; 115 116 bool restoreSGPR(MachineBasicBlock::iterator MI, 117 int FI, RegScavenger *RS, 118 bool OnlyToVGPR = false) const; 119 120 void eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, 121 unsigned FIOperandNum, 122 RegScavenger *RS) const override; 123 124 bool eliminateSGPRToVGPRSpillFrameIndex(MachineBasicBlock::iterator MI, 125 int FI, RegScavenger *RS) const; 126 127 StringRef getRegAsmName(MCRegister Reg) const override; 128 129 unsigned getHWRegIndex(MCRegister Reg) const { 130 return getEncodingValue(Reg) & 0xff; 131 } 132 133 static const TargetRegisterClass *getVGPRClassForBitWidth(unsigned BitWidth); 134 static const TargetRegisterClass *getAGPRClassForBitWidth(unsigned BitWidth); 135 static const TargetRegisterClass *getSGPRClassForBitWidth(unsigned BitWidth); 136 137 /// Return the 'base' register class for this register. 138 /// e.g. SGPR0 => SReg_32, VGPR => VGPR_32 SGPR0_SGPR1 -> SReg_32, etc. 139 const TargetRegisterClass *getPhysRegClass(MCRegister Reg) const; 140 141 /// \returns true if this class contains only SGPR registers 142 bool isSGPRClass(const TargetRegisterClass *RC) const { 143 return !hasVGPRs(RC) && !hasAGPRs(RC); 144 } 145 146 /// \returns true if this class ID contains only SGPR registers 147 bool isSGPRClassID(unsigned RCID) const { 148 return isSGPRClass(getRegClass(RCID)); 149 } 150 151 bool isSGPRReg(const MachineRegisterInfo &MRI, Register Reg) const { 152 const TargetRegisterClass *RC; 153 if (Reg.isVirtual()) 154 RC = MRI.getRegClass(Reg); 155 else 156 RC = getPhysRegClass(Reg); 157 return isSGPRClass(RC); 158 } 159 160 /// \returns true if this class contains only AGPR registers 161 bool isAGPRClass(const TargetRegisterClass *RC) const { 162 return hasAGPRs(RC) && !hasVGPRs(RC); 163 } 164 165 /// \returns true if this class contains VGPR registers. 166 bool hasVGPRs(const TargetRegisterClass *RC) const; 167 168 /// \returns true if this class contains AGPR registers. 169 bool hasAGPRs(const TargetRegisterClass *RC) const; 170 171 /// \returns true if this class contains any vector registers. 172 bool hasVectorRegisters(const TargetRegisterClass *RC) const { 173 return hasVGPRs(RC) || hasAGPRs(RC); 174 } 175 176 /// \returns A VGPR reg class with the same width as \p SRC 177 const TargetRegisterClass * 178 getEquivalentVGPRClass(const TargetRegisterClass *SRC) const; 179 180 /// \returns An AGPR reg class with the same width as \p SRC 181 const TargetRegisterClass * 182 getEquivalentAGPRClass(const TargetRegisterClass *SRC) const; 183 184 /// \returns A SGPR reg class with the same width as \p SRC 185 const TargetRegisterClass * 186 getEquivalentSGPRClass(const TargetRegisterClass *VRC) const; 187 188 /// \returns The register class that is used for a sub-register of \p RC for 189 /// the given \p SubIdx. If \p SubIdx equals NoSubRegister, \p RC will 190 /// be returned. 191 const TargetRegisterClass *getSubRegClass(const TargetRegisterClass *RC, 192 unsigned SubIdx) const; 193 194 bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC, 195 unsigned DefSubReg, 196 const TargetRegisterClass *SrcRC, 197 unsigned SrcSubReg) const override; 198 199 /// \returns True if operands defined with this operand type can accept 200 /// a literal constant (i.e. any 32-bit immediate). 201 bool opCanUseLiteralConstant(unsigned OpType) const { 202 // TODO: 64-bit operands have extending behavior from 32-bit literal. 203 return OpType >= AMDGPU::OPERAND_REG_IMM_FIRST && 204 OpType <= AMDGPU::OPERAND_REG_IMM_LAST; 205 } 206 207 /// \returns True if operands defined with this operand type can accept 208 /// an inline constant. i.e. An integer value in the range (-16, 64) or 209 /// -4.0f, -2.0f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 2.0f, 4.0f. 210 bool opCanUseInlineConstant(unsigned OpType) const; 211 212 MCRegister findUnusedRegister(const MachineRegisterInfo &MRI, 213 const TargetRegisterClass *RC, 214 const MachineFunction &MF, 215 bool ReserveHighestVGPR = false) const; 216 217 const TargetRegisterClass *getRegClassForReg(const MachineRegisterInfo &MRI, 218 Register Reg) const; 219 bool isVGPR(const MachineRegisterInfo &MRI, Register Reg) const; 220 bool isAGPR(const MachineRegisterInfo &MRI, Register Reg) const; 221 bool isVectorRegister(const MachineRegisterInfo &MRI, Register Reg) const { 222 return isVGPR(MRI, Reg) || isAGPR(MRI, Reg); 223 } 224 225 bool isConstantPhysReg(MCRegister PhysReg) const override; 226 227 bool isDivergentRegClass(const TargetRegisterClass *RC) const override { 228 return !isSGPRClass(RC); 229 } 230 231 ArrayRef<int16_t> getRegSplitParts(const TargetRegisterClass *RC, 232 unsigned EltSize) const; 233 234 bool shouldCoalesce(MachineInstr *MI, 235 const TargetRegisterClass *SrcRC, 236 unsigned SubReg, 237 const TargetRegisterClass *DstRC, 238 unsigned DstSubReg, 239 const TargetRegisterClass *NewRC, 240 LiveIntervals &LIS) const override; 241 242 unsigned getRegPressureLimit(const TargetRegisterClass *RC, 243 MachineFunction &MF) const override; 244 245 unsigned getRegPressureSetLimit(const MachineFunction &MF, 246 unsigned Idx) const override; 247 248 const int *getRegUnitPressureSets(unsigned RegUnit) const override; 249 250 MCRegister getReturnAddressReg(const MachineFunction &MF) const; 251 252 const TargetRegisterClass * 253 getRegClassForSizeOnBank(unsigned Size, 254 const RegisterBank &Bank, 255 const MachineRegisterInfo &MRI) const; 256 257 const TargetRegisterClass * 258 getRegClassForTypeOnBank(LLT Ty, 259 const RegisterBank &Bank, 260 const MachineRegisterInfo &MRI) const { 261 return getRegClassForSizeOnBank(Ty.getSizeInBits(), Bank, MRI); 262 } 263 264 const TargetRegisterClass * 265 getConstrainedRegClassForOperand(const MachineOperand &MO, 266 const MachineRegisterInfo &MRI) const override; 267 268 const TargetRegisterClass *getBoolRC() const { 269 return isWave32 ? &AMDGPU::SReg_32RegClass 270 : &AMDGPU::SReg_64RegClass; 271 } 272 273 const TargetRegisterClass *getWaveMaskRegClass() const { 274 return isWave32 ? &AMDGPU::SReg_32_XM0_XEXECRegClass 275 : &AMDGPU::SReg_64_XEXECRegClass; 276 } 277 278 MCRegister getVCC() const; 279 280 const TargetRegisterClass *getRegClass(unsigned RCID) const; 281 282 // Find reaching register definition 283 MachineInstr *findReachingDef(Register Reg, unsigned SubReg, 284 MachineInstr &Use, 285 MachineRegisterInfo &MRI, 286 LiveIntervals *LIS) const; 287 288 const uint32_t *getAllVGPRRegMask() const; 289 const uint32_t *getAllAllocatableSRegMask() const; 290 291 // \returns number of 32 bit registers covered by a \p LM 292 static unsigned getNumCoveredRegs(LaneBitmask LM) { 293 // The assumption is that every lo16 subreg is an even bit and every hi16 294 // is an adjacent odd bit or vice versa. 295 uint64_t Mask = LM.getAsInteger(); 296 uint64_t Even = Mask & 0xAAAAAAAAAAAAAAAAULL; 297 Mask = (Even >> 1) | Mask; 298 uint64_t Odd = Mask & 0x5555555555555555ULL; 299 return countPopulation(Odd); 300 } 301 302 // \returns a DWORD offset of a \p SubReg 303 unsigned getChannelFromSubReg(unsigned SubReg) const { 304 return SubReg ? (getSubRegIdxOffset(SubReg) + 31) / 32 : 0; 305 } 306 307 // \returns a DWORD size of a \p SubReg 308 unsigned getNumChannelsFromSubReg(unsigned SubReg) const { 309 return getNumCoveredRegs(getSubRegIndexLaneMask(SubReg)); 310 } 311 312 // For a given 16 bit \p Reg \returns a 32 bit register holding it. 313 // \returns \p Reg otherwise. 314 MCPhysReg get32BitRegister(MCPhysReg Reg) const; 315 316 /// Return all SGPR128 which satisfy the waves per execution unit requirement 317 /// of the subtarget. 318 ArrayRef<MCPhysReg> getAllSGPR128(const MachineFunction &MF) const; 319 320 /// Return all SGPR32 which satisfy the waves per execution unit requirement 321 /// of the subtarget. 322 ArrayRef<MCPhysReg> getAllSGPR32(const MachineFunction &MF) const; 323 324 /// Return all VGPR32 which satisfy the waves per execution unit requirement 325 /// of the subtarget. 326 ArrayRef<MCPhysReg> getAllVGPR32(const MachineFunction &MF) const; 327 328 private: 329 void buildSpillLoadStore(MachineBasicBlock::iterator MI, 330 unsigned LoadStoreOp, 331 int Index, 332 Register ValueReg, 333 bool ValueIsKill, 334 MCRegister ScratchRsrcReg, 335 MCRegister ScratchOffsetReg, 336 int64_t InstrOffset, 337 MachineMemOperand *MMO, 338 RegScavenger *RS) const; 339 }; 340 341 } // End namespace llvm 342 343 #endif 344