bool nir_repair_ssa(nir_shader *shader);
void nir_convert_loop_to_lcssa(nir_loop *loop);
+bool nir_convert_to_lcssa(nir_shader *shader);
/* If phi_webs_only is true, only convert SSA values involved in phi nodes to
* registers. If false, convert all values (even those not involved in a phi
/* The loop we store information for */
nir_loop *loop;
+ bool progress;
} lcssa_state;
static bool
}
}
+ state->progress = true;
return true;
}
{
switch (cf_node->type) {
case nir_cf_node_block:
- nir_foreach_instr(instr, nir_cf_node_as_block(cf_node))
- nir_foreach_ssa_def(instr, convert_loop_exit_for_ssa, state);
+ if (state->loop) {
+ nir_foreach_instr(instr, nir_cf_node_as_block(cf_node))
+ nir_foreach_ssa_def(instr, convert_loop_exit_for_ssa, state);
+ }
return;
case nir_cf_node_if: {
nir_if *if_stmt = nir_cf_node_as_if(cf_node);
}
void
-nir_convert_loop_to_lcssa(nir_loop *loop) {
+nir_convert_loop_to_lcssa(nir_loop *loop)
+{
nir_function_impl *impl = nir_cf_node_get_function(&loop->cf_node);
nir_metadata_require(impl, nir_metadata_block_index);
ralloc_free(state);
}
+
+bool
+nir_convert_to_lcssa(nir_shader *shader)
+{
+ bool progress = false;
+ lcssa_state *state = rzalloc(NULL, lcssa_state);
+ state->shader = shader;
+
+ nir_foreach_function(function, shader) {
+ if (function->impl == NULL)
+ continue;
+
+ state->progress = false;
+ nir_metadata_require(function->impl, nir_metadata_block_index);
+
+ foreach_list_typed(nir_cf_node, node, node, &function->impl->body)
+ convert_to_lcssa(node, state);
+
+ if (state->progress) {
+ progress = true;
+ nir_metadata_preserve(function->impl, nir_metadata_block_index |
+ nir_metadata_dominance);
+ } else {
+#ifndef NDEBUG
+ function->impl->valid_metadata &= ~nir_metadata_not_properly_reset;
+#endif
+ }
+ }
+
+ ralloc_free(state);
+ return progress;
+}
+