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 22 namespace llvm { 23 24 class GCNSubtarget; 25 class LiveIntervals; 26 class LivePhysRegs; 27 class RegisterBank; 28 struct SGPRSpillBuilder; 29 30 class SIRegisterInfo final : public AMDGPUGenRegisterInfo { 31 private: 32 const GCNSubtarget &ST; 33 bool SpillSGPRToVGPR; 34 bool isWave32; 35 BitVector RegPressureIgnoredUnits; 36 37 /// Sub reg indexes for getRegSplitParts. 38 /// First index represents subreg size from 1 to 16 DWORDs. 39 /// The inner vector is sorted by bit offset. 40 /// Provided a register can be fully split with given subregs, 41 /// all elements of the inner vector combined give a full lane mask. 42 static std::array<std::vector<int16_t>, 16> RegSplitParts; 43 44 // Table representing sub reg of given width and offset. 45 // First index is subreg size: 32, 64, 96, 128, 160, 192, 224, 256, 512. 46 // Second index is 32 different dword offsets. 47 static std::array<std::array<uint16_t, 32>, 9> SubRegFromChannelTable; 48 49 void reserveRegisterTuples(BitVector &, MCRegister Reg) const; 50 51 public: 52 SIRegisterInfo(const GCNSubtarget &ST); 53 54 struct SpilledReg { 55 Register VGPR; 56 int Lane = -1; 57 58 SpilledReg() = default; SpilledRegSpilledReg59 SpilledReg(Register R, int L) : VGPR(R), Lane(L) {} 60 hasLaneSpilledReg61 bool hasLane() { return Lane != -1; } hasRegSpilledReg62 bool hasReg() { return VGPR != 0; } 63 }; 64 65 /// \returns the sub reg enum value for the given \p Channel 66 /// (e.g. getSubRegFromChannel(0) -> AMDGPU::sub0) 67 static unsigned getSubRegFromChannel(unsigned Channel, unsigned NumRegs = 1); 68 spillSGPRToVGPR()69 bool spillSGPRToVGPR() const { 70 return SpillSGPRToVGPR; 71 } 72 73 /// Return the end register initially reserved for the scratch buffer in case 74 /// spilling is needed. 75 MCRegister reservedPrivateSegmentBufferReg(const MachineFunction &MF) const; 76 77 BitVector getReservedRegs(const MachineFunction &MF) const override; 78 bool isAsmClobberable(const MachineFunction &MF, 79 MCRegister PhysReg) const override; 80 81 const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override; 82 const MCPhysReg *getCalleeSavedRegsViaCopy(const MachineFunction *MF) const; 83 const uint32_t *getCallPreservedMask(const MachineFunction &MF, 84 CallingConv::ID) const override; 85 const uint32_t *getNoPreservedMask() const override; 86 87 // Stack access is very expensive. CSRs are also the high registers, and we 88 // want to minimize the number of used registers. getCSRFirstUseCost()89 unsigned getCSRFirstUseCost() const override { 90 return 100; 91 } 92 93 const TargetRegisterClass * 94 getLargestLegalSuperClass(const TargetRegisterClass *RC, 95 const MachineFunction &MF) const override; 96 97 Register getFrameRegister(const MachineFunction &MF) const override; 98 99 bool hasBasePointer(const MachineFunction &MF) const; 100 Register getBaseRegister() const; 101 102 bool shouldRealignStack(const MachineFunction &MF) const override; 103 bool requiresRegisterScavenging(const MachineFunction &Fn) const override; 104 105 bool requiresFrameIndexScavenging(const MachineFunction &MF) const override; 106 bool requiresFrameIndexReplacementScavenging( 107 const MachineFunction &MF) const override; 108 bool requiresVirtualBaseRegisters(const MachineFunction &Fn) const override; 109 110 int64_t getScratchInstrOffset(const MachineInstr *MI) const; 111 112 int64_t getFrameIndexInstrOffset(const MachineInstr *MI, 113 int Idx) const override; 114 115 bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override; 116 117 Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx, 118 int64_t Offset) const override; 119 120 void resolveFrameIndex(MachineInstr &MI, Register BaseReg, 121 int64_t Offset) const override; 122 123 bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg, 124 int64_t Offset) const override; 125 126 const TargetRegisterClass *getPointerRegClass( 127 const MachineFunction &MF, unsigned Kind = 0) const override; 128 129 /// Returns a legal register class to copy a register in the specified class 130 /// to or from. If it is possible to copy the register directly without using 131 /// a cross register class copy, return the specified RC. Returns NULL if it 132 /// is not possible to copy between two registers of the specified class. 133 const TargetRegisterClass * 134 getCrossCopyRegClass(const TargetRegisterClass *RC) const override; 135 136 void buildVGPRSpillLoadStore(SGPRSpillBuilder &SB, int Index, int Offset, 137 bool IsLoad, bool IsKill = true) const; 138 139 /// If \p OnlyToVGPR is true, this will only succeed if this 140 bool spillSGPR(MachineBasicBlock::iterator MI, int FI, RegScavenger *RS, 141 SlotIndexes *Indexes = nullptr, LiveIntervals *LIS = nullptr, 142 bool OnlyToVGPR = false) const; 143 144 bool restoreSGPR(MachineBasicBlock::iterator MI, int FI, RegScavenger *RS, 145 SlotIndexes *Indexes = nullptr, LiveIntervals *LIS = nullptr, 146 bool OnlyToVGPR = false) const; 147 148 bool spillEmergencySGPR(MachineBasicBlock::iterator MI, 149 MachineBasicBlock &RestoreMBB, Register SGPR, 150 RegScavenger *RS) const; 151 supportsBackwardScavenger()152 bool supportsBackwardScavenger() const override { 153 return true; 154 } 155 156 bool eliminateFrameIndex(MachineBasicBlock::iterator MI, int SPAdj, 157 unsigned FIOperandNum, 158 RegScavenger *RS) const override; 159 160 bool eliminateSGPRToVGPRSpillFrameIndex(MachineBasicBlock::iterator MI, 161 int FI, RegScavenger *RS, 162 SlotIndexes *Indexes = nullptr, 163 LiveIntervals *LIS = nullptr) const; 164 165 StringRef getRegAsmName(MCRegister Reg) const override; 166 167 // Pseudo regs are not allowed getHWRegIndex(MCRegister Reg)168 unsigned getHWRegIndex(MCRegister Reg) const { 169 return getEncodingValue(Reg) & 0xff; 170 } 171 172 LLVM_READONLY 173 const TargetRegisterClass *getVGPRClassForBitWidth(unsigned BitWidth) const; 174 175 LLVM_READONLY 176 const TargetRegisterClass *getAGPRClassForBitWidth(unsigned BitWidth) const; 177 178 LLVM_READONLY 179 const TargetRegisterClass * 180 getVectorSuperClassForBitWidth(unsigned BitWidth) const; 181 182 LLVM_READONLY 183 static const TargetRegisterClass *getSGPRClassForBitWidth(unsigned BitWidth); 184 185 /// \returns true if this class contains only SGPR registers isSGPRClass(const TargetRegisterClass * RC)186 static bool isSGPRClass(const TargetRegisterClass *RC) { 187 return hasSGPRs(RC) && !hasVGPRs(RC) && !hasAGPRs(RC); 188 } 189 190 /// \returns true if this class ID contains only SGPR registers isSGPRClassID(unsigned RCID)191 bool isSGPRClassID(unsigned RCID) const { 192 return isSGPRClass(getRegClass(RCID)); 193 } 194 195 bool isSGPRReg(const MachineRegisterInfo &MRI, Register Reg) const; 196 197 /// \returns true if this class contains only VGPR registers isVGPRClass(const TargetRegisterClass * RC)198 static bool isVGPRClass(const TargetRegisterClass *RC) { 199 return hasVGPRs(RC) && !hasAGPRs(RC) && !hasSGPRs(RC); 200 } 201 202 /// \returns true if this class contains only AGPR registers isAGPRClass(const TargetRegisterClass * RC)203 static bool isAGPRClass(const TargetRegisterClass *RC) { 204 return hasAGPRs(RC) && !hasVGPRs(RC) && !hasSGPRs(RC); 205 } 206 207 /// \returns true only if this class contains both VGPR and AGPR registers isVectorSuperClass(const TargetRegisterClass * RC)208 bool isVectorSuperClass(const TargetRegisterClass *RC) const { 209 return hasVGPRs(RC) && hasAGPRs(RC) && !hasSGPRs(RC); 210 } 211 212 /// \returns true only if this class contains both VGPR and SGPR registers isVSSuperClass(const TargetRegisterClass * RC)213 bool isVSSuperClass(const TargetRegisterClass *RC) const { 214 return hasVGPRs(RC) && hasSGPRs(RC) && !hasAGPRs(RC); 215 } 216 217 /// \returns true if this class contains VGPR registers. hasVGPRs(const TargetRegisterClass * RC)218 static bool hasVGPRs(const TargetRegisterClass *RC) { 219 return RC->TSFlags & SIRCFlags::HasVGPR; 220 } 221 222 /// \returns true if this class contains AGPR registers. hasAGPRs(const TargetRegisterClass * RC)223 static bool hasAGPRs(const TargetRegisterClass *RC) { 224 return RC->TSFlags & SIRCFlags::HasAGPR; 225 } 226 227 /// \returns true if this class contains SGPR registers. hasSGPRs(const TargetRegisterClass * RC)228 static bool hasSGPRs(const TargetRegisterClass *RC) { 229 return RC->TSFlags & SIRCFlags::HasSGPR; 230 } 231 232 /// \returns true if this class contains any vector registers. hasVectorRegisters(const TargetRegisterClass * RC)233 static bool hasVectorRegisters(const TargetRegisterClass *RC) { 234 return hasVGPRs(RC) || hasAGPRs(RC); 235 } 236 237 /// \returns A VGPR reg class with the same width as \p SRC 238 const TargetRegisterClass * 239 getEquivalentVGPRClass(const TargetRegisterClass *SRC) const; 240 241 /// \returns An AGPR reg class with the same width as \p SRC 242 const TargetRegisterClass * 243 getEquivalentAGPRClass(const TargetRegisterClass *SRC) const; 244 245 /// \returns A SGPR reg class with the same width as \p SRC 246 const TargetRegisterClass * 247 getEquivalentSGPRClass(const TargetRegisterClass *VRC) const; 248 249 /// Returns a register class which is compatible with \p SuperRC, such that a 250 /// subregister exists with class \p SubRC with subregister index \p 251 /// SubIdx. If this is impossible (e.g., an unaligned subregister index within 252 /// a register tuple), return null. 253 const TargetRegisterClass * 254 getCompatibleSubRegClass(const TargetRegisterClass *SuperRC, 255 const TargetRegisterClass *SubRC, 256 unsigned SubIdx) const; 257 258 bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC, 259 unsigned DefSubReg, 260 const TargetRegisterClass *SrcRC, 261 unsigned SrcSubReg) const override; 262 263 /// \returns True if operands defined with this operand type can accept 264 /// a literal constant (i.e. any 32-bit immediate). 265 bool opCanUseLiteralConstant(unsigned OpType) const; 266 267 /// \returns True if operands defined with this operand type can accept 268 /// an inline constant. i.e. An integer value in the range (-16, 64) or 269 /// -4.0f, -2.0f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 2.0f, 4.0f. 270 bool opCanUseInlineConstant(unsigned OpType) const; 271 272 MCRegister findUnusedRegister(const MachineRegisterInfo &MRI, 273 const TargetRegisterClass *RC, 274 const MachineFunction &MF, 275 bool ReserveHighestVGPR = false) const; 276 277 const TargetRegisterClass *getRegClassForReg(const MachineRegisterInfo &MRI, 278 Register Reg) const; 279 const TargetRegisterClass * 280 getRegClassForOperandReg(const MachineRegisterInfo &MRI, 281 const MachineOperand &MO) const; 282 283 bool isVGPR(const MachineRegisterInfo &MRI, Register Reg) const; 284 bool isAGPR(const MachineRegisterInfo &MRI, Register Reg) const; isVectorRegister(const MachineRegisterInfo & MRI,Register Reg)285 bool isVectorRegister(const MachineRegisterInfo &MRI, Register Reg) const { 286 return isVGPR(MRI, Reg) || isAGPR(MRI, Reg); 287 } 288 isDivergentRegClass(const TargetRegisterClass * RC)289 bool isDivergentRegClass(const TargetRegisterClass *RC) const override { 290 return !isSGPRClass(RC); 291 } 292 293 ArrayRef<int16_t> getRegSplitParts(const TargetRegisterClass *RC, 294 unsigned EltSize) const; 295 296 bool shouldCoalesce(MachineInstr *MI, 297 const TargetRegisterClass *SrcRC, 298 unsigned SubReg, 299 const TargetRegisterClass *DstRC, 300 unsigned DstSubReg, 301 const TargetRegisterClass *NewRC, 302 LiveIntervals &LIS) const override; 303 304 unsigned getRegPressureLimit(const TargetRegisterClass *RC, 305 MachineFunction &MF) const override; 306 307 unsigned getRegPressureSetLimit(const MachineFunction &MF, 308 unsigned Idx) const override; 309 310 const int *getRegUnitPressureSets(unsigned RegUnit) const override; 311 312 MCRegister getReturnAddressReg(const MachineFunction &MF) const; 313 314 const TargetRegisterClass * 315 getRegClassForSizeOnBank(unsigned Size, const RegisterBank &Bank) const; 316 317 const TargetRegisterClass * getRegClassForTypeOnBank(LLT Ty,const RegisterBank & Bank)318 getRegClassForTypeOnBank(LLT Ty, const RegisterBank &Bank) const { 319 return getRegClassForSizeOnBank(Ty.getSizeInBits(), Bank); 320 } 321 322 const TargetRegisterClass * 323 getConstrainedRegClassForOperand(const MachineOperand &MO, 324 const MachineRegisterInfo &MRI) const override; 325 getBoolRC()326 const TargetRegisterClass *getBoolRC() const { 327 return isWave32 ? &AMDGPU::SReg_32RegClass 328 : &AMDGPU::SReg_64RegClass; 329 } 330 getWaveMaskRegClass()331 const TargetRegisterClass *getWaveMaskRegClass() const { 332 return isWave32 ? &AMDGPU::SReg_32_XM0_XEXECRegClass 333 : &AMDGPU::SReg_64_XEXECRegClass; 334 } 335 336 // Return the appropriate register class to use for 64-bit VGPRs for the 337 // subtarget. 338 const TargetRegisterClass *getVGPR64Class() const; 339 340 MCRegister getVCC() const; 341 342 MCRegister getExec() const; 343 344 const TargetRegisterClass *getRegClass(unsigned RCID) const; 345 346 // Find reaching register definition 347 MachineInstr *findReachingDef(Register Reg, unsigned SubReg, 348 MachineInstr &Use, 349 MachineRegisterInfo &MRI, 350 LiveIntervals *LIS) const; 351 352 const uint32_t *getAllVGPRRegMask() const; 353 const uint32_t *getAllAGPRRegMask() const; 354 const uint32_t *getAllVectorRegMask() const; 355 const uint32_t *getAllAllocatableSRegMask() const; 356 357 // \returns number of 32 bit registers covered by a \p LM getNumCoveredRegs(LaneBitmask LM)358 static unsigned getNumCoveredRegs(LaneBitmask LM) { 359 // The assumption is that every lo16 subreg is an even bit and every hi16 360 // is an adjacent odd bit or vice versa. 361 uint64_t Mask = LM.getAsInteger(); 362 uint64_t Even = Mask & 0xAAAAAAAAAAAAAAAAULL; 363 Mask = (Even >> 1) | Mask; 364 uint64_t Odd = Mask & 0x5555555555555555ULL; 365 return llvm::popcount(Odd); 366 } 367 368 // \returns a DWORD offset of a \p SubReg getChannelFromSubReg(unsigned SubReg)369 unsigned getChannelFromSubReg(unsigned SubReg) const { 370 return SubReg ? (getSubRegIdxOffset(SubReg) + 31) / 32 : 0; 371 } 372 373 // \returns a DWORD size of a \p SubReg getNumChannelsFromSubReg(unsigned SubReg)374 unsigned getNumChannelsFromSubReg(unsigned SubReg) const { 375 return getNumCoveredRegs(getSubRegIndexLaneMask(SubReg)); 376 } 377 378 // For a given 16 bit \p Reg \returns a 32 bit register holding it. 379 // \returns \p Reg otherwise. 380 MCPhysReg get32BitRegister(MCPhysReg Reg) const; 381 382 // Returns true if a given register class is properly aligned for 383 // the subtarget. 384 bool isProperlyAlignedRC(const TargetRegisterClass &RC) const; 385 386 // Given \p RC returns corresponding aligned register class if required 387 // by the subtarget. 388 const TargetRegisterClass * 389 getProperlyAlignedRC(const TargetRegisterClass *RC) const; 390 391 /// Return all SGPR128 which satisfy the waves per execution unit requirement 392 /// of the subtarget. 393 ArrayRef<MCPhysReg> getAllSGPR128(const MachineFunction &MF) const; 394 395 /// Return all SGPR64 which satisfy the waves per execution unit requirement 396 /// of the subtarget. 397 ArrayRef<MCPhysReg> getAllSGPR64(const MachineFunction &MF) const; 398 399 /// Return all SGPR32 which satisfy the waves per execution unit requirement 400 /// of the subtarget. 401 ArrayRef<MCPhysReg> getAllSGPR32(const MachineFunction &MF) const; 402 403 // Insert spill or restore instructions. 404 // When lowering spill pseudos, the RegScavenger should be set. 405 // For creating spill instructions during frame lowering, where no scavenger 406 // is available, LiveRegs can be used. 407 void buildSpillLoadStore(MachineBasicBlock &MBB, 408 MachineBasicBlock::iterator MI, const DebugLoc &DL, 409 unsigned LoadStoreOp, int Index, Register ValueReg, 410 bool ValueIsKill, MCRegister ScratchOffsetReg, 411 int64_t InstrOffset, MachineMemOperand *MMO, 412 RegScavenger *RS, 413 LivePhysRegs *LiveRegs = nullptr) const; 414 }; 415 416 } // End namespace llvm 417 418 #endif 419