On Fri, May 24, 2019 at 09:48:03AM +0200, Martin Liška wrote:
> gcc/ChangeLog:
> 
> 2019-05-23  Martin Liska  <mli...@suse.cz>
> 
>       PR ipa/90555
>       * ipa-icf-gimple.c (func_checker::compare_loops): New function.
>       * ipa-icf-gimple.h (func_checker::compare_loops): Likewise.
>       * ipa-icf.c (sem_function::equals_private): Use compare_loops.
> 
> gcc/testsuite/ChangeLog:
> 
> 2019-05-23  Martin Liska  <mli...@suse.cz>
> 
>       PR ipa/90555
>       * gcc.dg/ipa/pr90555.c: New test.

> @@ -605,6 +606,45 @@ func_checker::compare_variable_decl (tree t1, tree t2)
>    return return_with_debug (ret);
>  }
>  
> +/* Compare significant loop information.  */
> +bool
> +func_checker::compare_loops (void)
> +{
> +  struct loop *loop;
> +
> +  auto_vec <struct loop *> loops1;
> +  auto_vec <struct loop *> loops2;
> +
> +  FOR_EACH_LOOP_FN (DECL_STRUCT_FUNCTION (m_source_func_decl), loop, 0)
> +    loops1.safe_push (loop);
> +
> +  FOR_EACH_LOOP_FN (DECL_STRUCT_FUNCTION (m_target_func_decl), loop, 0)
> +    loops2.safe_push (loop);
> +
> +  gcc_assert (loops1.length () == loops2.length ());
> +
> +  for (unsigned i = 0; i < loops1.length (); i++)

I wonder how likely/unlikely it is that the loops will be ordered the same
by the iterators.  If they are the same always, then perhaps it would be
better to avoid the temporary vectors, and just do one FOR_EACH_LOOP_FN
with another manual loop_iterator use in sync with that.
If it isn't guaranteed they are ordered the same, then I think we need to
match the loops by the corresponding loop header and perhaps also verify
loop latch and other basic blocks in the loop?

> +    {
> +      struct loop *l1 = loops1[i];
> +      struct loop *l2 = loops2[i];
> +      if (l1->simdlen != l2->simdlen)
> +     return return_false_with_msg ("simdlen");
> +      if (l1->safelen != l2->safelen)
> +     return return_false_with_msg ("safelen");
> +      if (l1->can_be_parallel != l2->can_be_parallel)
> +     return return_false_with_msg ("can_be_parallel");
> +      if (l1->dont_vectorize != l2->dont_vectorize)
> +     return return_false_with_msg ("dont_vectorize");
> +      if (l1->force_vectorize != l2->force_vectorize)
> +     return return_false_with_msg ("force_vectorize");
> +      if (l1->unroll != l2->unroll)
> +     return return_false_with_msg ("unroll");
> +      if (!compare_variable_decl (l1->simduid, l2->simduid))
> +     return return_false_with_msg ("simduid");

The above looks reasonable if we are guaranteed we are talking about a loop
corresponding between the two functions.

> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/ipa/pr90555.c
> @@ -0,0 +1,67 @@
> +/* { dg-do compile } */
> +/* { dg-options "-fopenmp-simd -O2 -mavx512f -fdump-ipa-icf" } */
> +/* { dg-do compile { target i?86-*-* x86_64-*-* } } */

Please don't use two dg-do compile directives, drop the first line,
move the third line to first one.

        Jakub

Reply via email to