AMDGPU: Shift down reserved SP register like scratch wave offset

llvm-svn: 301367
This commit is contained in:
Matt Arsenault 2017-04-25 23:40:57 +00:00
parent 7a8317c09a
commit 36c3122ecd
2 changed files with 59 additions and 17 deletions

View File

@ -143,7 +143,10 @@ unsigned SIFrameLowering::getReservedPrivateSegmentBufferReg(
return ScratchRsrcReg;
}
unsigned SIFrameLowering::getReservedPrivateSegmentWaveByteOffsetReg(
// Shift down registers reserved for the scratch wave offset and stack pointer
// SGPRs.
std::pair<unsigned, unsigned>
SIFrameLowering::getReservedPrivateSegmentWaveByteOffsetReg(
const SISubtarget &ST,
const SIInstrInfo *TII,
const SIRegisterInfo *TRI,
@ -154,18 +157,20 @@ unsigned SIFrameLowering::getReservedPrivateSegmentWaveByteOffsetReg(
// No replacement necessary.
if (ScratchWaveOffsetReg == AMDGPU::NoRegister ||
!MRI.isPhysRegUsed(ScratchWaveOffsetReg))
return AMDGPU::NoRegister;
!MRI.isPhysRegUsed(ScratchWaveOffsetReg)) {
assert(MFI->getStackPtrOffsetReg() == AMDGPU::NoRegister);
return std::make_pair(AMDGPU::NoRegister, AMDGPU::NoRegister);
}
if (ST.hasSGPRInitBug() ||
ScratchWaveOffsetReg != TRI->reservedPrivateSegmentWaveByteOffsetReg(MF))
return ScratchWaveOffsetReg;
unsigned SPReg = MFI->getStackPtrOffsetReg();
if (ST.hasSGPRInitBug())
return std::make_pair(ScratchWaveOffsetReg, SPReg);
unsigned NumPreloaded = MFI->getNumPreloadedSGPRs();
ArrayRef<MCPhysReg> AllSGPRs = getAllSGPRs(ST, MF);
if (NumPreloaded > AllSGPRs.size())
return ScratchWaveOffsetReg;
return std::make_pair(ScratchWaveOffsetReg, SPReg);
AllSGPRs = AllSGPRs.slice(NumPreloaded);
@ -180,22 +185,42 @@ unsigned SIFrameLowering::getReservedPrivateSegmentWaveByteOffsetReg(
// register from the list to consider, it means that when this
// register is being used for the scratch wave offset and there
// are no other free SGPRs, then the value will stay in this register.
// + 1 if stack pointer is used.
// ----
// 13
if (AllSGPRs.size() < 13)
return ScratchWaveOffsetReg;
// 13 (+1)
unsigned ReservedRegCount = 13;
if (SPReg != AMDGPU::NoRegister)
++ReservedRegCount;
for (MCPhysReg Reg : AllSGPRs.drop_back(13)) {
if (AllSGPRs.size() < ReservedRegCount)
return std::make_pair(ScratchWaveOffsetReg, SPReg);
bool HandledScratchWaveOffsetReg =
ScratchWaveOffsetReg != TRI->reservedPrivateSegmentWaveByteOffsetReg(MF);
for (MCPhysReg Reg : AllSGPRs.drop_back(ReservedRegCount)) {
// Pick the first unallocated SGPR. Be careful not to pick an alias of the
// scratch descriptor, since we havent added its uses yet.
if (!MRI.isPhysRegUsed(Reg) && MRI.isAllocatable(Reg)) {
MRI.replaceRegWith(ScratchWaveOffsetReg, Reg);
MFI->setScratchWaveOffsetReg(Reg);
return Reg;
if (!HandledScratchWaveOffsetReg) {
HandledScratchWaveOffsetReg = true;
MRI.replaceRegWith(ScratchWaveOffsetReg, Reg);
MFI->setScratchWaveOffsetReg(Reg);
ScratchWaveOffsetReg = Reg;
} else {
if (SPReg == AMDGPU::NoRegister)
break;
MRI.replaceRegWith(SPReg, Reg);
MFI->setStackPtrOffsetReg(Reg);
SPReg = Reg;
break;
}
}
}
return ScratchWaveOffsetReg;
return std::make_pair(ScratchWaveOffsetReg, SPReg);
}
void SIFrameLowering::emitPrologue(MachineFunction &MF,
@ -233,9 +258,26 @@ void SIFrameLowering::emitPrologue(MachineFunction &MF,
if (MF.getFrameInfo().hasStackObjects() && MFI->hasFlatScratchInit())
emitFlatScratchInit(ST, MF, MBB);
unsigned SPReg = MFI->getStackPtrOffsetReg();
if (SPReg != AMDGPU::NoRegister) {
DebugLoc DL;
int64_t StackSize = MF.getFrameInfo().getStackSize();
if (StackSize == 0) {
BuildMI(MBB, MBB.begin(), DL, TII->get(AMDGPU::COPY), SPReg)
.addReg(MFI->getScratchWaveOffsetReg());
} else {
BuildMI(MBB, MBB.begin(), DL, TII->get(AMDGPU::S_ADD_U32), SPReg)
.addReg(MFI->getScratchWaveOffsetReg())
.addImm(StackSize * ST.getWavefrontSize());
}
}
unsigned ScratchRsrcReg
= getReservedPrivateSegmentBufferReg(ST, TII, TRI, MFI, MF);
unsigned ScratchWaveOffsetReg
unsigned ScratchWaveOffsetReg;
std::tie(ScratchWaveOffsetReg, SPReg)
= getReservedPrivateSegmentWaveByteOffsetReg(ST, TII, TRI, MFI, MF);
// It's possible to have uses of only ScratchWaveOffsetReg without

View File

@ -49,7 +49,7 @@ private:
SIMachineFunctionInfo *MFI,
MachineFunction &MF) const;
unsigned getReservedPrivateSegmentWaveByteOffsetReg(
std::pair<unsigned, unsigned> getReservedPrivateSegmentWaveByteOffsetReg(
const SISubtarget &ST,
const SIInstrInfo *TII,
const SIRegisterInfo *TRI,