aco/lower_branches: stitch linear blocks if there is exactly one successor with one predecessor

Totals from 12906 (16.26% of 79395) affected shaders: (Navi31)

Instrs: 22051521 -> 22049488 (-0.01%); split: -0.01%, +0.00%
CodeSize: 116591240 -> 116583920 (-0.01%)
Latency: 196625178 -> 196538410 (-0.04%); split: -0.04%, +0.00%
InvThroughput: 33943045 -> 33930615 (-0.04%); split: -0.04%, +0.00%
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32477>
This commit is contained in:
Daniel Schürmann
2024-12-03 11:47:37 +01:00
committed by Marge Bot
parent c90ae5f773
commit 08560b8ff8

View File

@@ -453,6 +453,64 @@ lower_branch_instruction(branch_ctx& ctx, Block& block)
} }
} }
void
try_stitch_linear_block(branch_ctx& ctx, Block& block)
{
/* Don't stitch blocks that are part of the logical CFG. */
if (block.linear_preds.empty() || block.linear_succs.empty() || !block.logical_preds.empty())
return;
/* Try to stitch this block with the predecessor:
* This block must have exactly one predecessor and
* the predecessor must have exactly one successor.
*/
Block& pred = ctx.program->blocks[block.linear_preds[0]];
if (block.linear_preds.size() == 1 && pred.linear_succs.size() == 1 &&
(pred.instructions.empty() || !pred.instructions.back()->isSOPP())) {
/* Insert the instructions at the end of the predecessor and fixup edges. */
pred.instructions.insert(pred.instructions.end(),
std::move_iterator(block.instructions.begin()),
std::move_iterator(block.instructions.end()));
for (unsigned succ_idx : block.linear_succs) {
Block& s = ctx.program->blocks[succ_idx];
std::replace(s.linear_preds.begin(), s.linear_preds.end(), block.index, pred.index);
}
pred.linear_succs = std::move(block.linear_succs);
block.instructions.clear();
block.linear_preds.clear();
block.linear_succs.clear();
return;
}
/* Try to stitch this block with the successor:
* This block must have exactly one successor and
* the successor must have exactly one predecessor.
*/
Block& succ = ctx.program->blocks[block.linear_succs[0]];
if (block.linear_succs.size() == 1 && succ.linear_preds.size() == 1 &&
(block.instructions.empty() || !block.instructions.back()->isSOPP())) {
/* Insert the instructions at the beginning of the successor. */
succ.instructions.insert(succ.instructions.begin(),
std::move_iterator(block.instructions.begin()),
std::move_iterator(block.instructions.end()));
for (unsigned pred_idx : block.linear_preds) {
Block& p = ctx.program->blocks[pred_idx];
if (!p.instructions.empty() &&
instr_info.classes[(int)p.instructions.back()->opcode] == instr_class::branch &&
p.instructions.back()->salu().imm == block.index) {
p.instructions.back()->salu().imm = succ.index;
}
std::replace(p.linear_succs.begin(), p.linear_succs.end(), block.index, succ.index);
}
succ.linear_preds = std::move(block.linear_preds);
block.instructions.clear();
block.linear_preds.clear();
block.linear_succs.clear();
}
}
} /* end namespace */ } /* end namespace */
void void
@@ -471,6 +529,10 @@ lower_branches(Program* program)
if (block.linear_succs.size() == 1) if (block.linear_succs.size() == 1)
try_remove_simple_block(ctx, block); try_remove_simple_block(ctx, block);
} }
for (Block& block : program->blocks) {
try_stitch_linear_block(ctx, block);
}
} }
} // namespace aco } // namespace aco