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