[Mesa-dev] [PATCH 07/21] etnaviv: nir: merge mov of result into alu op

Philipp Zabel p.zabel at pengutronix.de
Tue Jun 5 14:38:31 UTC 2018


Remove unnecessary mov instructions. If the destination of an ALU
instruction is only used in a following mov, merge that mov into the ALU
instruction.

Signed-off-by: Philipp Zabel <p.zabel at pengutronix.de>
Signed-off-by: Michael Tretter <m.tretter at pengutronix.de>
---
 src/gallium/drivers/etnaviv/etnaviv_nir.c | 43 +++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/src/gallium/drivers/etnaviv/etnaviv_nir.c b/src/gallium/drivers/etnaviv/etnaviv_nir.c
index 3b29ea9a0e76..b73d4be31bc6 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_nir.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_nir.c
@@ -156,6 +156,48 @@ etna_hardwire_io_position(nir_shader *shader)
    }
 }
 
+/* To be called after register assignment and the vec_to_movs lowering step.
+ * Merges ALU instructions whose destination is only used by the following
+ * mov instruction with that instruction.
+ */
+static void
+etna_opt_merge_alu_mov_pair(nir_shader *shader)
+{
+   nir_foreach_function(function, shader) {
+      nir_foreach_block(block, function->impl) {
+         nir_foreach_instr_safe(instr, block) {
+            if (instr->type != nir_instr_type_alu)
+               continue;
+
+            nir_alu_instr *alu = nir_instr_as_alu(instr);
+            if (alu->op != nir_op_imov)
+               continue;
+
+            nir_instr *prev_instr = nir_instr_prev(instr);
+            if (!prev_instr || prev_instr->type != nir_instr_type_alu)
+               continue;
+
+            nir_alu_instr *prev_alu = nir_instr_as_alu(prev_instr);
+
+            if (prev_alu->dest.dest.is_ssa ||
+                alu->src[0].src.is_ssa ||
+                alu->dest.dest.is_ssa ||
+                prev_alu->dest.dest.reg.reg != alu->src[0].src.reg.reg ||
+                prev_alu->dest.write_mask != alu->dest.write_mask)
+               continue;
+
+            /* FIXME: there mustn't be any later uses of prev_instr->dest */
+
+            nir_instr_rewrite_dest(prev_instr, &prev_alu->dest.dest,
+                                   alu->dest.dest);
+            nir_instr_remove(instr);
+         }
+      }
+      nir_metadata_preserve(function->impl, nir_metadata_block_index |
+                                            nir_metadata_dominance);
+   }
+}
+
 /* Move const loads, input load intrinsics, and uniform load intrinsics to the
  * beginning of the function implementation.
  *
@@ -640,6 +682,7 @@ etna_optimize_nir(struct etna_shader *shader,
     */
    NIR_PASS_V(s, nir_move_vec_src_uses_to_dest);
    NIR_PASS_V(s, nir_lower_vec_to_movs);
+   NIR_PASS_V(s, etna_opt_merge_alu_mov_pair);
 
    nir_sweep(s);
 
-- 
2.17.1



More information about the mesa-dev mailing list