mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-19 02:48:07 +02:00
nir/licm: allow speculative hoisting across terminate if the filter is set
Reviewed-by: Daniel Schürmann <daniel@schuermann.dev> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41453>
This commit is contained in:
parent
3c2786b76a
commit
feeaae1c28
1 changed files with 15 additions and 4 deletions
|
|
@ -9,6 +9,7 @@ typedef struct {
|
|||
nir_opt_licm_filter_cb filter;
|
||||
|
||||
nir_loop *loop;
|
||||
bool loop_has_terminate;
|
||||
bool current_block_dominates_exit;
|
||||
} licm_state;
|
||||
|
||||
|
|
@ -71,8 +72,10 @@ visit_block(nir_block *block, licm_state *state)
|
|||
}
|
||||
|
||||
static bool
|
||||
should_optimize_loop(nir_loop *loop)
|
||||
should_optimize_loop(nir_loop *loop, licm_state *state)
|
||||
{
|
||||
state->loop_has_terminate = false;
|
||||
|
||||
/* Ignore loops without back-edge */
|
||||
if (!nir_loop_has_back_edge(loop))
|
||||
return false;
|
||||
|
|
@ -83,8 +86,13 @@ should_optimize_loop(nir_loop *loop)
|
|||
if (instr->type == nir_instr_type_intrinsic) {
|
||||
nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
|
||||
if (intrin->intrinsic == nir_intrinsic_terminate ||
|
||||
intrin->intrinsic == nir_intrinsic_terminate_if)
|
||||
return false;
|
||||
intrin->intrinsic == nir_intrinsic_terminate_if) {
|
||||
state->loop_has_terminate = true;
|
||||
|
||||
/* The filter allows speculative hoisting across terminate. */
|
||||
if (!state->filter)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -115,7 +123,8 @@ visit_cf_list(struct exec_list *list, licm_state *state)
|
|||
*/
|
||||
if (next && next->type == nir_cf_node_loop) {
|
||||
nir_loop *inner_loop = nir_cf_node_as_loop(next);
|
||||
optimize_loop = should_optimize_loop(inner_loop);
|
||||
bool prev_loop_has_terminate = state->loop_has_terminate;
|
||||
optimize_loop = should_optimize_loop(inner_loop, state);
|
||||
|
||||
if (optimize_loop) {
|
||||
nir_loop *outer_loop = state->loop;
|
||||
|
|
@ -125,11 +134,13 @@ visit_cf_list(struct exec_list *list, licm_state *state)
|
|||
progress |= visit_cf_list(&inner_loop->continue_list, state);
|
||||
state->loop = outer_loop;
|
||||
}
|
||||
state->loop_has_terminate = prev_loop_has_terminate;
|
||||
}
|
||||
|
||||
nir_block *block = nir_cf_node_as_block(node);
|
||||
if (state->loop) {
|
||||
state->current_block_dominates_exit =
|
||||
!state->loop_has_terminate &&
|
||||
nir_block_dominates(block, nir_loop_successor_block(state->loop));
|
||||
|
||||
/* By only visiting blocks which dominate the block after the loop,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue