<div dir="ltr">Reviewed-by: Jason Ekstrand <<a href="mailto:jason.ekstrand@intel.com">jason.ekstrand@intel.com</a>></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Jan 22, 2015 at 3:41 AM, Kenneth Graunke <span dir="ltr"><<a href="mailto:kenneth@whitecape.org" target="_blank">kenneth@whitecape.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Matt and I noticed that one of the shaders hurt by INTEL_USE_NIR=1 had<br>
load_input and load_uniform intrinsics repeated several times, with the<br>
same parameters, but each one generating a distinct SSA value.  This<br>
made ALU operations on those values appear distinct as well.<br>
<br>
Generating distinct SSA values is silly - these are read only variables.<br>
CSE'ing them makes everything use a single SSA value, which then allows<br>
other operations to be CSE'd away as well.<br>
<br>
Generalizing a bit, it seems like we should be able to safely CSE any<br>
intrinsics that can be eliminated and reordered.  I didn't implement<br>
support for variables for the time being.<br>
<br>
v2: Assert that info->num_variables == 0 (requested by Jason).<br>
<br>
total NIR instructions in shared programs: 2435936 -> 2023511 (-16.93%)<br>
NIR instructions in affected programs:     2413496 -> 2001071 (-17.09%)<br>
helped:                                    16872<br>
<br>
total i965 instructions in shared programs: 6028987 -> 6008427 (-0.34%)<br>
i965 instructions in affected programs:     640654 -> 620094 (-3.21%)<br>
helped:                                     2071<br>
HURT:                                       585<br>
GAINED:                                     14<br>
LOST:                                       25<br>
<br>
Signed-off-by: Kenneth Graunke <<a href="mailto:kenneth@whitecape.org">kenneth@whitecape.org</a>><br>
---<br>
 src/glsl/nir/nir_opt_cse.c | 40 ++++++++++++++++++++++++++++++++++++++--<br>
 1 file changed, 38 insertions(+), 2 deletions(-)<br>
<br>
Here's v2 of CSE for intrinsics.  Sounds like it's good to go.<br>
<br>
diff --git a/src/glsl/nir/nir_opt_cse.c b/src/glsl/nir/nir_opt_cse.c<br>
index fef1678..b3e9c0d 100644<br>
--- a/src/glsl/nir/nir_opt_cse.c<br>
+++ b/src/glsl/nir/nir_opt_cse.c<br>
@@ -112,7 +112,34 @@ nir_instrs_equal(nir_instr *instr1, nir_instr *instr2)<br>
<br>
       return true;<br>
    }<br>
-   case nir_instr_type_intrinsic:<br>
+   case nir_instr_type_intrinsic: {<br>
+      nir_intrinsic_instr *intrinsic1 = nir_instr_as_intrinsic(instr1);<br>
+      nir_intrinsic_instr *intrinsic2 = nir_instr_as_intrinsic(instr2);<br>
+      const nir_intrinsic_info *info =<br>
+         &nir_intrinsic_infos[intrinsic1->intrinsic];<br>
+<br>
+      if (intrinsic1->intrinsic != intrinsic2->intrinsic ||<br>
+          intrinsic1->num_components != intrinsic2->num_components)<br>
+         return false;<br>
+<br>
+      if (info->has_dest && intrinsic1->dest.ssa.num_components !=<br>
+                            intrinsic2->dest.ssa.num_components)<br>
+         return false;<br>
+<br>
+      for (unsigned i = 0; i < info->num_srcs; i++) {<br>
+         if (!nir_srcs_equal(intrinsic1->src[i], intrinsic2->src[i]))<br>
+            return false;<br>
+      }<br>
+<br>
+      assert(info->num_variables == 0);<br>
+<br>
+      for (unsigned i = 0; i < info->num_indices; i++) {<br>
+         if (intrinsic1->const_index[i] != intrinsic2->const_index[i])<br>
+            return false;<br>
+      }<br>
+<br>
+      return true;<br>
+   }<br>
    case nir_instr_type_call:<br>
    case nir_instr_type_jump:<br>
    case nir_instr_type_ssa_undef:<br>
@@ -151,7 +178,13 @@ nir_instr_can_cse(nir_instr *instr)<br>
       return true;<br>
    case nir_instr_type_tex:<br>
       return false; /* TODO */<br>
-   case nir_instr_type_intrinsic:<br>
+   case nir_instr_type_intrinsic: {<br>
+      const nir_intrinsic_info *info =<br>
+         &nir_intrinsic_infos[nir_instr_as_intrinsic(instr)->intrinsic];<br>
+      return (info->flags & NIR_INTRINSIC_CAN_ELIMINATE) &&<br>
+             (info->flags & NIR_INTRINSIC_CAN_REORDER) &&<br>
+             info->num_variables == 0; /* not implemented yet */<br>
+   }<br>
    case nir_instr_type_call:<br>
    case nir_instr_type_jump:<br>
    case nir_instr_type_ssa_undef:<br>
@@ -176,6 +209,9 @@ nir_instr_get_dest_ssa_def(nir_instr *instr)<br>
    case nir_instr_type_phi:<br>
       assert(nir_instr_as_phi(instr)->dest.is_ssa);<br>
       return &nir_instr_as_phi(instr)->dest.ssa;<br>
+   case nir_instr_type_intrinsic:<br>
+      assert(nir_instr_as_intrinsic(instr)->dest.is_ssa);<br>
+      return &nir_instr_as_intrinsic(instr)->dest.ssa;<br>
    default:<br>
       unreachable("We never ask for any of these");<br>
    }<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.2.2<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" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div>