From: Caio Marcelo de Oliveira Filho Date: Tue, 8 Jan 2019 23:53:02 +0000 (-0800) Subject: nir/copy_prop_vars: don't get confused by array_deref of vectors X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=60d9bb9ff50b1bbaf917cc9fb40dbab71e180add;p=mesa.git nir/copy_prop_vars: don't get confused by array_deref of vectors For now these derefs are not handled, so don't let these get into the copies list -- which would cause wrong propagations. For load_derefs, do nothing. For store_derefs, invalidate whatever the store is writing to. For copy_derefs, invalidate whatever the copy is writing to. These cases will happen once derefs to SSBOs/UBOs are kept around long enough to get optimized by copy_prop_vars. Reviewed-by: Jason Ekstrand --- diff --git a/src/compiler/nir/nir_opt_copy_prop_vars.c b/src/compiler/nir/nir_opt_copy_prop_vars.c index 392fef407cf..a7b85f4cc9b 100644 --- a/src/compiler/nir/nir_opt_copy_prop_vars.c +++ b/src/compiler/nir/nir_opt_copy_prop_vars.c @@ -616,6 +616,15 @@ invalidate_copies_for_cf_node(struct copy_prop_var_state *state, } } +static bool +is_array_deref_of_vector(nir_deref_instr *deref) +{ + if (deref->deref_type != nir_deref_type_array) + return false; + nir_deref_instr *parent = nir_deref_instr_parent(deref); + return glsl_type_is_vector(parent->type); +} + static void copy_prop_vars_block(struct copy_prop_var_state *state, nir_builder *b, nir_block *block, @@ -651,6 +660,11 @@ copy_prop_vars_block(struct copy_prop_var_state *state, case nir_intrinsic_load_deref: { nir_deref_instr *src = nir_src_as_deref(intrin->src[0]); + if (is_array_deref_of_vector(src)) { + /* Not handled yet. This load won't invalidate existing copies. */ + break; + } + struct copy_entry *src_entry = lookup_entry_for_deref(copies, src, nir_derefs_a_contains_b_bit); struct value value; @@ -720,6 +734,11 @@ copy_prop_vars_block(struct copy_prop_var_state *state, * store is redundant so remove it. */ nir_instr_remove(instr); + } else if (is_array_deref_of_vector(dst)) { + /* Not handled yet. Writing into an element of 'dst' invalidates + * any related entries in copies. + */ + kill_aliases(copies, nir_deref_instr_parent(dst), 0xf); } else { struct value value = { .is_ssa = true @@ -747,6 +766,15 @@ copy_prop_vars_block(struct copy_prop_var_state *state, continue; } + if (is_array_deref_of_vector(src) || is_array_deref_of_vector(dst)) { + /* Cases not handled yet. Writing into an element of 'dst' + * invalidates any related entries in copies. Reading from 'src' + * doesn't invalidate anything, so no action needed for it. + */ + kill_aliases(copies, dst, 0xf); + break; + } + struct copy_entry *src_entry = lookup_entry_for_deref(copies, src, nir_derefs_a_contains_b_bit); struct value value;