[Mesa-dev] [PATCH 1/6] nir/dead_variables: Remove shader-local variables that are only written
Timothy Arceri
timothy.arceri at collabora.com
Wed Jan 4 23:20:15 UTC 2017
On Mon, 2016-12-12 at 19:39 -0800, Jason Ekstrand wrote:
> ---
> src/compiler/nir/nir_remove_dead_variables.c | 66
> ++++++++++++++++++++++++----
> 1 file changed, 58 insertions(+), 8 deletions(-)
>
> diff --git a/src/compiler/nir/nir_remove_dead_variables.c
> b/src/compiler/nir/nir_remove_dead_variables.c
> index f7429eb..d22b7f5 100644
> --- a/src/compiler/nir/nir_remove_dead_variables.c
> +++ b/src/compiler/nir/nir_remove_dead_variables.c
> @@ -31,9 +31,27 @@ static void
> add_var_use_intrinsic(nir_intrinsic_instr *instr, struct set *live)
> {
> unsigned num_vars = nir_intrinsic_infos[instr-
> >intrinsic].num_variables;
> - for (unsigned i = 0; i < num_vars; i++) {
> - nir_variable *var = instr->variables[i]->var;
> - _mesa_set_add(live, var);
> +
> + switch (instr->intrinsic) {
> + case nir_intrinsic_copy_var:
> + _mesa_set_add(live, instr->variables[1]->var);
> + /* Fall through */
> + case nir_intrinsic_store_var: {
> + /* The first source in both copy_var and store_var is the
> destination.
> + * If the variable is a local that never escapes the shader,
> then we
> + * don't mark it as live for just a store.
> + */
> + nir_variable_mode mode = instr->variables[0]->var->data.mode;
> + if (!(mode & (nir_var_local | nir_var_global |
> nir_var_shared)))
So you have nir_var_shared here but I think you are missing the bit to
add:
if (modes & nir_var_shared)
progress = remove_dead_vars(&shader->shared, live) || progress;
Otherwise won't the var remain while the write instruction is removed?
> + _mesa_set_add(live, instr->variables[0]->var);
> + break;
> + }
> +
> + default:
> + for (unsigned i = 0; i < num_vars; i++) {
> + _mesa_set_add(live, instr->variables[i]->var);
> + }
> + break;
> }
> }
>
> @@ -94,6 +112,31 @@ add_var_use_shader(nir_shader *shader, struct set
> *live)
> }
> }
>
> +static void
> +remove_dead_var_writes(nir_shader *shader, struct set *live)
> +{
> + nir_foreach_function(function, shader) {
> + if (!function->impl)
> + continue;
> +
> + nir_foreach_block(block, function->impl) {
> + nir_foreach_instr_safe(instr, block) {
> + if (instr->type != nir_instr_type_intrinsic)
> + continue;
> +
> + nir_intrinsic_instr *intrin =
> nir_instr_as_intrinsic(instr);
> + if (intrin->intrinsic != nir_intrinsic_copy_var &&
> + intrin->intrinsic != nir_intrinsic_store_var)
> + continue;
> +
> + /* Stores to dead variables need to be removed */
> + if (!_mesa_set_search(live, intrin->variables[0]->var))
> + nir_instr_remove(instr);
> + }
> + }
> + }
> +}
> +
> static bool
> remove_dead_vars(struct exec_list *var_list, struct set *live)
> {
> @@ -138,12 +181,19 @@ nir_remove_dead_variables(nir_shader *shader,
> nir_variable_mode modes)
> if (modes & nir_var_local) {
> nir_foreach_function(function, shader) {
> if (function->impl) {
> - if (remove_dead_vars(&function->impl->locals, live)) {
> - nir_metadata_preserve(function->impl,
> nir_metadata_block_index |
> - nir_metadata_do
> minance |
> - nir_metadata_li
> ve_ssa_defs);
> + if (remove_dead_vars(&function->impl->locals, live))
> progress = true;
> - }
> + }
> + }
> + }
> +
> + if (progress) {
> + remove_dead_var_writes(shader, live);
The vars are conditional on modes passed to nir_remove_dead_variables()
dont we need this here too? Otherwise we will remove the write
instruction but not the var.
> +
> + nir_foreach_function(function, shader) {
> + if (function->impl) {
> + nir_metadata_preserve(function->impl,
> nir_metadata_block_index |
> + nir_metadata_domin
> ance);
> }
> }
> }
More information about the mesa-dev
mailing list