pan/midgard: Add mir_mask_of_read_components helper
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Fri, 26 Jul 2019 16:37:28 +0000 (09:37 -0700)
committerAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Fri, 26 Jul 2019 16:37:28 +0000 (09:37 -0700)
This facilitates analysis of vec4 registers (after going out-of-SSA).

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
src/panfrost/midgard/compiler.h
src/panfrost/midgard/mir.c

index 528dfacdc3bff7054d59f92a0d50639bb4d6c6ea..84a00fb0174cc64cadae912a6501a9a08986938e 100644 (file)
@@ -382,6 +382,7 @@ bool mir_single_use(compiler_context *ctx, unsigned value);
 bool mir_special_index(compiler_context *ctx, unsigned idx);
 unsigned mir_use_count(compiler_context *ctx, unsigned value);
 bool mir_is_written_before(compiler_context *ctx, midgard_instruction *ins, unsigned node);
+unsigned mir_mask_of_read_components(midgard_instruction *ins, unsigned node);
 
 /* MIR printing */
 
index 61427e7c3d50da10324906a85bd297b36d52d490..75da2fb0864908e7cdde90e13bf939149161d946 100644 (file)
@@ -194,3 +194,43 @@ mir_is_written_before(compiler_context *ctx, midgard_instruction *ins, unsigned
 
         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;
+}