Skip to content

Commit c3e07a0

Browse files
committed
[AMDGPU] SIInsertSkips: Refactor early exit block creation
Refactor exit block creation to a single call ensureEarlyExitBlock. Add support for generating an early exit block which clears the exec mask, but only add this instruction when required. These changes are to facilitate adding more forms of early termination for PS shaders in the near future. Reviewed By: nhaehnle Differential Revision: https://reviews.llvm.org/D88775
1 parent ea9d639 commit c3e07a0

File tree

1 file changed

+20
-11
lines changed

1 file changed

+20
-11
lines changed

llvm/lib/Target/AMDGPU/SIInsertSkips.cpp

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,13 @@ class SIInsertSkips : public MachineFunctionPass {
5858
MachineDominatorTree *MDT = nullptr;
5959

6060
MachineBasicBlock *EarlyExitBlock = nullptr;
61+
bool EarlyExitClearsExec = false;
6162

6263
bool shouldSkip(const MachineBasicBlock &From,
6364
const MachineBasicBlock &To) const;
6465

6566
bool dominatesAllReachable(MachineBasicBlock &MBB);
66-
void createEarlyExitBlock(MachineBasicBlock &MBB);
67+
void ensureEarlyExitBlock(MachineBasicBlock &MBB, bool ClearExec);
6768
void skipIfDead(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
6869
DebugLoc DL);
6970

@@ -180,15 +181,27 @@ static void generatePsEndPgm(MachineBasicBlock &MBB,
180181
BuildMI(MBB, I, DL, TII->get(AMDGPU::S_ENDPGM)).addImm(0);
181182
}
182183

183-
void SIInsertSkips::createEarlyExitBlock(MachineBasicBlock &MBB) {
184+
void SIInsertSkips::ensureEarlyExitBlock(MachineBasicBlock &MBB,
185+
bool ClearExec) {
184186
MachineFunction *MF = MBB.getParent();
185187
DebugLoc DL;
186188

187-
assert(!EarlyExitBlock);
188-
EarlyExitBlock = MF->CreateMachineBasicBlock();
189-
MF->insert(MF->end(), EarlyExitBlock);
189+
if (!EarlyExitBlock) {
190+
EarlyExitBlock = MF->CreateMachineBasicBlock();
191+
MF->insert(MF->end(), EarlyExitBlock);
192+
generatePsEndPgm(*EarlyExitBlock, EarlyExitBlock->end(), DL, TII);
193+
EarlyExitClearsExec = false;
194+
}
190195

191-
generatePsEndPgm(*EarlyExitBlock, EarlyExitBlock->end(), DL, TII);
196+
if (ClearExec && !EarlyExitClearsExec) {
197+
const GCNSubtarget &ST = MF->getSubtarget<GCNSubtarget>();
198+
unsigned Mov = ST.isWave32() ? AMDGPU::S_MOV_B32 : AMDGPU::S_MOV_B64;
199+
Register Exec = ST.isWave32() ? AMDGPU::EXEC_LO : AMDGPU::EXEC;
200+
auto ExitI = EarlyExitBlock->getFirstNonPHI();
201+
assert(ExitI->getOpcode() == AMDGPU::EXP_DONE);
202+
BuildMI(*EarlyExitBlock, ExitI, DL, TII->get(Mov), Exec).addImm(0);
203+
EarlyExitClearsExec = true;
204+
}
192205
}
193206

194207
static void splitBlock(MachineBasicBlock &MBB, MachineInstr &MI,
@@ -233,11 +246,7 @@ void SIInsertSkips::skipIfDead(MachineBasicBlock &MBB,
233246
if (NoSuccessor) {
234247
generatePsEndPgm(MBB, I, DL, TII);
235248
} else {
236-
if (!EarlyExitBlock) {
237-
createEarlyExitBlock(MBB);
238-
// Update next block pointer to reflect any new blocks
239-
NextBBI = std::next(MBB.getIterator());
240-
}
249+
ensureEarlyExitBlock(MBB, false);
241250

242251
MachineInstr *BranchMI =
243252
BuildMI(MBB, I, DL, TII->get(AMDGPU::S_CBRANCH_EXECZ))

0 commit comments

Comments
 (0)