From 3a2ea2af9d18826967ea48645d5b70e6c7cf39e6 Mon Sep 17 00:00:00 2001 From: Connor Abbott Date: Wed, 15 May 2019 12:49:29 +0200 Subject: [PATCH] nir: Avoid coalescing vars created by lower_io_to_temporaries Right now nir_copy_prop_vars is effectively undoing nir_lower_io_to_temporaries for inputs by propagating the original variable through the copy created in lower_io_to_temporaries. A theoretical variable coalescing pass would have the same issue with output variables, although that doesn't exist yet. To fix this, add a new bit to nir_variable, and disable copy propagation when it's set. This doesn't seem to affect any drivers now, probably since since no one uses lower_io_to_temporaries for inputs as well as copy_prop_vars, but it will fix radv once we flip on lower_io_to_temporaries for fs inputs. Reviewed-by: Bas Nieuwenhuizen --- src/compiler/nir/nir.h | 11 +++++++++++ src/compiler/nir/nir_lower_io_to_temporaries.c | 1 + src/compiler/nir/nir_opt_copy_prop_vars.c | 8 ++++++++ 3 files changed, 20 insertions(+) diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 3119e656e24..a2b3d393f12 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -227,6 +227,17 @@ typedef struct nir_variable { unsigned patch:1; unsigned invariant:1; + /** + * Can this variable be coalesced with another? + * + * This is set by nir_lower_io_to_temporaries to say that any + * copies involving this variable should stay put. Propagating it can + * duplicate the resulting load/store, which is not wanted, and may + * result in a load/store of the variable with an indirect offset which + * the backend may not be able to handle. + */ + unsigned cannot_coalesce:1; + /** * When separate shader programs are enabled, only input/outputs between * the stages of a multi-stage separate program can be safely removed diff --git a/src/compiler/nir/nir_lower_io_to_temporaries.c b/src/compiler/nir/nir_lower_io_to_temporaries.c index d2b069d3d68..1f1f7af62a1 100644 --- a/src/compiler/nir/nir_lower_io_to_temporaries.c +++ b/src/compiler/nir/nir_lower_io_to_temporaries.c @@ -123,6 +123,7 @@ create_shadow_temp(struct lower_io_state *state, nir_variable *var) { nir_variable *nvar = ralloc(state->shader, nir_variable); memcpy(nvar, var, sizeof *nvar); + nvar->data.cannot_coalesce = true; /* The original is now the temporary */ nir_variable *temp = var; diff --git a/src/compiler/nir/nir_opt_copy_prop_vars.c b/src/compiler/nir/nir_opt_copy_prop_vars.c index a1c8ffabf7a..c65beb22756 100644 --- a/src/compiler/nir/nir_opt_copy_prop_vars.c +++ b/src/compiler/nir/nir_opt_copy_prop_vars.c @@ -997,6 +997,14 @@ copy_prop_vars_block(struct copy_prop_var_state *state, }; } + nir_variable *src_var = nir_deref_instr_get_variable(src); + if (src_var && src_var->data.cannot_coalesce) { + /* The source cannot be coaleseced, which means we can't propagate + * this copy. + */ + break; + } + struct copy_entry *dst_entry = get_entry_and_kill_aliases(copies, dst, full_mask); value_set_from_value(&dst_entry->src, &value, 0, full_mask); -- 2.30.2