diff --git a/src/compiler/nir/nir_opt_copy_prop_vars.c b/src/compiler/nir/nir_opt_copy_prop_vars.c index 91c8277658b..40829a6cc1d 100644 --- a/src/compiler/nir/nir_opt_copy_prop_vars.c +++ b/src/compiler/nir/nir_opt_copy_prop_vars.c @@ -905,6 +905,13 @@ copy_prop_vars_block(struct copy_prop_var_state *state, nir_deref_instr *src = nir_src_as_deref(intrin->src[0]); + /* If this is a load from a read-only mode, then all this pass would + * do is combine redundant loads and CSE should be more efficient for + * that. + */ + if (nir_deref_mode_must_be(src, nir_var_read_only_modes & ~nir_var_vec_indexable_modes)) + break; + /* Direct array_derefs of vectors operate on the vectors (the parent * deref). Indirects will be handled like other derefs. */ diff --git a/src/compiler/nir/nir_opt_dead_write_vars.c b/src/compiler/nir/nir_opt_dead_write_vars.c index ba98a2d202e..dc9414e05e2 100644 --- a/src/compiler/nir/nir_opt_dead_write_vars.c +++ b/src/compiler/nir/nir_opt_dead_write_vars.c @@ -109,7 +109,7 @@ update_unused_writes(struct util_dynarray *unused_writes, } static bool -remove_dead_write_vars_local(void *mem_ctx, nir_block *block) +remove_dead_write_vars_local(void *mem_ctx, nir_shader *shader, nir_block *block) { bool progress = false; @@ -171,6 +171,8 @@ remove_dead_write_vars_local(void *mem_ctx, nir_block *block) case nir_intrinsic_load_deref: { nir_deref_instr *src = nir_src_as_deref(intrin->src[0]); + if (nir_deref_mode_must_be(src, nir_var_read_only_modes)) + break; clear_unused_for_read(&unused_writes, src); break; } @@ -231,14 +233,14 @@ remove_dead_write_vars_local(void *mem_ctx, nir_block *block) } static bool -remove_dead_write_vars_impl(void *mem_ctx, nir_function_impl *impl) +remove_dead_write_vars_impl(void *mem_ctx, nir_shader *shader, nir_function_impl *impl) { bool progress = false; nir_metadata_require(impl, nir_metadata_block_index); nir_foreach_block(block, impl) - progress |= remove_dead_write_vars_local(mem_ctx, block); + progress |= remove_dead_write_vars_local(mem_ctx, shader, block); if (progress) { nir_metadata_preserve(impl, nir_metadata_block_index | @@ -259,7 +261,7 @@ nir_opt_dead_write_vars(nir_shader *shader) nir_foreach_function(function, shader) { if (!function->impl) continue; - progress |= remove_dead_write_vars_impl(mem_ctx, function->impl); + progress |= remove_dead_write_vars_impl(mem_ctx, shader, function->impl); } ralloc_free(mem_ctx); diff --git a/src/compiler/nir/tests/vars_tests.cpp b/src/compiler/nir/tests/vars_tests.cpp index f8b08ae2f1e..91bd6974cb6 100644 --- a/src/compiler/nir/tests/vars_tests.cpp +++ b/src/compiler/nir/tests/vars_tests.cpp @@ -218,7 +218,7 @@ TEST_F(nir_redundant_load_vars_test, duplicated_load) { /* Load a variable twice in the same block. One should be removed. */ - nir_variable *in = create_int(nir_var_shader_in, "in"); + nir_variable *in = create_int(nir_var_mem_ssbo, "in"); nir_variable **out = create_many_int(nir_var_shader_out, "out", 2); nir_store_var(b, out[0], nir_load_var(b, in), 1); @@ -240,7 +240,7 @@ TEST_F(nir_redundant_load_vars_test, duplicated_load_volatile) { /* Load a variable twice in the same block. One should be removed. */ - nir_variable *in = create_int(nir_var_shader_in, "in"); + nir_variable *in = create_int(nir_var_mem_ssbo, "in"); nir_variable **out = create_many_int(nir_var_shader_out, "out", 3); /* Volatile prevents us from eliminating a load by combining it with @@ -275,7 +275,7 @@ TEST_F(nir_redundant_load_vars_test, duplicated_load_in_two_blocks) { /* Load a variable twice in different blocks. One should be removed. */ - nir_variable *in = create_int(nir_var_shader_in, "in"); + nir_variable *in = create_int(nir_var_mem_ssbo, "in"); nir_variable **out = create_many_int(nir_var_shader_out, "out", 2); nir_store_var(b, out[0], nir_load_var(b, in), 1);