From fc3f659aa9c312661bf2a4a63643e40fbebda338 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Mon, 11 Jan 2016 15:33:41 -0800 Subject: [PATCH] nir/vars_to_ssa: Add phi sources for unreachable predecessors It is possible to end up with unreachable blocks if, for instance, you have an "if (...) { break; } else { continue; } unreachable()". In this case, the unreachable block does not show up in the dominance tree so it never gets visited. Instead, we go and visit all of those in follow-on pass. --- src/glsl/nir/nir_lower_vars_to_ssa.c | 46 ++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/glsl/nir/nir_lower_vars_to_ssa.c b/src/glsl/nir/nir_lower_vars_to_ssa.c index 75d31ff60af..a5f5ef2de3c 100644 --- a/src/glsl/nir/nir_lower_vars_to_ssa.c +++ b/src/glsl/nir/nir_lower_vars_to_ssa.c @@ -581,6 +581,33 @@ add_phi_sources(nir_block *block, nir_block *pred, } } +static void +add_undef_phi_sources(nir_block *block, nir_block *pred, + struct lower_variables_state *state) +{ + nir_foreach_instr(block, instr) { + if (instr->type != nir_instr_type_phi) + break; + + nir_phi_instr *phi = nir_instr_as_phi(instr); + + nir_ssa_undef_instr *undef = + nir_ssa_undef_instr_create(state->shader, + phi->dest.ssa.num_components); + nir_instr_insert(nir_before_cf_list(&state->impl->body), &undef->instr); + + nir_phi_src *src = ralloc(phi, nir_phi_src); + src->pred = pred; + src->src.parent_instr = &phi->instr; + src->src.is_ssa = true; + src->src.ssa = &undef->def; + + list_addtail(&src->src.use_link, &undef->def.uses); + + exec_list_push_tail(&phi->srcs, &src->node); + } +} + /* Performs variable renaming by doing a DFS of the dominance tree * * This algorithm is very similar to the one outlined in "Efficiently @@ -774,6 +801,23 @@ rename_variables_block(nir_block *block, struct lower_variables_state *state) return true; } +static bool +add_unreachable_phi_srcs_block(nir_block *block, void *void_state) +{ + struct lower_variables_state *state = void_state; + + /* Only run on unreachable blocks */ + if (block->imm_dom || block == nir_start_block(state->impl)) + return true; + + if (block->successors[0]) + add_undef_phi_sources(block->successors[0], block, state); + if (block->successors[1]) + add_undef_phi_sources(block->successors[1], block, state); + + return true; +} + /* Inserts phi nodes for all variables marked lower_to_ssa * * This is the same algorithm as presented in "Efficiently Computing Static @@ -955,6 +999,8 @@ nir_lower_vars_to_ssa_impl(nir_function_impl *impl) insert_phi_nodes(&state); rename_variables_block(nir_start_block(impl), &state); + nir_foreach_block(impl, add_unreachable_phi_srcs_block, &state); + nir_metadata_preserve(impl, nir_metadata_block_index | nir_metadata_dominance); -- 2.30.2