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