1 //===-- SIRegisterInfo.cpp - SI Register Information ---------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 /// \file 11 /// \brief SI implementation of the TargetRegisterInfo class. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "SIRegisterInfo.h" 16 #include "SIInstrInfo.h" 17 #include "SIMachineFunctionInfo.h" 18 #include "llvm/CodeGen/MachineFrameInfo.h" 19 #include "llvm/CodeGen/MachineInstrBuilder.h" 20 #include "llvm/CodeGen/RegisterScavenging.h" 21 #include "llvm/IR/Function.h" 22 #include "llvm/IR/LLVMContext.h" 23 24 using namespace llvm; 25 26 SIRegisterInfo::SIRegisterInfo() : AMDGPURegisterInfo() {} 27 28 void SIRegisterInfo::reserveRegisterTuples(BitVector &Reserved, unsigned Reg) const { 29 MCRegAliasIterator R(Reg, this, true); 30 31 for (; R.isValid(); ++R) 32 Reserved.set(*R); 33 } 34 35 BitVector SIRegisterInfo::getReservedRegs(const MachineFunction &MF) const { 36 BitVector Reserved(getNumRegs()); 37 Reserved.set(AMDGPU::INDIRECT_BASE_ADDR); 38 39 // EXEC_LO and EXEC_HI could be allocated and used as regular register, but 40 // this seems likely to result in bugs, so I'm marking them as reserved. 41 reserveRegisterTuples(Reserved, AMDGPU::EXEC); 42 reserveRegisterTuples(Reserved, AMDGPU::FLAT_SCR); 43 44 // Reserve the last 2 registers so we will always have at least 2 more that 45 // will physically contain VCC. 46 reserveRegisterTuples(Reserved, AMDGPU::SGPR102_SGPR103); 47 48 const AMDGPUSubtarget &ST = MF.getSubtarget<AMDGPUSubtarget>(); 49 50 if (ST.getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS) { 51 // SI/CI have 104 SGPRs. VI has 102. We need to shift down the reservation 52 // for VCC/FLAT_SCR. 53 reserveRegisterTuples(Reserved, AMDGPU::SGPR98_SGPR99); 54 reserveRegisterTuples(Reserved, AMDGPU::SGPR100_SGPR101); 55 } 56 57 // Tonga and Iceland can only allocate a fixed number of SGPRs due 58 // to a hw bug. 59 if (ST.hasSGPRInitBug()) { 60 unsigned NumSGPRs = AMDGPU::SGPR_32RegClass.getNumRegs(); 61 // Reserve some SGPRs for FLAT_SCRATCH and VCC (4 SGPRs). 62 // Assume XNACK_MASK is unused. 63 unsigned Limit = AMDGPUSubtarget::FIXED_SGPR_COUNT_FOR_INIT_BUG - 4; 64 65 for (unsigned i = Limit; i < NumSGPRs; ++i) { 66 unsigned Reg = AMDGPU::SGPR_32RegClass.getRegister(i); 67 reserveRegisterTuples(Reserved, Reg); 68 } 69 } 70 71 return Reserved; 72 } 73 74 unsigned SIRegisterInfo::getRegPressureSetLimit(const MachineFunction &MF, 75 unsigned Idx) const { 76 const AMDGPUSubtarget &STI = MF.getSubtarget<AMDGPUSubtarget>(); 77 // FIXME: We should adjust the max number of waves based on LDS size. 78 unsigned SGPRLimit = getNumSGPRsAllowed(STI.getGeneration(), 79 STI.getMaxWavesPerCU()); 80 unsigned VGPRLimit = getNumVGPRsAllowed(STI.getMaxWavesPerCU()); 81 82 unsigned VSLimit = SGPRLimit + VGPRLimit; 83 84 for (regclass_iterator I = regclass_begin(), E = regclass_end(); 85 I != E; ++I) { 86 const TargetRegisterClass *RC = *I; 87 88 unsigned NumSubRegs = std::max((int)RC->getSize() / 4, 1); 89 unsigned Limit; 90 91 if (isPseudoRegClass(RC)) { 92 // FIXME: This is a hack. We should never be considering the pressure of 93 // these since no virtual register should ever have this class. 94 Limit = VSLimit; 95 } else if (isSGPRClass(RC)) { 96 Limit = SGPRLimit / NumSubRegs; 97 } else { 98 Limit = VGPRLimit / NumSubRegs; 99 } 100 101 const int *Sets = getRegClassPressureSets(RC); 102 assert(Sets); 103 for (unsigned i = 0; Sets[i] != -1; ++i) { 104 if (Sets[i] == (int)Idx) 105 return Limit; 106 } 107 } 108 return 256; 109 } 110 111 bool SIRegisterInfo::requiresRegisterScavenging(const MachineFunction &Fn) const { 112 return Fn.getFrameInfo()->hasStackObjects(); 113 } 114 115 static unsigned getNumSubRegsForSpillOp(unsigned Op) { 116 117 switch (Op) { 118 case AMDGPU::SI_SPILL_S512_SAVE: 119 case AMDGPU::SI_SPILL_S512_RESTORE: 120 case AMDGPU::SI_SPILL_V512_SAVE: 121 case AMDGPU::SI_SPILL_V512_RESTORE: 122 return 16; 123 case AMDGPU::SI_SPILL_S256_SAVE: 124 case AMDGPU::SI_SPILL_S256_RESTORE: 125 case AMDGPU::SI_SPILL_V256_SAVE: 126 case AMDGPU::SI_SPILL_V256_RESTORE: 127 return 8; 128 case AMDGPU::SI_SPILL_S128_SAVE: 129 case AMDGPU::SI_SPILL_S128_RESTORE: 130 case AMDGPU::SI_SPILL_V128_SAVE: 131 case AMDGPU::SI_SPILL_V128_RESTORE: 132 return 4; 133 case AMDGPU::SI_SPILL_V96_SAVE: 134 case AMDGPU::SI_SPILL_V96_RESTORE: 135 return 3; 136 case AMDGPU::SI_SPILL_S64_SAVE: 137 case AMDGPU::SI_SPILL_S64_RESTORE: 138 case AMDGPU::SI_SPILL_V64_SAVE: 139 case AMDGPU::SI_SPILL_V64_RESTORE: 140 return 2; 141 case AMDGPU::SI_SPILL_S32_SAVE: 142 case AMDGPU::SI_SPILL_S32_RESTORE: 143 case AMDGPU::SI_SPILL_V32_SAVE: 144 case AMDGPU::SI_SPILL_V32_RESTORE: 145 return 1; 146 default: llvm_unreachable("Invalid spill opcode"); 147 } 148 } 149 150 void SIRegisterInfo::buildScratchLoadStore(MachineBasicBlock::iterator MI, 151 unsigned LoadStoreOp, 152 unsigned Value, 153 unsigned ScratchRsrcReg, 154 unsigned ScratchOffset, 155 int64_t Offset, 156 RegScavenger *RS) const { 157 158 MachineBasicBlock *MBB = MI->getParent(); 159 const MachineFunction *MF = MI->getParent()->getParent(); 160 const SIInstrInfo *TII = 161 static_cast<const SIInstrInfo *>(MF->getSubtarget().getInstrInfo()); 162 LLVMContext &Ctx = MF->getFunction()->getContext(); 163 DebugLoc DL = MI->getDebugLoc(); 164 bool IsLoad = TII->get(LoadStoreOp).mayLoad(); 165 166 bool RanOutOfSGPRs = false; 167 unsigned SOffset = ScratchOffset; 168 169 unsigned NumSubRegs = getNumSubRegsForSpillOp(MI->getOpcode()); 170 unsigned Size = NumSubRegs * 4; 171 172 if (!isUInt<12>(Offset + Size)) { 173 SOffset = RS->scavengeRegister(&AMDGPU::SGPR_32RegClass, MI, 0); 174 if (SOffset == AMDGPU::NoRegister) { 175 RanOutOfSGPRs = true; 176 SOffset = AMDGPU::SGPR0; 177 } 178 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::S_ADD_U32), SOffset) 179 .addReg(ScratchOffset) 180 .addImm(Offset); 181 Offset = 0; 182 } 183 184 if (RanOutOfSGPRs) 185 Ctx.emitError("Ran out of SGPRs for spilling VGPRS"); 186 187 for (unsigned i = 0, e = NumSubRegs; i != e; ++i, Offset += 4) { 188 unsigned SubReg = NumSubRegs > 1 ? 189 getPhysRegSubReg(Value, &AMDGPU::VGPR_32RegClass, i) : 190 Value; 191 bool IsKill = (i == e - 1); 192 193 BuildMI(*MBB, MI, DL, TII->get(LoadStoreOp)) 194 .addReg(SubReg, getDefRegState(IsLoad)) 195 .addReg(ScratchRsrcReg, getKillRegState(IsKill)) 196 .addReg(SOffset) 197 .addImm(Offset) 198 .addImm(0) // glc 199 .addImm(0) // slc 200 .addImm(0) // tfe 201 .addReg(Value, RegState::Implicit | getDefRegState(IsLoad)) 202 .setMemRefs(MI->memoperands_begin(), MI->memoperands_end()); 203 } 204 } 205 206 void SIRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI, 207 int SPAdj, unsigned FIOperandNum, 208 RegScavenger *RS) const { 209 MachineFunction *MF = MI->getParent()->getParent(); 210 MachineBasicBlock *MBB = MI->getParent(); 211 SIMachineFunctionInfo *MFI = MF->getInfo<SIMachineFunctionInfo>(); 212 MachineFrameInfo *FrameInfo = MF->getFrameInfo(); 213 const SIInstrInfo *TII = 214 static_cast<const SIInstrInfo *>(MF->getSubtarget().getInstrInfo()); 215 DebugLoc DL = MI->getDebugLoc(); 216 217 MachineOperand &FIOp = MI->getOperand(FIOperandNum); 218 int Index = MI->getOperand(FIOperandNum).getIndex(); 219 220 switch (MI->getOpcode()) { 221 // SGPR register spill 222 case AMDGPU::SI_SPILL_S512_SAVE: 223 case AMDGPU::SI_SPILL_S256_SAVE: 224 case AMDGPU::SI_SPILL_S128_SAVE: 225 case AMDGPU::SI_SPILL_S64_SAVE: 226 case AMDGPU::SI_SPILL_S32_SAVE: { 227 unsigned NumSubRegs = getNumSubRegsForSpillOp(MI->getOpcode()); 228 229 for (unsigned i = 0, e = NumSubRegs; i < e; ++i) { 230 unsigned SubReg = getPhysRegSubReg(MI->getOperand(0).getReg(), 231 &AMDGPU::SGPR_32RegClass, i); 232 struct SIMachineFunctionInfo::SpilledReg Spill = 233 MFI->getSpilledReg(MF, Index, i); 234 235 if (Spill.VGPR == AMDGPU::NoRegister) { 236 LLVMContext &Ctx = MF->getFunction()->getContext(); 237 Ctx.emitError("Ran out of VGPRs for spilling SGPR"); 238 } 239 240 BuildMI(*MBB, MI, DL, 241 TII->getMCOpcodeFromPseudo(AMDGPU::V_WRITELANE_B32), 242 Spill.VGPR) 243 .addReg(SubReg) 244 .addImm(Spill.Lane); 245 246 } 247 MI->eraseFromParent(); 248 break; 249 } 250 251 // SGPR register restore 252 case AMDGPU::SI_SPILL_S512_RESTORE: 253 case AMDGPU::SI_SPILL_S256_RESTORE: 254 case AMDGPU::SI_SPILL_S128_RESTORE: 255 case AMDGPU::SI_SPILL_S64_RESTORE: 256 case AMDGPU::SI_SPILL_S32_RESTORE: { 257 unsigned NumSubRegs = getNumSubRegsForSpillOp(MI->getOpcode()); 258 259 for (unsigned i = 0, e = NumSubRegs; i < e; ++i) { 260 unsigned SubReg = getPhysRegSubReg(MI->getOperand(0).getReg(), 261 &AMDGPU::SGPR_32RegClass, i); 262 struct SIMachineFunctionInfo::SpilledReg Spill = 263 MFI->getSpilledReg(MF, Index, i); 264 265 if (Spill.VGPR == AMDGPU::NoRegister) { 266 LLVMContext &Ctx = MF->getFunction()->getContext(); 267 Ctx.emitError("Ran out of VGPRs for spilling SGPR"); 268 } 269 270 BuildMI(*MBB, MI, DL, 271 TII->getMCOpcodeFromPseudo(AMDGPU::V_READLANE_B32), 272 SubReg) 273 .addReg(Spill.VGPR) 274 .addImm(Spill.Lane) 275 .addReg(MI->getOperand(0).getReg(), RegState::ImplicitDefine); 276 } 277 278 // TODO: only do this when it is needed 279 switch (MF->getSubtarget<AMDGPUSubtarget>().getGeneration()) { 280 case AMDGPUSubtarget::SOUTHERN_ISLANDS: 281 // "VALU writes SGPR" -> "SMRD reads that SGPR" needs "S_NOP 3" on SI 282 TII->insertNOPs(MI, 3); 283 break; 284 case AMDGPUSubtarget::SEA_ISLANDS: 285 break; 286 default: // VOLCANIC_ISLANDS and later 287 // "VALU writes SGPR -> VMEM reads that SGPR" needs "S_NOP 4" on VI 288 // and later. This also applies to VALUs which write VCC, but we're 289 // unlikely to see VMEM use VCC. 290 TII->insertNOPs(MI, 4); 291 } 292 293 MI->eraseFromParent(); 294 break; 295 } 296 297 // VGPR register spill 298 case AMDGPU::SI_SPILL_V512_SAVE: 299 case AMDGPU::SI_SPILL_V256_SAVE: 300 case AMDGPU::SI_SPILL_V128_SAVE: 301 case AMDGPU::SI_SPILL_V96_SAVE: 302 case AMDGPU::SI_SPILL_V64_SAVE: 303 case AMDGPU::SI_SPILL_V32_SAVE: 304 buildScratchLoadStore(MI, AMDGPU::BUFFER_STORE_DWORD_OFFSET, 305 TII->getNamedOperand(*MI, AMDGPU::OpName::src)->getReg(), 306 TII->getNamedOperand(*MI, AMDGPU::OpName::scratch_rsrc)->getReg(), 307 TII->getNamedOperand(*MI, AMDGPU::OpName::scratch_offset)->getReg(), 308 FrameInfo->getObjectOffset(Index), RS); 309 MI->eraseFromParent(); 310 break; 311 case AMDGPU::SI_SPILL_V32_RESTORE: 312 case AMDGPU::SI_SPILL_V64_RESTORE: 313 case AMDGPU::SI_SPILL_V96_RESTORE: 314 case AMDGPU::SI_SPILL_V128_RESTORE: 315 case AMDGPU::SI_SPILL_V256_RESTORE: 316 case AMDGPU::SI_SPILL_V512_RESTORE: { 317 buildScratchLoadStore(MI, AMDGPU::BUFFER_LOAD_DWORD_OFFSET, 318 TII->getNamedOperand(*MI, AMDGPU::OpName::dst)->getReg(), 319 TII->getNamedOperand(*MI, AMDGPU::OpName::scratch_rsrc)->getReg(), 320 TII->getNamedOperand(*MI, AMDGPU::OpName::scratch_offset)->getReg(), 321 FrameInfo->getObjectOffset(Index), RS); 322 MI->eraseFromParent(); 323 break; 324 } 325 326 default: { 327 int64_t Offset = FrameInfo->getObjectOffset(Index); 328 FIOp.ChangeToImmediate(Offset); 329 if (!TII->isImmOperandLegal(MI, FIOperandNum, FIOp)) { 330 unsigned TmpReg = RS->scavengeRegister(&AMDGPU::VGPR_32RegClass, MI, SPAdj); 331 BuildMI(*MBB, MI, MI->getDebugLoc(), 332 TII->get(AMDGPU::V_MOV_B32_e32), TmpReg) 333 .addImm(Offset); 334 FIOp.ChangeToRegister(TmpReg, false, false, true); 335 } 336 } 337 } 338 } 339 340 unsigned SIRegisterInfo::getHWRegIndex(unsigned Reg) const { 341 return getEncodingValue(Reg) & 0xff; 342 } 343 344 // FIXME: This is very slow. It might be worth creating a map from physreg to 345 // register class. 346 const TargetRegisterClass *SIRegisterInfo::getPhysRegClass(unsigned Reg) const { 347 assert(!TargetRegisterInfo::isVirtualRegister(Reg)); 348 349 static const TargetRegisterClass *const BaseClasses[] = { 350 &AMDGPU::VGPR_32RegClass, 351 &AMDGPU::SReg_32RegClass, 352 &AMDGPU::VReg_64RegClass, 353 &AMDGPU::SReg_64RegClass, 354 &AMDGPU::VReg_96RegClass, 355 &AMDGPU::VReg_128RegClass, 356 &AMDGPU::SReg_128RegClass, 357 &AMDGPU::VReg_256RegClass, 358 &AMDGPU::SReg_256RegClass, 359 &AMDGPU::VReg_512RegClass, 360 &AMDGPU::SReg_512RegClass 361 }; 362 363 for (const TargetRegisterClass *BaseClass : BaseClasses) { 364 if (BaseClass->contains(Reg)) { 365 return BaseClass; 366 } 367 } 368 return nullptr; 369 } 370 371 // TODO: It might be helpful to have some target specific flags in 372 // TargetRegisterClass to mark which classes are VGPRs to make this trivial. 373 bool SIRegisterInfo::hasVGPRs(const TargetRegisterClass *RC) const { 374 switch (RC->getSize()) { 375 case 4: 376 return getCommonSubClass(&AMDGPU::VGPR_32RegClass, RC) != nullptr; 377 case 8: 378 return getCommonSubClass(&AMDGPU::VReg_64RegClass, RC) != nullptr; 379 case 12: 380 return getCommonSubClass(&AMDGPU::VReg_96RegClass, RC) != nullptr; 381 case 16: 382 return getCommonSubClass(&AMDGPU::VReg_128RegClass, RC) != nullptr; 383 case 32: 384 return getCommonSubClass(&AMDGPU::VReg_256RegClass, RC) != nullptr; 385 case 64: 386 return getCommonSubClass(&AMDGPU::VReg_512RegClass, RC) != nullptr; 387 default: 388 llvm_unreachable("Invalid register class size"); 389 } 390 } 391 392 const TargetRegisterClass *SIRegisterInfo::getEquivalentVGPRClass( 393 const TargetRegisterClass *SRC) const { 394 switch (SRC->getSize()) { 395 case 4: 396 return &AMDGPU::VGPR_32RegClass; 397 case 8: 398 return &AMDGPU::VReg_64RegClass; 399 case 12: 400 return &AMDGPU::VReg_96RegClass; 401 case 16: 402 return &AMDGPU::VReg_128RegClass; 403 case 32: 404 return &AMDGPU::VReg_256RegClass; 405 case 64: 406 return &AMDGPU::VReg_512RegClass; 407 default: 408 llvm_unreachable("Invalid register class size"); 409 } 410 } 411 412 const TargetRegisterClass *SIRegisterInfo::getSubRegClass( 413 const TargetRegisterClass *RC, unsigned SubIdx) const { 414 if (SubIdx == AMDGPU::NoSubRegister) 415 return RC; 416 417 // If this register has a sub-register, we can safely assume it is a 32-bit 418 // register, because all of SI's sub-registers are 32-bit. 419 if (isSGPRClass(RC)) { 420 return &AMDGPU::SGPR_32RegClass; 421 } else { 422 return &AMDGPU::VGPR_32RegClass; 423 } 424 } 425 426 bool SIRegisterInfo::shouldRewriteCopySrc( 427 const TargetRegisterClass *DefRC, 428 unsigned DefSubReg, 429 const TargetRegisterClass *SrcRC, 430 unsigned SrcSubReg) const { 431 // We want to prefer the smallest register class possible, so we don't want to 432 // stop and rewrite on anything that looks like a subregister 433 // extract. Operations mostly don't care about the super register class, so we 434 // only want to stop on the most basic of copies between the smae register 435 // class. 436 // 437 // e.g. if we have something like 438 // vreg0 = ... 439 // vreg1 = ... 440 // vreg2 = REG_SEQUENCE vreg0, sub0, vreg1, sub1, vreg2, sub2 441 // vreg3 = COPY vreg2, sub0 442 // 443 // We want to look through the COPY to find: 444 // => vreg3 = COPY vreg0 445 446 // Plain copy. 447 return getCommonSubClass(DefRC, SrcRC) != nullptr; 448 } 449 450 unsigned SIRegisterInfo::getPhysRegSubReg(unsigned Reg, 451 const TargetRegisterClass *SubRC, 452 unsigned Channel) const { 453 454 switch (Reg) { 455 case AMDGPU::VCC: 456 switch(Channel) { 457 case 0: return AMDGPU::VCC_LO; 458 case 1: return AMDGPU::VCC_HI; 459 default: llvm_unreachable("Invalid SubIdx for VCC"); 460 } 461 462 case AMDGPU::FLAT_SCR: 463 switch (Channel) { 464 case 0: 465 return AMDGPU::FLAT_SCR_LO; 466 case 1: 467 return AMDGPU::FLAT_SCR_HI; 468 default: 469 llvm_unreachable("Invalid SubIdx for FLAT_SCR"); 470 } 471 break; 472 473 case AMDGPU::EXEC: 474 switch (Channel) { 475 case 0: 476 return AMDGPU::EXEC_LO; 477 case 1: 478 return AMDGPU::EXEC_HI; 479 default: 480 llvm_unreachable("Invalid SubIdx for EXEC"); 481 } 482 break; 483 } 484 485 const TargetRegisterClass *RC = getPhysRegClass(Reg); 486 // 32-bit registers don't have sub-registers, so we can just return the 487 // Reg. We need to have this check here, because the calculation below 488 // using getHWRegIndex() will fail with special 32-bit registers like 489 // VCC_LO, VCC_HI, EXEC_LO, EXEC_HI and M0. 490 if (RC->getSize() == 4) { 491 assert(Channel == 0); 492 return Reg; 493 } 494 495 unsigned Index = getHWRegIndex(Reg); 496 return SubRC->getRegister(Index + Channel); 497 } 498 499 bool SIRegisterInfo::opCanUseLiteralConstant(unsigned OpType) const { 500 return OpType == AMDGPU::OPERAND_REG_IMM32; 501 } 502 503 bool SIRegisterInfo::opCanUseInlineConstant(unsigned OpType) const { 504 if (opCanUseLiteralConstant(OpType)) 505 return true; 506 507 return OpType == AMDGPU::OPERAND_REG_INLINE_C; 508 } 509 510 unsigned SIRegisterInfo::getPreloadedValue(const MachineFunction &MF, 511 enum PreloadedValue Value) const { 512 513 const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>(); 514 switch (Value) { 515 case SIRegisterInfo::TGID_X: 516 return AMDGPU::SReg_32RegClass.getRegister(MFI->NumUserSGPRs + 0); 517 case SIRegisterInfo::TGID_Y: 518 return AMDGPU::SReg_32RegClass.getRegister(MFI->NumUserSGPRs + 1); 519 case SIRegisterInfo::TGID_Z: 520 return AMDGPU::SReg_32RegClass.getRegister(MFI->NumUserSGPRs + 2); 521 case SIRegisterInfo::SCRATCH_WAVE_OFFSET: 522 if (MFI->getShaderType() != ShaderType::COMPUTE) 523 return MFI->ScratchOffsetReg; 524 return AMDGPU::SReg_32RegClass.getRegister(MFI->NumUserSGPRs + 4); 525 case SIRegisterInfo::SCRATCH_PTR: 526 return AMDGPU::SGPR2_SGPR3; 527 case SIRegisterInfo::INPUT_PTR: 528 return AMDGPU::SGPR0_SGPR1; 529 case SIRegisterInfo::TIDIG_X: 530 return AMDGPU::VGPR0; 531 case SIRegisterInfo::TIDIG_Y: 532 return AMDGPU::VGPR1; 533 case SIRegisterInfo::TIDIG_Z: 534 return AMDGPU::VGPR2; 535 } 536 llvm_unreachable("unexpected preloaded value type"); 537 } 538 539 /// \brief Returns a register that is not used at any point in the function. 540 /// If all registers are used, then this function will return 541 // AMDGPU::NoRegister. 542 unsigned SIRegisterInfo::findUnusedRegister(const MachineRegisterInfo &MRI, 543 const TargetRegisterClass *RC) const { 544 for (unsigned Reg : *RC) 545 if (!MRI.isPhysRegUsed(Reg)) 546 return Reg; 547 return AMDGPU::NoRegister; 548 } 549 550 unsigned SIRegisterInfo::getNumVGPRsAllowed(unsigned WaveCount) const { 551 switch(WaveCount) { 552 case 10: return 24; 553 case 9: return 28; 554 case 8: return 32; 555 case 7: return 36; 556 case 6: return 40; 557 case 5: return 48; 558 case 4: return 64; 559 case 3: return 84; 560 case 2: return 128; 561 default: return 256; 562 } 563 } 564 565 unsigned SIRegisterInfo::getNumSGPRsAllowed(AMDGPUSubtarget::Generation gen, 566 unsigned WaveCount) const { 567 if (gen >= AMDGPUSubtarget::VOLCANIC_ISLANDS) { 568 switch (WaveCount) { 569 case 10: return 80; 570 case 9: return 80; 571 case 8: return 96; 572 default: return 102; 573 } 574 } else { 575 switch(WaveCount) { 576 case 10: return 48; 577 case 9: return 56; 578 case 8: return 64; 579 case 7: return 72; 580 case 6: return 80; 581 case 5: return 96; 582 default: return 103; 583 } 584 } 585 } 586