<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Oct 23, 2015 at 10:55 AM, Eduardo Lima Mitev <span dir="ltr"><<a href="mailto:elima@igalia.com" target="_blank">elima@igalia.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">When both fadd and fmul instructions have at least one operand that is a<br>
constant and it is only used once, the total number of instructions can<br>
be reduced from 3 (1 ffma + 2 load_const) to 2 (1 fmul + 1 fadd); because<br>
the constants will be progagated as immediate operands of fmul and fadd.<br>
<br>
This patch detects these situations and prevents fusing fmul+fadd into ffma.<br>
<br>
Shader-db results on i965 Haswell:<br>
<br>
total instructions in shared programs: 6235835 -> 6225895 (-0.16%)<br>
instructions in affected programs:     1124094 -> 1114154 (-0.88%)<br>
total loops in shared programs:        1979 -> 1979 (0.00%)<br>
helped:                                7612<br>
HURT:                                  843<br>
GAINED:                                4<br>
LOST:                                  0<br>
---<br>
 .../drivers/dri/i965/brw_nir_opt_peephole_ffma.c   | 31 ++++++++++++++++++++++<br>
 1 file changed, 31 insertions(+)<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/brw_nir_opt_peephole_ffma.c b/src/mesa/drivers/dri/i965/brw_nir_opt_peephole_ffma.c<br>
index a8448e7..c7fc15a 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_nir_opt_peephole_ffma.c<br>
+++ b/src/mesa/drivers/dri/i965/brw_nir_opt_peephole_ffma.c<br>
@@ -133,6 +133,28 @@ get_mul_for_src(nir_alu_src *src, int num_components,<br>
    return alu;<br>
 }<br>
<br>
+/**<br>
+ * Given a list of (at least two) nir_alu_src's, tells if any of them is a<br>
+ * constant value and is used only once.<br>
+ */<br>
+static bool<br>
+any_alu_src_is_a_constant(nir_alu_src srcs[])<br>
+{<br>
+   for (unsigned i = 0; i < 2; i++) {<br>
+      if (srcs[i].src.ssa->parent_instr->type == nir_instr_type_load_const) {<br>
+         nir_load_const_instr *load_const =<br>
+            nir_instr_as_load_const (srcs[i].src.ssa->parent_instr);<br>
+<br>
+         if (list_is_single(&load_const->def.uses) &&<br>
+             list_empty(&load_const->def.if_uses)) {<br>
+            return true;<br>
+         }<br>
+      }<br>
+   }<br>
+<br>
+   return false;<br>
+}<br>
+<br></blockquote><div><br></div><div>The comment above this functions reads "Given a list of (at least two) nir_alu_src's...", but the function checks exactly two. Was it your intention to support lists with size > 2?<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
 static bool<br>
 brw_nir_opt_peephole_ffma_block(nir_block *block, void *void_state)<br>
 {<br>
@@ -183,6 +205,15 @@ brw_nir_opt_peephole_ffma_block(nir_block *block, void *void_state)<br>
       mul_src[0] = mul->src[0].src.ssa;<br>
       mul_src[1] = mul->src[1].src.ssa;<br>
<br>
+      /* If any of the operands of the fmul and any of the fadd is a constant,<br>
+       * we bypass because it will be more efficient as the constants will be<br>
+       * propagated as operands, potentially saving two load_const instructions.<br>
+       */<br>
+      if (any_alu_src_is_a_constant(mul->src) &&<br>
+          any_alu_src_is_a_constant(add->src)) {<br>
+         continue;<br>
+      }<br>
+<br>
       if (abs) {<br>
          for (unsigned i = 0; i < 2; i++) {<br>
             nir_alu_instr *abs = nir_alu_instr_create(state->mem_ctx,<br>
<span class=""><font color="#888888">--<br>
2.5.3<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>