pan/midgard: Add dead move elimination pass
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Thu, 25 Jul 2019 21:43:32 +0000 (14:43 -0700)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Fri, 26 Jul 2019 15:37:08 +0000 (08:37 -0700)
This is a special case of DCE designed to run after the out-of-ssa pass
to cleanup special register lowering.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
src/panfrost/midgard/compiler.h
src/panfrost/midgard/midgard_opt_dce.c

index 86b6e1754542baec52064e9c39409da40481f0f7..32714d78d74add853d14ecad220c5ce60737b622 100644 (file)
@@ -503,5 +503,6 @@ bool midgard_opt_copy_prop(compiler_context *ctx, midgard_block *block);
 bool midgard_opt_combine_projection(compiler_context *ctx, midgard_block *block);
 bool midgard_opt_varying_projection(compiler_context *ctx, midgard_block *block);
 bool midgard_opt_dead_code_eliminate(compiler_context *ctx, midgard_block *block);
+bool midgard_opt_dead_move_eliminate(compiler_context *ctx, midgard_block *block);
 
 #endif
index 6621c2fe2ddb0844ee4da4e23fee598f52e51d0d..698650ab8ade01f258ba0d5eb6b092c101e96150 100644 (file)
@@ -44,3 +44,46 @@ midgard_opt_dead_code_eliminate(compiler_context *ctx, midgard_block *block)
 
         return progress;
 }
+
+/* Removes dead moves, that is, moves with a destination overwritten before
+ * being read. Normally handled implicitly as part of DCE, but this has to run
+ * after the out-of-SSA pass */
+
+bool
+midgard_opt_dead_move_eliminate(compiler_context *ctx, midgard_block *block)
+{
+        bool progress = false;
+
+        mir_foreach_instr_in_block_safe(block, ins) {
+                if (ins->type != TAG_ALU_4) continue;
+                if (ins->compact_branch) continue;
+                if (!OP_IS_MOVE(ins->alu.op)) continue;
+
+                /* Check if it's overwritten in this block before being read */
+                bool overwritten = false;
+
+                mir_foreach_instr_in_block_from(block, q, mir_next_op(ins)) {
+                        if (q->compact_branch) continue;
+
+                        /* Check if used */
+                        if (mir_has_arg(q, ins->ssa_args.dest))
+                                break;
+
+                        /* Check if overwritten */
+                        if (q->ssa_args.dest == ins->ssa_args.dest) {
+                                /* Special case to vec4; component tracking is
+                                 * harder */
+
+                                overwritten = (q->mask == 0xF);
+                                break;
+                        }
+                }
+
+                if (overwritten) {
+                        mir_remove_instruction(ins);
+                        progress = true;
+                }
+        }
+
+        return progress;
+}