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