From: Alyssa Rosenzweig Date: Thu, 25 Jul 2019 21:43:32 +0000 (-0700) Subject: pan/midgard: Add dead move elimination pass X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=10324095d2ee0e897a1bc41762d8fd8614ecd634;p=mesa.git pan/midgard: Add dead move elimination pass 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 --- diff --git a/src/panfrost/midgard/compiler.h b/src/panfrost/midgard/compiler.h index 86b6e175454..32714d78d74 100644 --- a/src/panfrost/midgard/compiler.h +++ b/src/panfrost/midgard/compiler.h @@ -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 diff --git a/src/panfrost/midgard/midgard_opt_dce.c b/src/panfrost/midgard/midgard_opt_dce.c index 6621c2fe2dd..698650ab8ad 100644 --- a/src/panfrost/midgard/midgard_opt_dce.c +++ b/src/panfrost/midgard/midgard_opt_dce.c @@ -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; +}