nir/loop_unroll: clean up after complex_unroll_single_terminator()
Previously we would just unroll the loop one extra iteration and let other optimisation passes clean up the mess. This worked to a degree but if the loop happened to be nested inside another loop we would end up with phi chains that would block other passes from being able to do the cleanup. With this commit we explicitly clone the variables create by lcsaa and insert them directly in the last continue branch after we are done unrolling. With this optimisation passes can recognise both sides of the if output the same values and can progress further. Help with the issues described in: https://gitlab.freedesktop.org/mesa/mesa/-/issues/6051 Reviewed-by: Iago Toral Quiroga <itoral@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17611>
This commit is contained in:
parent
bfebf51571
commit
d1e36634bd
|
@ -495,6 +495,41 @@ complex_unroll_single_terminator(nir_loop *loop)
|
|||
complex_unroll_loop_body(loop, terminator, &lp_header, &lp_body,
|
||||
remap_table, num_times_to_clone);
|
||||
|
||||
assert(unroll_loc->type == nir_cf_node_if);
|
||||
|
||||
/* We need to clone the lcssa vars in order to insert them on both sides
|
||||
* of the if in the last iteration/if-statement. Otherwise the optimisation
|
||||
* passes will have trouble optimising the unrolled if ladder.
|
||||
*/
|
||||
nir_cursor cursor =
|
||||
get_complex_unroll_insert_location(unroll_loc,
|
||||
terminator->continue_from_then);
|
||||
|
||||
nir_if *if_stmt = nir_cf_node_as_if(unroll_loc);
|
||||
nir_cursor start_cursor;
|
||||
nir_cursor end_cursor;
|
||||
if (terminator->continue_from_then) {
|
||||
start_cursor = nir_before_block(nir_if_first_else_block(if_stmt));
|
||||
end_cursor = nir_after_block(nir_if_last_else_block(if_stmt));
|
||||
} else {
|
||||
start_cursor = nir_before_block(nir_if_first_then_block(if_stmt));
|
||||
end_cursor = nir_after_block(nir_if_last_then_block(if_stmt));
|
||||
}
|
||||
|
||||
nir_cf_list lcssa_list;
|
||||
nir_cf_extract(&lcssa_list, start_cursor, end_cursor);
|
||||
|
||||
/* Insert the cloned vars in the last continue branch */
|
||||
nir_cf_list_clone_and_reinsert(&lcssa_list, loop->cf_node.parent,
|
||||
cursor, remap_table);
|
||||
|
||||
start_cursor = terminator->continue_from_then ?
|
||||
nir_before_block(nir_if_first_else_block(if_stmt)) :
|
||||
nir_before_block(nir_if_first_then_block(if_stmt));
|
||||
|
||||
/* Reinsert the cloned vars back where they came from */
|
||||
nir_cf_reinsert(&lcssa_list, start_cursor);
|
||||
|
||||
/* Delete the original loop header and body */
|
||||
nir_cf_delete(&lp_header);
|
||||
nir_cf_delete(&lp_body);
|
||||
|
|
Loading…
Reference in New Issue