aco: check logical_phi_info at p_logical_end when eliminating exec writes
This is when the copies actually happen, not at the branch. fossil-db (gfx1100): Totals from 1 (0.00% of 79332) affected shaders: Instrs: 424 -> 423 (-0.24%) CodeSize: 2172 -> 2168 (-0.18%) Latency: 2899 -> 2896 (-0.10%) Copies: 24 -> 23 (-4.17%) Signed-off-by: Rhys Perry <pendingchaos02@gmail.com> Reviewed-by: Timur Kristóf <timur.kristof@gmail.com> Cc: mesa-stable Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25244>
This commit is contained in:
@@ -547,30 +547,25 @@ eliminate_useless_exec_writes_in_block(ssa_elimination_ctx& ctx, Block& block)
|
||||
{
|
||||
/* Check if any successor needs the outgoing exec mask from the current block. */
|
||||
|
||||
bool exec_write_used;
|
||||
bool copy_to_exec = false;
|
||||
bool copy_from_exec = false;
|
||||
|
||||
if (!ctx.logical_phi_info[block.index].empty()) {
|
||||
exec_write_used = true;
|
||||
} else {
|
||||
bool copy_to_exec = false;
|
||||
bool copy_from_exec = false;
|
||||
|
||||
for (const auto& successor_phi_info : ctx.linear_phi_info[block.index]) {
|
||||
copy_to_exec |= successor_phi_info.def.physReg() == exec;
|
||||
copy_from_exec |= successor_phi_info.op.physReg() == exec;
|
||||
}
|
||||
|
||||
if (copy_from_exec)
|
||||
exec_write_used = true;
|
||||
else if (copy_to_exec)
|
||||
exec_write_used = false;
|
||||
else
|
||||
/* blocks_incoming_exec_used is initialized to true, so this is correct even for loops. */
|
||||
exec_write_used =
|
||||
std::any_of(block.linear_succs.begin(), block.linear_succs.end(),
|
||||
[&ctx](int succ_idx) { return ctx.blocks_incoming_exec_used[succ_idx]; });
|
||||
for (const auto& successor_phi_info : ctx.linear_phi_info[block.index]) {
|
||||
copy_to_exec |= successor_phi_info.def.physReg() == exec;
|
||||
copy_from_exec |= successor_phi_info.op.physReg() == exec;
|
||||
}
|
||||
|
||||
bool exec_write_used;
|
||||
if (copy_from_exec)
|
||||
exec_write_used = true;
|
||||
else if (copy_to_exec)
|
||||
exec_write_used = false;
|
||||
else
|
||||
/* blocks_incoming_exec_used is initialized to true, so this is correct even for loops. */
|
||||
exec_write_used =
|
||||
std::any_of(block.linear_succs.begin(), block.linear_succs.end(),
|
||||
[&ctx](int succ_idx) { return ctx.blocks_incoming_exec_used[succ_idx]; });
|
||||
|
||||
/* Collect information about the branching sequence. */
|
||||
|
||||
bool logical_end_found = false;
|
||||
@@ -590,7 +585,9 @@ eliminate_useless_exec_writes_in_block(ssa_elimination_ctx& ctx, Block& block)
|
||||
break;
|
||||
|
||||
/* See if the current instruction needs or writes exec. */
|
||||
bool needs_exec = needs_exec_mask(instr.get());
|
||||
bool needs_exec =
|
||||
needs_exec_mask(instr.get()) ||
|
||||
(instr->opcode == aco_opcode::p_logical_end && !ctx.logical_phi_info[block.index].empty());
|
||||
bool writes_exec = instr_writes_exec(instr.get());
|
||||
|
||||
logical_end_found |= instr->opcode == aco_opcode::p_logical_end;
|
||||
|
Reference in New Issue
Block a user