Hi, this patch updates loop unroller to use likely upper bounds and add testcases that profile updating goes well at least in very trivial cases. I will try to add more complex but since there is a lot of target specific stuff involved in RTL expansion I think it is safer to test easy cases first and see what breaks.
Bootstrapped/regtested x86_64-linux, will commit it shortly. * loop-unroll.c (decide_unroll_constant_iterations, decide_unroll_runtime_iterations, decide_unroll_stupid): Use likely upper bounds. * loop-iv.c (find_simple_exit): Dump likely upper bounds. * gcc.dg/unroll-6.c: Update template. * gcc.dg/unroll-7.c: New testcase. * gcc.dg/unroll-8.c: New testcase. Index: loop-unroll.c =================================================================== --- loop-unroll.c (revision 236984) +++ loop-unroll.c (working copy) @@ -396,7 +396,7 @@ decide_unroll_constant_iterations (struc of iterations. */ if (desc->niter < 2 * nunroll || ((get_estimated_loop_iterations (loop, &iterations) - || get_max_loop_iterations (loop, &iterations)) + || get_likely_max_loop_iterations (loop, &iterations)) && wi::ltu_p (iterations, 2 * nunroll))) { if (dump_file) @@ -706,7 +706,7 @@ decide_unroll_runtime_iterations (struct /* Check whether the loop rolls. */ if ((get_estimated_loop_iterations (loop, &iterations) - || get_max_loop_iterations (loop, &iterations)) + || get_likely_max_loop_iterations (loop, &iterations)) && wi::ltu_p (iterations, 2 * nunroll)) { if (dump_file) @@ -1162,7 +1162,7 @@ decide_unroll_stupid (struct loop *loop, /* Check whether the loop rolls. */ if ((get_estimated_loop_iterations (loop, &iterations) - || get_max_loop_iterations (loop, &iterations)) + || get_likely_max_loop_iterations (loop, &iterations)) && wi::ltu_p (iterations, 2 * nunroll)) { if (dump_file) Index: testsuite/gcc.dg/unroll-6.c =================================================================== --- testsuite/gcc.dg/unroll-6.c (revision 236984) +++ testsuite/gcc.dg/unroll-6.c (working copy) @@ -28,7 +28,7 @@ int t2() abort (); return 0; } -/* { dg-final { scan-rtl-dump-times "upper bound: 999999" 1 "loop2_unroll" } } */ +/* { dg-final { scan-rtl-dump-times " upper bound: 999999" 1 "loop2_unroll" } } */ /* { dg-final { scan-rtl-dump-not "realistic bound: 999999" "loop2_unroll" } } */ -/* { dg-final { scan-rtl-dump-times "upper bound: 2999999" 1 "loop2_unroll" } } */ +/* { dg-final { scan-rtl-dump-times " upper bound: 2999999" 1 "loop2_unroll" } } */ /* { dg-final { scan-rtl-dump-times "realistic bound: 2999999" 1 "loop2_unroll" } } */ Index: testsuite/gcc.dg/unroll-7.c =================================================================== --- testsuite/gcc.dg/unroll-7.c (revision 0) +++ testsuite/gcc.dg/unroll-7.c (working copy) @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-rtl-loop2_unroll -funroll-loops" } */ +int t(int *a) +{ + int i; + for (i=0;i<1000000;i++) + a[i]++; +} +/* { dg-final { scan-rtl-dump "Unrolled loop" "loop2_unroll" } } */ +/* { dg-final { scan-rtl-dump "number of iterations: .const_int 999999" "loop2_unroll" } } */ +/* { dg-final { scan-rtl-dump "upper bound: 999999" "loop2_unroll" } } */ +/* { dg-final { scan-rtl-dump "realistic bound: 999999" "loop2_unroll" } } */ +/* { dg-final { scan-rtl-dump "Considering unrolling loop with constant number of iterations" "loop2_unroll" } } */ +/* { dg-final { scan-rtl-dump-not "Invalid sum" "loop2_unroll" } } */ Index: testsuite/gcc.dg/unroll-8.c =================================================================== --- testsuite/gcc.dg/unroll-8.c (revision 0) +++ testsuite/gcc.dg/unroll-8.c (working copy) @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-rtl-loop2_unroll -funroll-loops" } */ +struct a {int a[7];}; +int t(struct a *a, int n) +{ + int i; + for (i=0;i<n;i++) + a->a[i]++; +} +/* { dg-final { scan-rtl-dump-not "Unrolled loop" "loop2_unroll" } } */ +/* { dg-final { scan-rtl-dump "likely upper bound: 7" "loop2_unroll" } } */ +/* { dg-final { scan-rtl-dump "realistic bound: -1" "loop2_unroll" } } */ +/* { dg-final { scan-rtl-dump "Not unrolling loop, doesn't roll" "loop2_unroll" } } */ +/* { dg-final { scan-rtl-dump-not "Invalid sum" "loop2_unroll" } } */ +/* { dg-final { scan-rtl-dump-not "upper bound: -1" "loop2_unroll" } } */ Index: loop-iv.c =================================================================== --- loop-iv.c (revision 236984) +++ loop-iv.c (working copy) @@ -2998,6 +2998,8 @@ find_simple_exit (struct loop *loop, str fprintf (dump_file, " upper bound: %li\n", (long)get_max_loop_iterations_int (loop)); + fprintf (dump_file, " likely upper bound: %li\n", + (long)get_likely_max_loop_iterations_int (loop)); fprintf (dump_file, " realistic bound: %li\n", (long)get_estimated_loop_iterations_int (loop)); }