diff mbox

Make loop unroller to use likely upper bounds

Message ID 20160601115954.GB41993@kam.mff.cuni.cz
State New
Headers show

Commit Message

Jan Hubicka June 1, 2016, 11:59 a.m. UTC
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.
diff mbox

Patch

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));
 	}