<p dir="ltr"><br>
On Jan 21, 2015 3:29 AM, "Kenneth Graunke" <<a href="mailto:kenneth@whitecape.org">kenneth@whitecape.org</a>> wrote:<br>
><br>
> 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.</p>
<p dir="ltr">I think this is fine for now. If it ever becomes a problem, we can add a can_cse flag. Couple comments below; otherwise,<br>
Reviewed-by: Jason Ekstrand <<a href="mailto:jason.ekstrand@intel.com">jason.ekstrand@intel.com</a>></p>
<p dir="ltr">> --- NIR instruction statistics ---<br>
> total instructions in shared programs: 2435936 -> 2023511 (-16.93%)<br>
> instructions in affected programs: 2413496 -> 2001071 (-17.09%)<br>
> helped: 16872<br>
><br>
> --- i965 instruction statistics ---<br>
> total instructions in shared programs: 6028987 -> 6008427 (-0.34%)<br>
> 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 | 38 ++++++++++++++++++++++++++++++++++++--<br>
> 1 file changed, 36 insertions(+), 2 deletions(-)<br>
><br>
> diff --git a/src/glsl/nir/nir_opt_cse.c b/src/glsl/nir/nir_opt_cse.c<br>
> index e7dba1d..6ad78f6 100644<br>
> --- a/src/glsl/nir/nir_opt_cse.c<br>
> +++ b/src/glsl/nir/nir_opt_cse.c<br>
> @@ -112,7 +112,32 @@ 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>
> + for (unsigned i = 0; i < info->num_indices; i++) {<br>
> + if (intrinsic1->const_index[i] != intrinsic2->const_index[i])<br>
> + return false;<br>
> + }</p>
<p dir="ltr">Can we assert num_vars == 0 somewhere in here. It's a comment to the reader that the assumption is there and a placeholder for when/if we add variable support.</p>
<p dir="ltr">> +<br>
> + return true;<br>
> + }<br>
> case nir_instr_type_call:<br>
> case nir_instr_type_jump:<br>
> case nir_instr_type_ssa_undef:<br>
> @@ -147,7 +172,13 @@ nir_instr_can_cse(nir_instr *instr)<br>
> nir_foreach_src(instr, src_is_ssa, NULL);<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 */</p>
<p dir="ltr">We also need to ensure sources and destination are SSA here. Maybe that should be pulled out of the switch.</p>
<p dir="ltr">> + }<br>
> case nir_instr_type_call:<br>
> case nir_instr_type_jump:<br>
> case nir_instr_type_ssa_undef:<br>
> @@ -172,6 +203,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>
> --<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">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</p>