From 8b7aa66169f9d675f83c483b3c7af38007e7e056 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Tue, 20 Mar 2018 17:32:07 -0700 Subject: [PATCH] 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 --- 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 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) { -- 2.30.2