Sometimes it's useful for a pass to be able to clean up its own derefs instead of waiting for DCE. This little helper makes it very easy.
Reviewed-by: Caio Marcelo de Oliveira Filho <caio.olive...@intel.com> --- src/compiler/nir/nir.h | 4 ++++ src/compiler/nir/nir_deref.c | 53 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 8b826d8..f8a12c1 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -1021,6 +1021,8 @@ nir_deref_instr_get_variable(const nir_deref_instr *instr) return instr->var; } +bool nir_deref_instr_remove_if_unused(nir_deref_instr *instr); + nir_deref_var * nir_deref_instr_to_deref(nir_deref_instr *instr, void *mem_ctx); @@ -2675,6 +2677,8 @@ bool nir_lower_regs_to_ssa_impl(nir_function_impl *impl); bool nir_lower_regs_to_ssa(nir_shader *shader); bool nir_lower_vars_to_ssa(nir_shader *shader); +bool nir_remove_dead_derefs(nir_shader *shader); +bool nir_remove_dead_derefs_impl(nir_function_impl *impl); bool nir_remove_dead_variables(nir_shader *shader, nir_variable_mode modes); bool nir_lower_constant_initializers(nir_shader *shader, nir_variable_mode modes); diff --git a/src/compiler/nir/nir_deref.c b/src/compiler/nir/nir_deref.c index 87a8192..0e8699a 100644 --- a/src/compiler/nir/nir_deref.c +++ b/src/compiler/nir/nir_deref.c @@ -24,6 +24,59 @@ #include "nir.h" #include "nir_builder.h" +/** + * Recursively removes unused deref instructions + */ +bool +nir_deref_instr_remove_if_unused(nir_deref_instr *instr) +{ + bool progress = false; + + for (nir_deref_instr *d = instr; d; d = nir_deref_instr_parent(d)) { + /* If anyone is using this deref, leave it alone */ + assert(d->dest.is_ssa); + if (!list_empty(&d->dest.ssa.uses)) + break; + + nir_instr_remove(&d->instr); + progress = true; + } + + return progress; +} + +bool +nir_remove_dead_derefs_impl(nir_function_impl *impl) +{ + bool progress = false; + + nir_foreach_block(block, impl) { + nir_foreach_instr_safe(instr, block) { + if (instr->type == nir_instr_type_deref && + nir_deref_instr_remove_if_unused(nir_instr_as_deref(instr))) + progress = true; + } + } + + if (progress) + nir_metadata_preserve(impl, nir_metadata_block_index | + nir_metadata_dominance); + + return progress; +} + +bool +nir_remove_dead_derefs(nir_shader *shader) +{ + bool progress = false; + nir_foreach_function(function, shader) { + if (function->impl && nir_remove_dead_derefs_impl(function->impl)) + progress = true; + } + + return progress; +} + nir_deref_var * nir_deref_instr_to_deref(nir_deref_instr *instr, void *mem_ctx) { -- 2.5.0.400.gff86faf _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev