Commit 3f56fa8f authored by Jason Ekstrand's avatar Jason Ekstrand Committed by Dylan Baker

nir/repair_ssa: Repair dominance for unreachable blocks

NIR currently assumes that unreachable blocks are trivially dominated by
everything.  However, when considering well-formed SSA, there is no path
from any block to an unreachable block.  Therefore, we can break any
use-def chains where the use is in an unreachable block.  This removes
any dependencies on code created by uses in unreachable blocks and lets
DCE do a better job of cleaning it up.

Cc: mesa-stable@lists.freedesktop.org
Reviewed-by: Caio Marcelo de Oliveira Filho's avatarCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
(cherry picked from commit a3268599)
parent 2c6e34ac
...@@ -71,7 +71,8 @@ repair_ssa_def(nir_ssa_def *def, void *void_state) ...@@ -71,7 +71,8 @@ repair_ssa_def(nir_ssa_def *def, void *void_state)
bool is_valid = true; bool is_valid = true;
nir_foreach_use(src, def) { nir_foreach_use(src, def) {
if (!nir_block_dominates(def->parent_instr->block, get_src_block(src))) { if (nir_block_is_unreachable(get_src_block(src)) ||
!nir_block_dominates(def->parent_instr->block, get_src_block(src))) {
is_valid = false; is_valid = false;
break; break;
} }
...@@ -80,7 +81,8 @@ repair_ssa_def(nir_ssa_def *def, void *void_state) ...@@ -80,7 +81,8 @@ repair_ssa_def(nir_ssa_def *def, void *void_state)
nir_foreach_if_use(src, def) { nir_foreach_if_use(src, def) {
nir_block *block_before_if = nir_block *block_before_if =
nir_cf_node_as_block(nir_cf_node_prev(&src->parent_if->cf_node)); nir_cf_node_as_block(nir_cf_node_prev(&src->parent_if->cf_node));
if (!nir_block_dominates(def->parent_instr->block, block_before_if)) { if (nir_block_is_unreachable(block_before_if) ||
!nir_block_dominates(def->parent_instr->block, block_before_if)) {
is_valid = false; is_valid = false;
break; break;
} }
...@@ -101,7 +103,8 @@ repair_ssa_def(nir_ssa_def *def, void *void_state) ...@@ -101,7 +103,8 @@ repair_ssa_def(nir_ssa_def *def, void *void_state)
nir_foreach_use_safe(src, def) { nir_foreach_use_safe(src, def) {
nir_block *src_block = get_src_block(src); nir_block *src_block = get_src_block(src);
if (!nir_block_dominates(def->parent_instr->block, src_block)) { if (nir_block_is_unreachable(src_block) ||
!nir_block_dominates(def->parent_instr->block, src_block)) {
nir_instr_rewrite_src(src->parent_instr, src, nir_src_for_ssa( nir_instr_rewrite_src(src->parent_instr, src, nir_src_for_ssa(
nir_phi_builder_value_get_block_def(val, src_block))); nir_phi_builder_value_get_block_def(val, src_block)));
} }
...@@ -110,7 +113,8 @@ repair_ssa_def(nir_ssa_def *def, void *void_state) ...@@ -110,7 +113,8 @@ repair_ssa_def(nir_ssa_def *def, void *void_state)
nir_foreach_if_use_safe(src, def) { nir_foreach_if_use_safe(src, def) {
nir_block *block_before_if = nir_block *block_before_if =
nir_cf_node_as_block(nir_cf_node_prev(&src->parent_if->cf_node)); nir_cf_node_as_block(nir_cf_node_prev(&src->parent_if->cf_node));
if (!nir_block_dominates(def->parent_instr->block, block_before_if)) { if (nir_block_is_unreachable(block_before_if) ||
!nir_block_dominates(def->parent_instr->block, block_before_if)) {
nir_if_rewrite_condition(src->parent_if, nir_src_for_ssa( nir_if_rewrite_condition(src->parent_if, nir_src_for_ssa(
nir_phi_builder_value_get_block_def(val, block_before_if))); nir_phi_builder_value_get_block_def(val, block_before_if)));
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment