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 <caio.oliveira@intel.com> Acked-by: Rob Clark <robdclark@gmail.com> Acked-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> Acked-by: Dave Airlie <airlied@redhat.com> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
@@ -1032,6 +1032,8 @@ nir_deref_instr_get_variable(const nir_deref_instr *instr)
|
|||||||
return instr->var;
|
return instr->var;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool nir_deref_instr_remove_if_unused(nir_deref_instr *instr);
|
||||||
|
|
||||||
nir_deref_var *
|
nir_deref_var *
|
||||||
nir_deref_instr_to_deref(nir_deref_instr *instr, void *mem_ctx);
|
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_regs_to_ssa(nir_shader *shader);
|
||||||
bool nir_lower_vars_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_remove_dead_variables(nir_shader *shader, nir_variable_mode modes);
|
||||||
bool nir_lower_constant_initializers(nir_shader *shader,
|
bool nir_lower_constant_initializers(nir_shader *shader,
|
||||||
nir_variable_mode modes);
|
nir_variable_mode modes);
|
||||||
|
@@ -24,6 +24,59 @@
|
|||||||
#include "nir.h"
|
#include "nir.h"
|
||||||
#include "nir_builder.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_var *
|
||||||
nir_deref_instr_to_deref(nir_deref_instr *instr, void *mem_ctx)
|
nir_deref_instr_to_deref(nir_deref_instr *instr, void *mem_ctx)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user