mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-28 23:20:08 +01:00
nir: remove unreachable loop terminators
Remove the conditional break statements associated with all terminators that are associated with a fixed iteration count, except for the one associated with the limiting terminator. This logic matches similiar functionality that exists in the old GLSL IR unrolling code. This change helps a piglit test pass on the r300 driver once we switch off the old GLSL IR unrolling code. Shader-db results IRIS (BDW): total instructions in shared programs: 17538619 -> 17538595 (<.01%) instructions in affected programs: 216 -> 192 (-11.11%) helped: 3 HURT: 0 helped stats (abs) min: 7 max: 10 x̄: 8.00 x̃: 7 helped stats (rel) min: 10.00% max: 12.07% x̄: 11.38% x̃: 12.07% total cycles in shared programs: 858674910 -> 858672810 (<.01%) cycles in affected programs: 79540 -> 77440 (-2.64%) helped: 3 HURT: 0 helped stats (abs) min: 620 max: 800 x̄: 700.00 x̃: 680 helped stats (rel) min: 2.45% max: 2.83% x̄: 2.63% x̃: 2.62% Reviewed-by: Emma Anholt <emma@anholt.net> Reviewed-by: Jason Ekstrand <jason.ekstrand@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16399>
This commit is contained in:
parent
4c3d138e5d
commit
0f98ed4afe
1 changed files with 37 additions and 0 deletions
|
|
@ -946,6 +946,43 @@ process_loops(nir_shader *sh, nir_cf_node *cf_node, bool *has_nested_loop_out,
|
|||
*/
|
||||
if (!progress && loop->control != nir_loop_control_dont_unroll) {
|
||||
|
||||
/* Remove the conditional break statements associated with all terminators
|
||||
* that are associated with a fixed iteration count, except for the one
|
||||
* associated with the limiting terminator--that one needs to stay, since
|
||||
* it terminates the loop.
|
||||
*/
|
||||
if (loop->info->limiting_terminator) {
|
||||
list_for_each_entry_safe(nir_loop_terminator, t,
|
||||
&loop->info->loop_terminator_list,
|
||||
loop_terminator_link) {
|
||||
if (t->exact_trip_count_unknown)
|
||||
continue;
|
||||
|
||||
if (t != loop->info->limiting_terminator) {
|
||||
|
||||
/* Only delete the if-statement if the continue block is empty.
|
||||
* We trust that nir_opt_if() does its job well enough to
|
||||
* remove all instructions from the continue block when possible.
|
||||
*/
|
||||
nir_block *first_continue_from_blk = t->continue_from_then ?
|
||||
nir_if_first_then_block(t->nif) :
|
||||
nir_if_first_else_block(t->nif);
|
||||
|
||||
if (!(nir_cf_node_is_last(&first_continue_from_blk->cf_node) &&
|
||||
exec_list_is_empty(&first_continue_from_blk->instr_list)))
|
||||
continue;
|
||||
|
||||
/* Now delete the if */
|
||||
nir_cf_node_remove(&t->nif->cf_node);
|
||||
|
||||
/* Also remove it from the terminator list */
|
||||
list_del(&t->loop_terminator_link);
|
||||
|
||||
progress = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for the classic
|
||||
*
|
||||
* do {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue