[13/13] panfrost/midgard: .pos propagation

Submitted by Alyssa Rosenzweig on May 26, 2019, 2:39 a.m.

Details

Message ID 20190526023924.6243-14-alyssa@rosenzweig.io
State New
Headers show
Series "panfrost/midgard: RA improvements (esp. RA)" ( rev: 1 ) in Mesa

Not browsing as part of any series.

Commit Message

Alyssa Rosenzweig May 26, 2019, 2:39 a.m.
A previous optimization converts fmax(x, 0.0) instructions to fmov.pos.
This pass then propagates the .pos from the move up to the source
instruction (when possible). From there, copy propagation will eliminate
the move.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
---
 .../panfrost/midgard/midgard_compile.c        | 80 +++++++++++++++++--
 1 file changed, 72 insertions(+), 8 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/gallium/drivers/panfrost/midgard/midgard_compile.c b/src/gallium/drivers/panfrost/midgard/midgard_compile.c
index 324e1b01f5f..6043dac608f 100644
--- a/src/gallium/drivers/panfrost/midgard/midgard_compile.c
+++ b/src/gallium/drivers/panfrost/midgard/midgard_compile.c
@@ -1717,6 +1717,18 @@  mir_nontrivial_mod(midgard_vector_alu_src src, bool is_int, unsigned mask)
         return false;
 }
 
+static bool
+mir_nontrivial_source2_mod(midgard_instruction *ins)
+{
+        unsigned mask = squeeze_writemask(ins->alu.mask);
+        bool is_int = midgard_is_integer_op(ins->alu.op);
+
+        midgard_vector_alu_src src2 =
+                vector_alu_from_unsigned(ins->alu.src2);
+
+        return mir_nontrivial_mod(src2, is_int, mask);
+}
+
 static bool
 midgard_opt_copy_prop(compiler_context *ctx, midgard_block *block)
 {
@@ -1740,14 +1752,7 @@  midgard_opt_copy_prop(compiler_context *ctx, midgard_block *block)
                 if (ins->ssa_args.inline_constant) continue;
                 if (ins->has_constants) continue;
 
-                /* Also, if the move has side effects, we're helpless */
-
-                midgard_vector_alu_src src =
-                        vector_alu_from_unsigned(ins->alu.src2);
-                unsigned mask = squeeze_writemask(ins->alu.mask);
-                bool is_int = midgard_is_integer_op(ins->alu.op);
-
-                if (mir_nontrivial_mod(src, is_int, mask)) continue;
+                if (mir_nontrivial_source2_mod(ins)) continue;
                 if (ins->alu.outmod != midgard_outmod_none) continue;
 
                 /* We're clear -- rewrite */
@@ -1759,6 +1764,64 @@  midgard_opt_copy_prop(compiler_context *ctx, midgard_block *block)
         return progress;
 }
 
+/* fmov.pos is an idiom for fpos. Propoagate the .pos up to the source, so then
+ * the move can be propagated away entirely */
+
+static bool
+mir_compose_outmod(midgard_outmod *outmod, midgard_outmod comp)
+{
+        /* Nothing to do */
+        if (comp == midgard_outmod_none)
+                return true;
+
+        if (*outmod == midgard_outmod_none) {
+                *outmod = comp;
+                return true;
+        }
+
+        /* TODO: Compose rules */
+        return false;
+}
+
+static bool
+midgard_opt_pos_propagate(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->alu.op != midgard_alu_op_fmov) continue;
+                if (ins->alu.outmod != midgard_outmod_pos) continue;
+
+                /* TODO: Registers? */
+                unsigned src = ins->ssa_args.src1;
+                if (src >= ctx->func->impl->ssa_alloc) continue;
+
+                /* There might be a source modifier, too */
+                if (mir_nontrivial_source2_mod(ins)) continue;
+
+                /* Backpropagate the modifier */
+                mir_foreach_instr_in_block_from_rev(block, v, mir_prev_op(ins)) {
+                        if (v->type != TAG_ALU_4) continue;
+                        if (v->ssa_args.dest != src) continue;
+
+                        midgard_outmod temp = v->alu.outmod;
+                        progress |= mir_compose_outmod(&temp, ins->alu.outmod);
+
+                        /* Throw in the towel.. */
+                        if (!progress) break;
+
+                        /* Otherwise, transfer the modifier */
+                        v->alu.outmod = temp;
+                        ins->alu.outmod = midgard_outmod_none;
+
+                        break;
+                }
+        }
+
+        return progress;
+}
+
 static bool
 midgard_opt_copy_prop_tex(compiler_context *ctx, midgard_block *block)
 {
@@ -2356,6 +2419,7 @@  midgard_compile_shader_nir(nir_shader *nir, midgard_program *program, bool is_bl
                 progress = false;
 
                 mir_foreach_block(ctx, block) {
+                        progress |= midgard_opt_pos_propagate(ctx, block);
                         progress |= midgard_opt_copy_prop(ctx, block);
                         progress |= midgard_opt_copy_prop_tex(ctx, block);
                         progress |= midgard_opt_dead_code_eliminate(ctx, block);