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