progress |= opt_if_cf_list(b, &loop->body,
aggressive_last_continue);
progress |= opt_simplify_bcsel_of_phi(b, loop);
- progress |= opt_peel_loop_initial_if(loop);
progress |= opt_if_loop_last_continue(loop,
aggressive_last_continue);
break;
return progress;
}
+static bool
+opt_peel_loop_initial_if_cf_list(struct exec_list *cf_list)
+{
+ bool progress = false;
+ foreach_list_typed(nir_cf_node, cf_node, node, cf_list) {
+ switch (cf_node->type) {
+ case nir_cf_node_block:
+ break;
+
+ case nir_cf_node_if: {
+ nir_if *nif = nir_cf_node_as_if(cf_node);
+ progress |= opt_peel_loop_initial_if_cf_list(&nif->then_list);
+ progress |= opt_peel_loop_initial_if_cf_list(&nif->else_list);
+ break;
+ }
+
+ case nir_cf_node_loop: {
+ nir_loop *loop = nir_cf_node_as_loop(cf_node);
+ progress |= opt_peel_loop_initial_if_cf_list(&loop->body);
+ progress |= opt_peel_loop_initial_if(loop);
+ break;
+ }
+
+ case nir_cf_node_function:
+ unreachable("Invalid cf type");
+ }
+ }
+
+ return progress;
+}
+
/**
* These optimisations depend on nir_metadata_block_index and therefore must
* not do anything to cause the metadata to become invalid.
nir_metadata_preserve(function->impl, nir_metadata_block_index |
nir_metadata_dominance);
- if (opt_if_cf_list(&b, &function->impl->body,
- aggressive_last_continue)) {
- nir_metadata_preserve(function->impl, nir_metadata_none);
+ bool preserve = true;
+
+ if (opt_if_cf_list(&b, &function->impl->body, aggressive_last_continue)) {
+ preserve = false;
+ progress = true;
+ }
+
+ if (opt_peel_loop_initial_if_cf_list(&function->impl->body)) {
+ preserve = false;
+ progress = true;
/* If that made progress, we're no longer really in SSA form. We
* need to convert registers back into SSA defs and clean up SSA defs
* that don't dominate their uses.
*/
nir_lower_regs_to_ssa_impl(function->impl);
+ }
- progress = true;
+ if (preserve) {
+ nir_metadata_preserve(function->impl, nir_metadata_none);
} else {
#ifndef NDEBUG
function->impl->valid_metadata &= ~nir_metadata_not_properly_reset;