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 unsigned NumRegPressureSets = getNumRegPressureSets(); 28 29 SGPR32SetID = NumRegPressureSets; 30 VGPR32SetID = NumRegPressureSets; 31 for (unsigned i = 0; i < NumRegPressureSets; ++i) { 32 if (strncmp("SGPR_32", getRegPressureSetName(i), 7) == 0) 33 SGPR32SetID = i; 34 else if (strncmp("VGPR_32", getRegPressureSetName(i), 7) == 0) 35 VGPR32SetID = i; 36 } 37 assert(SGPR32SetID < NumRegPressureSets && 38 VGPR32SetID < NumRegPressureSets); 39 } 40 41 void SIRegisterInfo::reserveRegisterTuples(BitVector &Reserved, unsigned Reg) const { 42 MCRegAliasIterator R(Reg, this, true); 43 44 for (; R.isValid(); ++R) 45 Reserved.set(*R); 46 } 47 48 unsigned SIRegisterInfo::reservedPrivateSegmentBufferReg( 49 const MachineFunction &MF) const { 50 const AMDGPUSubtarget &ST = MF.getSubtarget<AMDGPUSubtarget>(); 51 if (ST.hasSGPRInitBug()) { 52 // Leave space for flat_scr, xnack_mask, vcc, and alignment 53 unsigned BaseIdx = AMDGPUSubtarget::FIXED_SGPR_COUNT_FOR_INIT_BUG - 8 - 4; 54 unsigned BaseReg(AMDGPU::SGPR_32RegClass.getRegister(BaseIdx)); 55 return getMatchingSuperReg(BaseReg, AMDGPU::sub0, &AMDGPU::SReg_128RegClass); 56 } 57 58 if (ST.getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS) { 59 // 96/97 need to be reserved for flat_scr, 98/99 for xnack_mask, and 60 // 100/101 for vcc. This is the next sgpr128 down. 61 return AMDGPU::SGPR92_SGPR93_SGPR94_SGPR95; 62 } 63 64 return AMDGPU::SGPR96_SGPR97_SGPR98_SGPR99; 65 } 66 67 unsigned SIRegisterInfo::reservedPrivateSegmentWaveByteOffsetReg( 68 const MachineFunction &MF) const { 69 const AMDGPUSubtarget &ST = MF.getSubtarget<AMDGPUSubtarget>(); 70 if (ST.hasSGPRInitBug()) { 71 unsigned Idx = AMDGPUSubtarget::FIXED_SGPR_COUNT_FOR_INIT_BUG - 6 - 1; 72 return AMDGPU::SGPR_32RegClass.getRegister(Idx); 73 } 74 75 if (ST.getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS) { 76 // Next register before reservations for flat_scr, xnack_mask, vcc, 77 // and scratch resource. 78 return AMDGPU::SGPR91; 79 } 80 81 return AMDGPU::SGPR95; 82 } 83 84 BitVector SIRegisterInfo::getReservedRegs(const MachineFunction &MF) const { 85 BitVector Reserved(getNumRegs()); 86 Reserved.set(AMDGPU::INDIRECT_BASE_ADDR); 87 88 // EXEC_LO and EXEC_HI could be allocated and used as regular register, but 89 // this seems likely to result in bugs, so I'm marking them as reserved. 90 reserveRegisterTuples(Reserved, AMDGPU::EXEC); 91 reserveRegisterTuples(Reserved, AMDGPU::FLAT_SCR); 92 93 // Reserve the last 2 registers so we will always have at least 2 more that 94 // will physically contain VCC. 95 reserveRegisterTuples(Reserved, AMDGPU::SGPR102_SGPR103); 96 97 const AMDGPUSubtarget &ST = MF.getSubtarget<AMDGPUSubtarget>(); 98 99 if (ST.getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS) { 100 // SI/CI have 104 SGPRs. VI has 102. We need to shift down the reservation 101 // for VCC/XNACK_MASK/FLAT_SCR. 102 // 103 // TODO The SGPRs that alias to XNACK_MASK could be used as general purpose 104 // SGPRs when the XNACK feature is not used. This is currently not done 105 // because the code that counts SGPRs cannot account for such holes. 106 reserveRegisterTuples(Reserved, AMDGPU::SGPR96_SGPR97); 107 reserveRegisterTuples(Reserved, AMDGPU::SGPR98_SGPR99); 108 reserveRegisterTuples(Reserved, AMDGPU::SGPR100_SGPR101); 109 } 110 111 // Tonga and Iceland can only allocate a fixed number of SGPRs due 112 // to a hw bug. 113 if (ST.hasSGPRInitBug()) { 114 unsigned NumSGPRs = AMDGPU::SGPR_32RegClass.getNumRegs(); 115 // Reserve some SGPRs for FLAT_SCRATCH, XNACK_MASK, and VCC (6 SGPRs). 116 unsigned Limit = AMDGPUSubtarget::FIXED_SGPR_COUNT_FOR_INIT_BUG - 6; 117 118 for (unsigned i = Limit; i < NumSGPRs; ++i) { 119 unsigned Reg = AMDGPU::SGPR_32RegClass.getRegister(i); 120 reserveRegisterTuples(Reserved, Reg); 121 } 122 } 123 124 const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>(); 125 126 unsigned ScratchWaveOffsetReg = MFI->getScratchWaveOffsetReg(); 127 if (ScratchWaveOffsetReg != AMDGPU::NoRegister) { 128 // Reserve 1 SGPR for scratch wave offset in case we need to spill. 129 reserveRegisterTuples(Reserved, ScratchWaveOffsetReg); 130 } 131 132 unsigned ScratchRSrcReg = MFI->getScratchRSrcReg(); 133 if (ScratchRSrcReg != AMDGPU::NoRegister) { 134 // Reserve 4 SGPRs for the scratch buffer resource descriptor in case we need 135 // to spill. 136 // TODO: May need to reserve a VGPR if doing LDS spilling. 137 reserveRegisterTuples(Reserved, ScratchRSrcReg); 138 assert(!isSubRegister(ScratchRSrcReg, ScratchWaveOffsetReg)); 139 } 140 141 return Reserved; 142 } 143 144 unsigned SIRegisterInfo::getRegPressureSetLimit(const MachineFunction &MF, 145 unsigned Idx) const { 146 const AMDGPUSubtarget &STI = MF.getSubtarget<AMDGPUSubtarget>(); 147 // FIXME: We should adjust the max number of waves based on LDS size. 148 unsigned SGPRLimit = getNumSGPRsAllowed(STI.getGeneration(), 149 STI.getMaxWavesPerCU()); 150 unsigned VGPRLimit = getNumVGPRsAllowed(STI.getMaxWavesPerCU()); 151 152 unsigned VSLimit = SGPRLimit + VGPRLimit; 153 154 for (regclass_iterator I = regclass_begin(), E = regclass_end(); 155 I != E; ++I) { 156 const TargetRegisterClass *RC = *I; 157 158 unsigned NumSubRegs = std::max((int)RC->getSize() / 4, 1); 159 unsigned Limit; 160 161 if (isPseudoRegClass(RC)) { 162 // FIXME: This is a hack. We should never be considering the pressure of 163 // these since no virtual register should ever have this class. 164 Limit = VSLimit; 165 } else if (isSGPRClass(RC)) { 166 Limit = SGPRLimit / NumSubRegs; 167 } else { 168 Limit = VGPRLimit / NumSubRegs; 169 } 170 171 const int *Sets = getRegClassPressureSets(RC); 172 assert(Sets); 173 for (unsigned i = 0; Sets[i] != -1; ++i) { 174 if (Sets[i] == (int)Idx) 175 return Limit; 176 } 177 } 178 return 256; 179 } 180 181 bool SIRegisterInfo::requiresRegisterScavenging(const MachineFunction &Fn) const { 182 return Fn.getFrameInfo()->hasStackObjects(); 183 } 184 185 static unsigned getNumSubRegsForSpillOp(unsigned Op) { 186 187 switch (Op) { 188 case AMDGPU::SI_SPILL_S512_SAVE: 189 case AMDGPU::SI_SPILL_S512_RESTORE: 190 case AMDGPU::SI_SPILL_V512_SAVE: 191 case AMDGPU::SI_SPILL_V512_RESTORE: 192 return 16; 193 case AMDGPU::SI_SPILL_S256_SAVE: 194 case AMDGPU::SI_SPILL_S256_RESTORE: 195 case AMDGPU::SI_SPILL_V256_SAVE: 196 case AMDGPU::SI_SPILL_V256_RESTORE: 197 return 8; 198 case AMDGPU::SI_SPILL_S128_SAVE: 199 case AMDGPU::SI_SPILL_S128_RESTORE: 200 case AMDGPU::SI_SPILL_V128_SAVE: 201 case AMDGPU::SI_SPILL_V128_RESTORE: 202 return 4; 203 case AMDGPU::SI_SPILL_V96_SAVE: 204 case AMDGPU::SI_SPILL_V96_RESTORE: 205 return 3; 206 case AMDGPU::SI_SPILL_S64_SAVE: 207 case AMDGPU::SI_SPILL_S64_RESTORE: 208 case AMDGPU::SI_SPILL_V64_SAVE: 209 case AMDGPU::SI_SPILL_V64_RESTORE: 210 return 2; 211 case AMDGPU::SI_SPILL_S32_SAVE: 212 case AMDGPU::SI_SPILL_S32_RESTORE: 213 case AMDGPU::SI_SPILL_V32_SAVE: 214 case AMDGPU::SI_SPILL_V32_RESTORE: 215 return 1; 216 default: llvm_unreachable("Invalid spill opcode"); 217 } 218 } 219 220 void SIRegisterInfo::buildScratchLoadStore(MachineBasicBlock::iterator MI, 221 unsigned LoadStoreOp, 222 unsigned Value, 223 unsigned ScratchRsrcReg, 224 unsigned ScratchOffset, 225 int64_t Offset, 226 RegScavenger *RS) const { 227 228 MachineBasicBlock *MBB = MI->getParent(); 229 const MachineFunction *MF = MI->getParent()->getParent(); 230 const SIInstrInfo *TII = 231 static_cast<const SIInstrInfo *>(MF->getSubtarget().getInstrInfo()); 232 LLVMContext &Ctx = MF->getFunction()->getContext(); 233 DebugLoc DL = MI->getDebugLoc(); 234 bool IsLoad = TII->get(LoadStoreOp).mayLoad(); 235 236 bool RanOutOfSGPRs = false; 237 unsigned SOffset = ScratchOffset; 238 239 unsigned NumSubRegs = getNumSubRegsForSpillOp(MI->getOpcode()); 240 unsigned Size = NumSubRegs * 4; 241 242 if (!isUInt<12>(Offset + Size)) { 243 SOffset = RS->scavengeRegister(&AMDGPU::SGPR_32RegClass, MI, 0); 244 if (SOffset == AMDGPU::NoRegister) { 245 RanOutOfSGPRs = true; 246 SOffset = AMDGPU::SGPR0; 247 } 248 BuildMI(*MBB, MI, DL, TII->get(AMDGPU::S_ADD_U32), SOffset) 249 .addReg(ScratchOffset) 250 .addImm(Offset); 251 Offset = 0; 252 } 253 254 if (RanOutOfSGPRs) 255 Ctx.emitError("Ran out of SGPRs for spilling VGPRS"); 256 257 for (unsigned i = 0, e = NumSubRegs; i != e; ++i, Offset += 4) { 258 unsigned SubReg = NumSubRegs > 1 ? 259 getPhysRegSubReg(Value, &AMDGPU::VGPR_32RegClass, i) : 260 Value; 261 262 BuildMI(*MBB, MI, DL, TII->get(LoadStoreOp)) 263 .addReg(SubReg, getDefRegState(IsLoad)) 264 .addReg(ScratchRsrcReg) 265 .addReg(SOffset) 266 .addImm(Offset) 267 .addImm(0) // glc 268 .addImm(0) // slc 269 .addImm(0) // tfe 270 .addReg(Value, RegState::Implicit | getDefRegState(IsLoad)) 271 .setMemRefs(MI->memoperands_begin(), MI->memoperands_end()); 272 } 273 } 274 275 void SIRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI, 276 int SPAdj, unsigned FIOperandNum, 277 RegScavenger *RS) const { 278 MachineFunction *MF = MI->getParent()->getParent(); 279 MachineBasicBlock *MBB = MI->getParent(); 280 SIMachineFunctionInfo *MFI = MF->getInfo<SIMachineFunctionInfo>(); 281 MachineFrameInfo *FrameInfo = MF->getFrameInfo(); 282 const SIInstrInfo *TII = 283 static_cast<const SIInstrInfo *>(MF->getSubtarget().getInstrInfo()); 284 DebugLoc DL = MI->getDebugLoc(); 285 286 MachineOperand &FIOp = MI->getOperand(FIOperandNum); 287 int Index = MI->getOperand(FIOperandNum).getIndex(); 288 289 switch (MI->getOpcode()) { 290 // SGPR register spill 291 case AMDGPU::SI_SPILL_S512_SAVE: 292 case AMDGPU::SI_SPILL_S256_SAVE: 293 case AMDGPU::SI_SPILL_S128_SAVE: 294 case AMDGPU::SI_SPILL_S64_SAVE: 295 case AMDGPU::SI_SPILL_S32_SAVE: { 296 unsigned NumSubRegs = getNumSubRegsForSpillOp(MI->getOpcode()); 297 298 for (unsigned i = 0, e = NumSubRegs; i < e; ++i) { 299 unsigned SubReg = getPhysRegSubReg(MI->getOperand(0).getReg(), 300 &AMDGPU::SGPR_32RegClass, i); 301 struct SIMachineFunctionInfo::SpilledReg Spill = 302 MFI->getSpilledReg(MF, Index, i); 303 304 BuildMI(*MBB, MI, DL, 305 TII->getMCOpcodeFromPseudo(AMDGPU::V_WRITELANE_B32), 306 Spill.VGPR) 307 .addReg(SubReg) 308 .addImm(Spill.Lane); 309 310 // FIXME: Since this spills to another register instead of an actual 311 // frame index, we should delete the frame index when all references to 312 // it are fixed. 313 } 314 MI->eraseFromParent(); 315 break; 316 } 317 318 // SGPR register restore 319 case AMDGPU::SI_SPILL_S512_RESTORE: 320 case AMDGPU::SI_SPILL_S256_RESTORE: 321 case AMDGPU::SI_SPILL_S128_RESTORE: 322 case AMDGPU::SI_SPILL_S64_RESTORE: 323 case AMDGPU::SI_SPILL_S32_RESTORE: { 324 unsigned NumSubRegs = getNumSubRegsForSpillOp(MI->getOpcode()); 325 326 for (unsigned i = 0, e = NumSubRegs; i < e; ++i) { 327 unsigned SubReg = getPhysRegSubReg(MI->getOperand(0).getReg(), 328 &AMDGPU::SGPR_32RegClass, i); 329 struct SIMachineFunctionInfo::SpilledReg Spill = 330 MFI->getSpilledReg(MF, Index, i); 331 332 BuildMI(*MBB, MI, DL, 333 TII->getMCOpcodeFromPseudo(AMDGPU::V_READLANE_B32), 334 SubReg) 335 .addReg(Spill.VGPR) 336 .addImm(Spill.Lane) 337 .addReg(MI->getOperand(0).getReg(), RegState::ImplicitDefine); 338 } 339 340 // TODO: only do this when it is needed 341 switch (MF->getSubtarget<AMDGPUSubtarget>().getGeneration()) { 342 case AMDGPUSubtarget::SOUTHERN_ISLANDS: 343 // "VALU writes SGPR" -> "SMRD reads that SGPR" needs 4 wait states 344 // ("S_NOP 3") on SI 345 TII->insertWaitStates(MI, 4); 346 break; 347 case AMDGPUSubtarget::SEA_ISLANDS: 348 break; 349 default: // VOLCANIC_ISLANDS and later 350 // "VALU writes SGPR -> VMEM reads that SGPR" needs 5 wait states 351 // ("S_NOP 4") on VI and later. This also applies to VALUs which write 352 // VCC, but we're unlikely to see VMEM use VCC. 353 TII->insertWaitStates(MI, 5); 354 } 355 356 MI->eraseFromParent(); 357 break; 358 } 359 360 // VGPR register spill 361 case AMDGPU::SI_SPILL_V512_SAVE: 362 case AMDGPU::SI_SPILL_V256_SAVE: 363 case AMDGPU::SI_SPILL_V128_SAVE: 364 case AMDGPU::SI_SPILL_V96_SAVE: 365 case AMDGPU::SI_SPILL_V64_SAVE: 366 case AMDGPU::SI_SPILL_V32_SAVE: 367 buildScratchLoadStore(MI, AMDGPU::BUFFER_STORE_DWORD_OFFSET, 368 TII->getNamedOperand(*MI, AMDGPU::OpName::src)->getReg(), 369 TII->getNamedOperand(*MI, AMDGPU::OpName::scratch_rsrc)->getReg(), 370 TII->getNamedOperand(*MI, AMDGPU::OpName::scratch_offset)->getReg(), 371 FrameInfo->getObjectOffset(Index), RS); 372 MI->eraseFromParent(); 373 break; 374 case AMDGPU::SI_SPILL_V32_RESTORE: 375 case AMDGPU::SI_SPILL_V64_RESTORE: 376 case AMDGPU::SI_SPILL_V96_RESTORE: 377 case AMDGPU::SI_SPILL_V128_RESTORE: 378 case AMDGPU::SI_SPILL_V256_RESTORE: 379 case AMDGPU::SI_SPILL_V512_RESTORE: { 380 buildScratchLoadStore(MI, AMDGPU::BUFFER_LOAD_DWORD_OFFSET, 381 TII->getNamedOperand(*MI, AMDGPU::OpName::dst)->getReg(), 382 TII->getNamedOperand(*MI, AMDGPU::OpName::scratch_rsrc)->getReg(), 383 TII->getNamedOperand(*MI, AMDGPU::OpName::scratch_offset)->getReg(), 384 FrameInfo->getObjectOffset(Index), RS); 385 MI->eraseFromParent(); 386 break; 387 } 388 389 default: { 390 int64_t Offset = FrameInfo->getObjectOffset(Index); 391 FIOp.ChangeToImmediate(Offset); 392 if (!TII->isImmOperandLegal(MI, FIOperandNum, FIOp)) { 393 unsigned TmpReg = RS->scavengeRegister(&AMDGPU::VGPR_32RegClass, MI, SPAdj); 394 BuildMI(*MBB, MI, MI->getDebugLoc(), 395 TII->get(AMDGPU::V_MOV_B32_e32), TmpReg) 396 .addImm(Offset); 397 FIOp.ChangeToRegister(TmpReg, false, false, true); 398 } 399 } 400 } 401 } 402 403 unsigned SIRegisterInfo::getHWRegIndex(unsigned Reg) const { 404 return getEncodingValue(Reg) & 0xff; 405 } 406 407 // FIXME: This is very slow. It might be worth creating a map from physreg to 408 // register class. 409 const TargetRegisterClass *SIRegisterInfo::getPhysRegClass(unsigned Reg) const { 410 assert(!TargetRegisterInfo::isVirtualRegister(Reg)); 411 412 static const TargetRegisterClass *const BaseClasses[] = { 413 &AMDGPU::VGPR_32RegClass, 414 &AMDGPU::SReg_32RegClass, 415 &AMDGPU::VReg_64RegClass, 416 &AMDGPU::SReg_64RegClass, 417 &AMDGPU::VReg_96RegClass, 418 &AMDGPU::VReg_128RegClass, 419 &AMDGPU::SReg_128RegClass, 420 &AMDGPU::VReg_256RegClass, 421 &AMDGPU::SReg_256RegClass, 422 &AMDGPU::VReg_512RegClass, 423 &AMDGPU::SReg_512RegClass 424 }; 425 426 for (const TargetRegisterClass *BaseClass : BaseClasses) { 427 if (BaseClass->contains(Reg)) { 428 return BaseClass; 429 } 430 } 431 return nullptr; 432 } 433 434 // TODO: It might be helpful to have some target specific flags in 435 // TargetRegisterClass to mark which classes are VGPRs to make this trivial. 436 bool SIRegisterInfo::hasVGPRs(const TargetRegisterClass *RC) const { 437 switch (RC->getSize()) { 438 case 4: 439 return getCommonSubClass(&AMDGPU::VGPR_32RegClass, RC) != nullptr; 440 case 8: 441 return getCommonSubClass(&AMDGPU::VReg_64RegClass, RC) != nullptr; 442 case 12: 443 return getCommonSubClass(&AMDGPU::VReg_96RegClass, RC) != nullptr; 444 case 16: 445 return getCommonSubClass(&AMDGPU::VReg_128RegClass, RC) != nullptr; 446 case 32: 447 return getCommonSubClass(&AMDGPU::VReg_256RegClass, RC) != nullptr; 448 case 64: 449 return getCommonSubClass(&AMDGPU::VReg_512RegClass, RC) != nullptr; 450 default: 451 llvm_unreachable("Invalid register class size"); 452 } 453 } 454 455 const TargetRegisterClass *SIRegisterInfo::getEquivalentVGPRClass( 456 const TargetRegisterClass *SRC) const { 457 switch (SRC->getSize()) { 458 case 4: 459 return &AMDGPU::VGPR_32RegClass; 460 case 8: 461 return &AMDGPU::VReg_64RegClass; 462 case 12: 463 return &AMDGPU::VReg_96RegClass; 464 case 16: 465 return &AMDGPU::VReg_128RegClass; 466 case 32: 467 return &AMDGPU::VReg_256RegClass; 468 case 64: 469 return &AMDGPU::VReg_512RegClass; 470 default: 471 llvm_unreachable("Invalid register class size"); 472 } 473 } 474 475 const TargetRegisterClass *SIRegisterInfo::getSubRegClass( 476 const TargetRegisterClass *RC, unsigned SubIdx) const { 477 if (SubIdx == AMDGPU::NoSubRegister) 478 return RC; 479 480 // We can assume that each lane corresponds to one 32-bit register. 481 unsigned Count = countPopulation(getSubRegIndexLaneMask(SubIdx)); 482 if (isSGPRClass(RC)) { 483 switch (Count) { 484 case 1: 485 return &AMDGPU::SGPR_32RegClass; 486 case 2: 487 return &AMDGPU::SReg_64RegClass; 488 case 4: 489 return &AMDGPU::SReg_128RegClass; 490 case 8: 491 return &AMDGPU::SReg_256RegClass; 492 case 16: /* fall-through */ 493 default: 494 llvm_unreachable("Invalid sub-register class size"); 495 } 496 } else { 497 switch (Count) { 498 case 1: 499 return &AMDGPU::VGPR_32RegClass; 500 case 2: 501 return &AMDGPU::VReg_64RegClass; 502 case 3: 503 return &AMDGPU::VReg_96RegClass; 504 case 4: 505 return &AMDGPU::VReg_128RegClass; 506 case 8: 507 return &AMDGPU::VReg_256RegClass; 508 case 16: /* fall-through */ 509 default: 510 llvm_unreachable("Invalid sub-register class size"); 511 } 512 } 513 } 514 515 bool SIRegisterInfo::shouldRewriteCopySrc( 516 const TargetRegisterClass *DefRC, 517 unsigned DefSubReg, 518 const TargetRegisterClass *SrcRC, 519 unsigned SrcSubReg) const { 520 // We want to prefer the smallest register class possible, so we don't want to 521 // stop and rewrite on anything that looks like a subregister 522 // extract. Operations mostly don't care about the super register class, so we 523 // only want to stop on the most basic of copies between the smae register 524 // class. 525 // 526 // e.g. if we have something like 527 // vreg0 = ... 528 // vreg1 = ... 529 // vreg2 = REG_SEQUENCE vreg0, sub0, vreg1, sub1, vreg2, sub2 530 // vreg3 = COPY vreg2, sub0 531 // 532 // We want to look through the COPY to find: 533 // => vreg3 = COPY vreg0 534 535 // Plain copy. 536 return getCommonSubClass(DefRC, SrcRC) != nullptr; 537 } 538 539 unsigned SIRegisterInfo::getPhysRegSubReg(unsigned Reg, 540 const TargetRegisterClass *SubRC, 541 unsigned Channel) const { 542 543 switch (Reg) { 544 case AMDGPU::VCC: 545 switch(Channel) { 546 case 0: return AMDGPU::VCC_LO; 547 case 1: return AMDGPU::VCC_HI; 548 default: llvm_unreachable("Invalid SubIdx for VCC"); 549 } 550 551 case AMDGPU::FLAT_SCR: 552 switch (Channel) { 553 case 0: 554 return AMDGPU::FLAT_SCR_LO; 555 case 1: 556 return AMDGPU::FLAT_SCR_HI; 557 default: 558 llvm_unreachable("Invalid SubIdx for FLAT_SCR"); 559 } 560 break; 561 562 case AMDGPU::EXEC: 563 switch (Channel) { 564 case 0: 565 return AMDGPU::EXEC_LO; 566 case 1: 567 return AMDGPU::EXEC_HI; 568 default: 569 llvm_unreachable("Invalid SubIdx for EXEC"); 570 } 571 break; 572 } 573 574 const TargetRegisterClass *RC = getPhysRegClass(Reg); 575 // 32-bit registers don't have sub-registers, so we can just return the 576 // Reg. We need to have this check here, because the calculation below 577 // using getHWRegIndex() will fail with special 32-bit registers like 578 // VCC_LO, VCC_HI, EXEC_LO, EXEC_HI and M0. 579 if (RC->getSize() == 4) { 580 assert(Channel == 0); 581 return Reg; 582 } 583 584 unsigned Index = getHWRegIndex(Reg); 585 return SubRC->getRegister(Index + Channel); 586 } 587 588 bool SIRegisterInfo::opCanUseLiteralConstant(unsigned OpType) const { 589 return OpType == AMDGPU::OPERAND_REG_IMM32; 590 } 591 592 bool SIRegisterInfo::opCanUseInlineConstant(unsigned OpType) const { 593 if (opCanUseLiteralConstant(OpType)) 594 return true; 595 596 return OpType == AMDGPU::OPERAND_REG_INLINE_C; 597 } 598 599 // FIXME: Most of these are flexible with HSA and we don't need to reserve them 600 // as input registers if unused. Whether the dispatch ptr is necessary should be 601 // easy to detect from used intrinsics. Scratch setup is harder to know. 602 unsigned SIRegisterInfo::getPreloadedValue(const MachineFunction &MF, 603 enum PreloadedValue Value) const { 604 605 const SIMachineFunctionInfo *MFI = MF.getInfo<SIMachineFunctionInfo>(); 606 const AMDGPUSubtarget &ST = MF.getSubtarget<AMDGPUSubtarget>(); 607 (void)ST; 608 switch (Value) { 609 case SIRegisterInfo::WORKGROUP_ID_X: 610 assert(MFI->hasWorkGroupIDX()); 611 return MFI->WorkGroupIDXSystemSGPR; 612 case SIRegisterInfo::WORKGROUP_ID_Y: 613 assert(MFI->hasWorkGroupIDY()); 614 return MFI->WorkGroupIDYSystemSGPR; 615 case SIRegisterInfo::WORKGROUP_ID_Z: 616 assert(MFI->hasWorkGroupIDZ()); 617 return MFI->WorkGroupIDZSystemSGPR; 618 case SIRegisterInfo::PRIVATE_SEGMENT_WAVE_BYTE_OFFSET: 619 return MFI->PrivateSegmentWaveByteOffsetSystemSGPR; 620 case SIRegisterInfo::PRIVATE_SEGMENT_BUFFER: 621 assert(ST.isAmdHsaOS() && "Non-HSA ABI currently uses relocations"); 622 assert(MFI->hasPrivateSegmentBuffer()); 623 return MFI->PrivateSegmentBufferUserSGPR; 624 case SIRegisterInfo::KERNARG_SEGMENT_PTR: 625 assert(MFI->hasKernargSegmentPtr()); 626 return MFI->KernargSegmentPtrUserSGPR; 627 case SIRegisterInfo::DISPATCH_PTR: 628 assert(MFI->hasDispatchPtr()); 629 return MFI->DispatchPtrUserSGPR; 630 case SIRegisterInfo::QUEUE_PTR: 631 llvm_unreachable("not implemented"); 632 case SIRegisterInfo::WORKITEM_ID_X: 633 assert(MFI->hasWorkItemIDX()); 634 return AMDGPU::VGPR0; 635 case SIRegisterInfo::WORKITEM_ID_Y: 636 assert(MFI->hasWorkItemIDY()); 637 return AMDGPU::VGPR1; 638 case SIRegisterInfo::WORKITEM_ID_Z: 639 assert(MFI->hasWorkItemIDZ()); 640 return AMDGPU::VGPR2; 641 } 642 llvm_unreachable("unexpected preloaded value type"); 643 } 644 645 /// \brief Returns a register that is not used at any point in the function. 646 /// If all registers are used, then this function will return 647 // AMDGPU::NoRegister. 648 unsigned SIRegisterInfo::findUnusedRegister(const MachineRegisterInfo &MRI, 649 const TargetRegisterClass *RC) const { 650 for (unsigned Reg : *RC) 651 if (!MRI.isPhysRegUsed(Reg)) 652 return Reg; 653 return AMDGPU::NoRegister; 654 } 655 656 unsigned SIRegisterInfo::getNumVGPRsAllowed(unsigned WaveCount) const { 657 switch(WaveCount) { 658 case 10: return 24; 659 case 9: return 28; 660 case 8: return 32; 661 case 7: return 36; 662 case 6: return 40; 663 case 5: return 48; 664 case 4: return 64; 665 case 3: return 84; 666 case 2: return 128; 667 default: return 256; 668 } 669 } 670 671 unsigned SIRegisterInfo::getNumSGPRsAllowed(AMDGPUSubtarget::Generation gen, 672 unsigned WaveCount) const { 673 if (gen >= AMDGPUSubtarget::VOLCANIC_ISLANDS) { 674 switch (WaveCount) { 675 case 10: return 80; 676 case 9: return 80; 677 case 8: return 96; 678 default: return 102; 679 } 680 } else { 681 switch(WaveCount) { 682 case 10: return 48; 683 case 9: return 56; 684 case 8: return 64; 685 case 7: return 72; 686 case 6: return 80; 687 case 5: return 96; 688 default: return 103; 689 } 690 } 691 } 692