Mesa (master): pan/mdg: Allow scheduling "x + x" to multipliers

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jun 17 13:12:06 UTC 2020


Module: Mesa
Branch: master
Commit: 6318e461416feacd352b611fd28e698dd654c6a4
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=6318e461416feacd352b611fd28e698dd654c6a4

Author: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
Date:   Fri Jun 12 17:24:02 2020 -0400

pan/mdg: Allow scheduling "x + x" to multipliers

One of the neat things with Midgard's wacky VLIW... on VADD/SADD this is
(x + x) literally, on VMUL/SMUL/VLUT this is (x * 2.0) where the 2.0 is
exactly representable in FP16 so it fits nicely as an inline constant.
So we don't need to restrict its scheduling.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5475>

---

 src/panfrost/midgard/midgard_schedule.c | 53 +++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/src/panfrost/midgard/midgard_schedule.c b/src/panfrost/midgard/midgard_schedule.c
index 5a12d11045e..7ebcc2d4ebb 100644
--- a/src/panfrost/midgard/midgard_schedule.c
+++ b/src/panfrost/midgard/midgard_schedule.c
@@ -26,6 +26,7 @@
 #include "midgard_quirks.h"
 #include "util/u_memory.h"
 #include "util/u_math.h"
+#include "util/half_float.h"
 
 /* Scheduling for Midgard is complicated, to say the least. ALU instructions
  * must be grouped into VLIW bundles according to following model:
@@ -508,12 +509,61 @@ mir_pipeline_count(midgard_instruction *ins)
         return DIV_ROUND_UP(bytecount, 16);
 }
 
+/* Matches FADD x, x with modifiers compatible. Since x + x = x * 2, for
+ * any x including of the form f(y) for some swizzle/abs/neg function f */
+
+static bool
+mir_is_add_2(midgard_instruction *ins)
+{
+        if (ins->alu.op != midgard_alu_op_fadd)
+                return false;
+
+        if (ins->src[0] != ins->src[1])
+                return false;
+
+        if (ins->src_types[0] != ins->src_types[1])
+                return false;
+
+        for (unsigned i = 0; i < MIR_VEC_COMPONENTS; ++i) {
+                if (ins->swizzle[0][i] != ins->swizzle[1][i])
+                        return false;
+        }
+
+        if (ins->src_abs[0] != ins->src_abs[1])
+                return false;
+
+        if (ins->src_neg[0] != ins->src_neg[1])
+                return false;
+
+        return true;
+}
+
+static void
+mir_adjust_unit(midgard_instruction *ins, unsigned unit)
+{
+        /* FADD x, x = FMUL x, #2 */
+        if (mir_is_add_2(ins) && (unit & (UNITS_MUL | UNIT_VLUT))) {
+                ins->alu.op = midgard_alu_op_fmul;
+
+                ins->src[1] = ~0;
+                ins->src_abs[1] = false;
+                ins->src_neg[1] = false;
+
+                ins->has_inline_constant = true;
+                ins->inline_constant = _mesa_float_to_half(2.0);
+        }
+}
+
 static unsigned
 mir_has_unit(midgard_instruction *ins, unsigned unit)
 {
         if (alu_opcode_props[ins->alu.op].props & unit)
                 return true;
 
+        /* FADD x, x can run on any adder or any multiplier */
+        if (mir_is_add_2(ins))
+                return true;
+
         return false;
 }
 
@@ -616,6 +666,9 @@ mir_choose_instruction(
                 if (ldst)
                         predicate->pipeline_count += mir_pipeline_count(instructions[best_index]);
 
+                if (alu)
+                        mir_adjust_unit(instructions[best_index], unit);
+
                 /* Once we schedule a conditional, we can't again */
                 predicate->no_cond |= best_conditional;
         }



More information about the mesa-commit mailing list