}
bool
-mir_nontrivial_mod(midgard_vector_alu_src src, bool is_int, unsigned mask)
+mir_nontrivial_raw_mod(midgard_vector_alu_src src, bool is_int)
{
- /* abs or neg */
- if (!is_int && src.mod) return true;
+ if (is_int)
+ return src.mod == midgard_int_shift;
+ else
+ return src.mod;
+}
- /* Other int mods don't matter in isolation */
- if (is_int && src.mod == midgard_int_shift) return true;
+bool
+mir_nontrivial_mod(midgard_vector_alu_src src, bool is_int, unsigned mask)
+{
+ if (mir_nontrivial_raw_mod(src, is_int)) return true;
/* size-conversion */
if (src.half) return true;
return false;
}
-
bool
mir_nontrivial_source2_mod(midgard_instruction *ins)
{
bool is_int = midgard_is_integer_op(ins->alu.op);
unsigned mod = ins->alu.outmod;
+ /* Pseudo-outmod */
+ if (ins->invert)
+ return true;
+
/* Type conversion is a sort of outmod */
if (ins->alu.dest_override != midgard_dest_override_none)
return true;
return false;
}
+
+/* Is a node written before a given instruction? */
+
+bool
+mir_is_written_before(compiler_context *ctx, midgard_instruction *ins, unsigned node)
+{
+ if ((node < 0) || (node >= SSA_FIXED_MINIMUM))
+ return true;
+
+ mir_foreach_instr_global(ctx, q) {
+ if (q == ins)
+ break;
+
+ if (q->ssa_args.dest == node)
+ return true;
+ }
+
+ return false;
+}
+
+/* Creates a mask of the components of a node read by an instruction, by
+ * analyzing the swizzle with respect to the instruction's mask. E.g.:
+ *
+ * fadd r0.xz, r1.yyyy, r2.zwyx
+ *
+ * will return a mask of Z/Y for r2
+ */
+
+static unsigned
+mir_mask_of_read_components_single(unsigned src, unsigned outmask)
+{
+ midgard_vector_alu_src s = vector_alu_from_unsigned(src);
+ unsigned mask = 0;
+
+ for (unsigned c = 0; c < 4; ++c) {
+ if (!(outmask & (1 << c))) continue;
+
+ unsigned comp = (s.swizzle >> (2*c)) & 3;
+ mask |= (1 << comp);
+ }
+
+ return mask;
+}
+
+unsigned
+mir_mask_of_read_components(midgard_instruction *ins, unsigned node)
+{
+ assert(ins->type == TAG_ALU_4);
+
+ unsigned mask = 0;
+
+ if (ins->ssa_args.src0 == node)
+ mask |= mir_mask_of_read_components_single(ins->alu.src1, ins->mask);
+
+ if (ins->ssa_args.src1 == node && !ins->ssa_args.inline_constant)
+ mask |= mir_mask_of_read_components_single(ins->alu.src2, ins->mask);
+
+ return mask;
+}