diff options
author | Connor Abbott <[email protected]> | 2015-07-21 19:54:27 -0700 |
---|---|---|
committer | Kenneth Graunke <[email protected]> | 2015-08-24 13:31:42 -0700 |
commit | 211c79515d2d4cde12cc6a19bb064692b2de3f26 (patch) | |
tree | c5512b28ea6a875cc56f98f78c19d219568abf18 /src | |
parent | 633cbbc0682b1cec3107398a21a057697e8572aa (diff) |
nir/cf: remove uses of SSA definitions that are being deleted
Unlike calling nir_instr_remove(), calling nir_cf_node_remove() (and
later in the series, the nir_cf_list_delete()) implies that you're
removing instructions that may still have uses, except those
instructions are never executed so any uses will be undefined. When
cleaning up a CF node for deletion, we must clean up any uses of the
deleted instructions by making them point to undef instructions instead.
Signed-off-by: Connor Abbott <[email protected]>
Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src')
-rw-r--r-- | src/glsl/nir/nir_control_flow.c | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/src/glsl/nir/nir_control_flow.c b/src/glsl/nir/nir_control_flow.c index 8a4a0bf5f9d..5aab43bbf77 100644 --- a/src/glsl/nir/nir_control_flow.c +++ b/src/glsl/nir/nir_control_flow.c @@ -726,26 +726,41 @@ stitch_blocks(nir_block *before, nir_block *after) } } +static bool +replace_ssa_def_uses(nir_ssa_def *def, void *void_impl) +{ + nir_function_impl *impl = void_impl; + void *mem_ctx = ralloc_parent(impl); + + nir_ssa_undef_instr *undef = + nir_ssa_undef_instr_create(mem_ctx, def->num_components); + nir_instr_insert_before_cf_list(&impl->body, &undef->instr); + nir_ssa_def_rewrite_uses(def, nir_src_for_ssa(&undef->def), mem_ctx); + return true; +} static void -cleanup_cf_node(nir_cf_node *node) +cleanup_cf_node(nir_cf_node *node, nir_function_impl *impl) { switch (node->type) { case nir_cf_node_block: { nir_block *block = nir_cf_node_as_block(node); /* We need to walk the instructions and clean up defs/uses */ - nir_foreach_instr_safe(block, instr) - if (instr->type != nir_instr_type_jump) + nir_foreach_instr_safe(block, instr) { + if (instr->type != nir_instr_type_jump) { + nir_foreach_ssa_def(instr, replace_ssa_def_uses, impl); nir_instr_remove(instr); + } + } break; } case nir_cf_node_if: { nir_if *if_stmt = nir_cf_node_as_if(node); foreach_list_typed(nir_cf_node, child, node, &if_stmt->then_list) - cleanup_cf_node(child); + cleanup_cf_node(child, impl); foreach_list_typed(nir_cf_node, child, node, &if_stmt->else_list) - cleanup_cf_node(child); + cleanup_cf_node(child, impl); list_del(&if_stmt->condition.use_link); break; @@ -754,13 +769,13 @@ cleanup_cf_node(nir_cf_node *node) case nir_cf_node_loop: { nir_loop *loop = nir_cf_node_as_loop(node); foreach_list_typed(nir_cf_node, child, node, &loop->body) - cleanup_cf_node(child); + cleanup_cf_node(child, impl); break; } case nir_cf_node_function: { nir_function_impl *impl = nir_cf_node_as_function(node); foreach_list_typed(nir_cf_node, child, node, &impl->body) - cleanup_cf_node(child); + cleanup_cf_node(child, impl); break; } default: @@ -796,5 +811,6 @@ nir_cf_node_remove(nir_cf_node *node) stitch_blocks(before_block, after_block); } - cleanup_cf_node(node); + cleanup_cf_node(node, impl); } + |