diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/nir/nir.h | 2 | ||||
-rw-r--r-- | src/compiler/nir/nir_opt_gcm.c | 29 |
2 files changed, 25 insertions, 6 deletions
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index c1cf94001f6..ff7c422a6ea 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -2587,7 +2587,7 @@ bool nir_opt_dce(nir_shader *shader); bool nir_opt_dead_cf(nir_shader *shader); -void nir_opt_gcm(nir_shader *shader); +bool nir_opt_gcm(nir_shader *shader, bool value_number); bool nir_opt_peephole_select(nir_shader *shader); diff --git a/src/compiler/nir/nir_opt_gcm.c b/src/compiler/nir/nir_opt_gcm.c index 02a93489eba..77eb8e6da5a 100644 --- a/src/compiler/nir/nir_opt_gcm.c +++ b/src/compiler/nir/nir_opt_gcm.c @@ -26,6 +26,7 @@ */ #include "nir.h" +#include "nir_instr_set.h" /* * Implements Global Code Motion. A description of GCM can be found in @@ -451,8 +452,8 @@ gcm_place_instr(nir_instr *instr, struct gcm_state *state) block_info->last_instr = instr; } -static void -opt_gcm_impl(nir_function_impl *impl) +static bool +opt_gcm_impl(nir_function_impl *impl, bool value_number) { struct gcm_state state; @@ -470,6 +471,18 @@ opt_gcm_impl(nir_function_impl *impl) gcm_pin_instructions_block(block, &state); } + bool progress = false; + if (value_number) { + struct set *gvn_set = nir_instr_set_create(NULL); + foreach_list_typed_safe(nir_instr, instr, node, &state.instrs) { + if (nir_instr_set_add_or_rewrite(gvn_set, instr)) { + nir_instr_remove(instr); + progress = true; + } + } + nir_instr_set_destroy(gvn_set); + } + foreach_list_typed(nir_instr, instr, node, &state.instrs) gcm_schedule_early_instr(instr, &state); @@ -486,13 +499,19 @@ opt_gcm_impl(nir_function_impl *impl) nir_metadata_preserve(impl, nir_metadata_block_index | nir_metadata_dominance); + + return progress; } -void -nir_opt_gcm(nir_shader *shader) +bool +nir_opt_gcm(nir_shader *shader, bool value_number) { + bool progress = false; + nir_foreach_function(function, shader) { if (function->impl) - opt_gcm_impl(function->impl); + progress |= opt_gcm_impl(function->impl, value_number); } + + return progress; } |