#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)
{
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);
}