From: Jason Ekstrand Date: Wed, 21 Mar 2018 00:32:07 +0000 (-0700) Subject: nir/deref: Add some deref cleanup functions X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8b7aa66169f9d675f83c483b3c7af38007e7e056;p=mesa.git nir/deref: Add some deref cleanup functions 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 Acked-by: Rob Clark Acked-by: Bas Nieuwenhuizen Acked-by: Dave Airlie Reviewed-by: Kenneth Graunke --- diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index bec5f99ba78..d25aa7491ed 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -1032,6 +1032,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); @@ -2728,6 +2730,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 87a81925c40..0e8699aa6e6 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) {