summaryrefslogtreecommitdiff
path: root/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/AMDGPU/SIInstrInfo.cpp')
-rw-r--r--llvm/lib/Target/AMDGPU/SIInstrInfo.cpp46
1 files changed, 26 insertions, 20 deletions
diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
index 00fd102240d2..e83ecc30c4ae 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
@@ -2223,15 +2223,17 @@ MachineBasicBlock *SIInstrInfo::getBranchDestBlock(
return MI.getOperand(0).getMBB();
}
-unsigned SIInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB,
- MachineBasicBlock &DestBB,
- const DebugLoc &DL,
- int64_t BrOffset,
- RegScavenger *RS) const {
+void SIInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB,
+ MachineBasicBlock &DestBB,
+ MachineBasicBlock &RestoreBB,
+ const DebugLoc &DL, int64_t BrOffset,
+ RegScavenger *RS) const {
assert(RS && "RegScavenger required for long branching");
assert(MBB.empty() &&
"new block should be inserted for expanding unconditional branch");
assert(MBB.pred_size() == 1);
+ assert(RestoreBB.empty() &&
+ "restore block should be inserted for restoring clobbered registers");
MachineFunction *MF = MBB.getParent();
MachineRegisterInfo &MRI = MF->getRegInfo();
@@ -2268,14 +2270,6 @@ unsigned SIInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB,
BuildMI(&MBB, DL, get(AMDGPU::S_SETPC_B64))
.addReg(PCReg);
- auto ComputeBlockSize = [](const TargetInstrInfo *TII,
- const MachineBasicBlock &MBB) {
- unsigned Size = 0;
- for (const MachineInstr &MI : MBB)
- Size += TII->getInstSizeInBytes(MI);
- return Size;
- };
-
// FIXME: If spilling is necessary, this will fail because this scavenger has
// no emergency stack slots. It is non-trivial to spill in this situation,
// because the restore code needs to be specially placed after the
@@ -2314,22 +2308,34 @@ unsigned SIInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB,
RS->enterBasicBlockEnd(MBB);
Register Scav = RS->scavengeRegisterBackwards(
- AMDGPU::SReg_64RegClass,
- MachineBasicBlock::iterator(GetPC), false, 0);
- MRI.replaceRegWith(PCReg, Scav);
- MRI.clearVirtRegs();
- RS->setRegUsed(Scav);
+ AMDGPU::SReg_64RegClass, MachineBasicBlock::iterator(GetPC),
+ /* RestoreAfter */ false, 0, /* AllowSpill */ false);
+ if (Scav) {
+ RS->setRegUsed(Scav);
+ MRI.replaceRegWith(PCReg, Scav);
+ MRI.clearVirtRegs();
+ } else {
+ // As SGPR needs VGPR to be spilled, we reuse the slot of temporary VGPR for
+ // SGPR spill.
+ const GCNSubtarget &ST = MF->getSubtarget<GCNSubtarget>();
+ const SIRegisterInfo *TRI = ST.getRegisterInfo();
+ TRI->spillEmergencySGPR(GetPC, RestoreBB, AMDGPU::SGPR0_SGPR1, RS);
+ MRI.replaceRegWith(PCReg, AMDGPU::SGPR0_SGPR1);
+ MRI.clearVirtRegs();
+ }
+ MCSymbol *DestLabel = Scav ? DestBB.getSymbol() : RestoreBB.getSymbol();
// Now, the distance could be defined.
auto *Offset = MCBinaryExpr::createSub(
- MCSymbolRefExpr::create(DestBB.getSymbol(), MCCtx),
+ MCSymbolRefExpr::create(DestLabel, MCCtx),
MCSymbolRefExpr::create(PostGetPCLabel, MCCtx), MCCtx);
// Add offset assignments.
auto *Mask = MCConstantExpr::create(0xFFFFFFFFULL, MCCtx);
OffsetLo->setVariableValue(MCBinaryExpr::createAnd(Offset, Mask, MCCtx));
auto *ShAmt = MCConstantExpr::create(32, MCCtx);
OffsetHi->setVariableValue(MCBinaryExpr::createAShr(Offset, ShAmt, MCCtx));
- return ComputeBlockSize(this, MBB);
+
+ return;
}
unsigned SIInstrInfo::getBranchOpcode(SIInstrInfo::BranchPredicate Cond) {