panfrost: Build midgard_pack.h via meson
[mesa.git] / src / panfrost / midgard / midgard_opt_copy_prop.c
index 32d830d6ac74f340deb041d431d507cfc17c71c1..331c3d1dfa272129392f8194cab457438df35406 100644 (file)
 #include "compiler.h"
 #include "midgard_ops.h"
 
+/* Special case for copypropagating the results of vectors */
+
+static bool
+midgard_opt_copy_prop_reg(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 (!OP_IS_MOVE(ins->op)) continue;
+                if (ins->is_pack) continue;
+
+                unsigned from = ins->src[1];
+                unsigned to = ins->dest;
+
+                if (!(to & PAN_IS_REG))  continue;
+                if (from & PAN_IS_REG) continue;
+
+                if (ins->has_inline_constant) continue;
+                if (ins->has_constants) continue;
+                if (mir_nontrivial_mod(ins, 1, true)) continue;
+                if (mir_nontrivial_outmod(ins)) continue;
+                if (!mir_single_use(ctx, from)) continue;
+
+                /* Ensure mask is continguous from 0 */
+                if (!(ins->mask & (1 << COMPONENT_X))) continue;
+                if (ins->mask & (ins->mask + 1)) continue;
+
+                mir_rewrite_index_dst(ctx, from, ins->dest);
+                mir_remove_instruction(ins);
+                progress |= true;
+        }
+
+        return progress;
+}
+
 bool
 midgard_opt_copy_prop(compiler_context *ctx, midgard_block *block)
 {
@@ -32,31 +68,66 @@ midgard_opt_copy_prop(compiler_context *ctx, midgard_block *block)
 
         mir_foreach_instr_in_block_safe(block, ins) {
                 if (ins->type != TAG_ALU_4) continue;
-                if (!OP_IS_MOVE(ins->alu.op)) continue;
+                if (!OP_IS_MOVE(ins->op)) continue;
+                if (ins->is_pack) continue;
 
-                unsigned from = ins->ssa_args.src1;
-                unsigned to = ins->ssa_args.dest;
+                unsigned from = ins->src[1];
+                unsigned to = ins->dest;
 
                 /* We only work on pure SSA */
 
-                if (to >= SSA_FIXED_MINIMUM) continue;
-                if (from >= SSA_FIXED_MINIMUM) continue;
-                if (to >= ctx->func->impl->ssa_alloc) continue;
-                if (from >= ctx->func->impl->ssa_alloc) continue;
+                if (to & PAN_IS_REG) continue;
+                if (from & PAN_IS_REG) continue;
 
                 /* Constant propagation is not handled here, either */
-                if (ins->ssa_args.inline_constant) continue;
+                if (ins->has_inline_constant) continue;
                 if (ins->has_constants) continue;
 
                 /* Modifier propagation is not handled here */
-                if (mir_nontrivial_source2_mod(ins)) continue;
+                if (mir_nontrivial_mod(ins, 1, false)) continue;
                 if (mir_nontrivial_outmod(ins)) continue;
 
-                /* We're clear -- rewrite */
-                mir_rewrite_index_src(ctx, to, from);
+                /* Shortened arguments (bias for textures, extra load/store
+                 * arguments, etc.) do not get a swizzle, only a start
+                 * component and even that is restricted. Fragment writeout
+                 * doesn't even get that much */
+
+                bool skip = false;
+
+                mir_foreach_instr_global(ctx, q) {
+                        bool is_tex = q->type == TAG_TEXTURE_4;
+                        bool is_ldst = q->type == TAG_LOAD_STORE_4;
+                        bool is_branch = q->compact_branch;
+
+                        if (!(is_tex || is_ldst || is_branch)) continue;
+
+                        /* For textures, we get a real swizzle for the
+                         * coordinate and the content. For stores, we get one.
+                         * For loads, we get none. */
+
+                        unsigned start =
+                                is_tex ? 2 :
+                                OP_IS_STORE(q->op) ? 1 : 0;
+
+                        mir_foreach_src(q, s) {
+                                if ((s >= start) && q->src[s] == to) {
+                                        skip = true;
+                                        break;
+                                }
+                        }
+                }
+
+                if (skip)
+                        continue;
+
+                if (ctx->blend_src1 == to)
+                        ctx->blend_src1 = from;
+
+                /* We're clear -- rewrite, composing the swizzle */
+                mir_rewrite_index_src_swizzle(ctx, to, from, ins->swizzle[1]);
                 mir_remove_instruction(ins);
                 progress |= true;
         }
 
-        return progress;
+        return progress | midgard_opt_copy_prop_reg(ctx, block);
 }