diff options
author | Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> | 2019-07-25 14:43:32 -0700 |
---|---|---|
committer | Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> | 2019-07-26 08:37:08 -0700 |
commit | 10324095d2ee0e897a1bc41762d8fd8614ecd634 (patch) | |
tree | 13787791d7d8afc296bed3dcab8a91798e3f61be | |
parent | 082485d663301bbd1dfb14d9da11735f51c02fd0 (diff) | |
download | mesa-10324095d2ee0e897a1bc41762d8fd8614ecd634.tar.gz |
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 <alyssa.rosenzweig@collabora.com>
-rw-r--r-- | src/panfrost/midgard/compiler.h | 1 | ||||
-rw-r--r-- | src/panfrost/midgard/midgard_opt_dce.c | 43 |
2 files changed, 44 insertions, 0 deletions
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; +} |