summaryrefslogtreecommitdiffstats
path: root/src/compiler/nir
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/nir')
-rw-r--r--src/compiler/nir/nir.h2
-rw-r--r--src/compiler/nir/nir_opt_gcm.c29
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;
}