Do not give realistic estimates for loop with array accesses

Jan Hubicka hubicka@ucw.cz
Wed Mar 30 11:02:00 GMT 2016


Hi,
while looking into sudoku solving benchark, I noticed that we incorrectly
estimate loop to iterate 10 times just because the array it traverses is of
dimension 10. This of course is just upper bound and not realistic bound.
Realistically those loops iterates once most of time.

It turns out this bug was introduced by me in
https://gcc.gnu.org/ml/gcc-patches/2013-01/msg00444.html
While I do not recall doing that patch, it seems like a thinko about reliable
(name of the variable) and realistic (name of the parameter it is passed to).

Fixing this caused one testsuite fallout in predictive commoning testcase
because loop unswitching previously disabled itself having an estimated number
of iterations 1 (I am not sure if that is not supposed to be 0, with 1
iteration unswithcing may pay back, little bit, I suppose it wants to test
number of stmt executions of the condtional to be at least 2 which depends on
whether the conditional is before or after the loop exits). This made me notice
that some loop passes that want to give up on low trip count uses combination
of estimated number of iterations and max number of iterations while other
don't which is fixed here. The code combining both realistic and max counts
is same as i.e. in unroller and other passes already.

I also wonder if predictive comming is a win for loops with very low
trip count, but that is for separate patch, too, anyway.

Bootstrapped/regtested x86_64-linux, OK?

Honza

	* tree-ssa-loop-niter.c (idx_infer_loop_bounds): We can't get realistic
	estimates here.
	* tree-ssa-loop-unswitch.c (tree_unswitch_single_loop): Use also
	max_loop_iterations_int.
	* tree-ssa-loop-ivopts.c (avg_loop_niter): Likewise.
	* tree-vect-loop.c (vect_analyze_loop_2): Likewise.
Index: tree-ssa-loop-niter.c
===================================================================
--- tree-ssa-loop-niter.c	(revision 234516)
+++ tree-ssa-loop-niter.c	(working copy)
@@ -3115,7 +3115,6 @@ idx_infer_loop_bounds (tree base, tree *
   tree low, high, type, next;
   bool sign, upper = true, at_end = false;
   struct loop *loop = data->loop;
-  bool reliable = true;
 
   if (TREE_CODE (base) != ARRAY_REF)
     return true;
@@ -3187,14 +3186,14 @@ idx_infer_loop_bounds (tree base, tree *
       && tree_int_cst_compare (next, high) <= 0)
     return true;
 
-  /* If access is not executed on every iteration, we must ensure that overlow may
-     not make the access valid later.  */
+  /* If access is not executed on every iteration, we must ensure that overlow
+     may not make the access valid later.  */
   if (!dominated_by_p (CDI_DOMINATORS, loop->latch, gimple_bb (data->stmt))
       && scev_probably_wraps_p (initial_condition_in_loop_num (ev, loop->num),
 				step, data->stmt, loop, true))
-    reliable = false;
+    upper = false;
 
-  record_nonwrapping_iv (loop, init, step, data->stmt, low, high, reliable, upper);
+  record_nonwrapping_iv (loop, init, step, data->stmt, low, high, false, upper);
   return true;
 }
 
Index: tree-ssa-loop-unswitch.c
===================================================================
--- tree-ssa-loop-unswitch.c	(revision 234516)
+++ tree-ssa-loop-unswitch.c	(working copy)
@@ -223,6 +223,8 @@ tree_unswitch_single_loop (struct loop *
       /* If the loop is not expected to iterate, there is no need
 	 for unswitching.  */
       iterations = estimated_loop_iterations_int (loop);
+      if (iterations < 0)
+        iterations = max_loop_iterations_int (loop);
       if (iterations >= 0 && iterations <= 1)
 	{
 	  if (dump_file && (dump_flags & TDF_DETAILS))
Index: tree-ssa-loop-ivopts.c
===================================================================
--- tree-ssa-loop-ivopts.c	(revision 234516)
+++ tree-ssa-loop-ivopts.c	(working copy)
@@ -121,7 +121,11 @@ avg_loop_niter (struct loop *loop)
 {
   HOST_WIDE_INT niter = estimated_stmt_executions_int (loop);
   if (niter == -1)
-    return AVG_LOOP_NITER (loop);
+    {
+      niter = max_stmt_executions_int (loop);
+      if (niter == -1 || niter > AVG_LOOP_NITER (loop))
+        return AVG_LOOP_NITER (loop);
+    }
 
   return niter;
 }
Index: tree-vect-loop.c
===================================================================
--- tree-vect-loop.c	(revision 234516)
+++ tree-vect-loop.c	(working copy)
@@ -2063,6 +2063,9 @@ start_over:
 
   estimated_niter
     = estimated_stmt_executions_int (LOOP_VINFO_LOOP (loop_vinfo));
+  if (estimated_niter != -1)
+    estimated_niter
+      = max_stmt_executions_int (LOOP_VINFO_LOOP (loop_vinfo));
   if (estimated_niter != -1
       && ((unsigned HOST_WIDE_INT) estimated_niter
           <= MAX (th, (unsigned)min_profitable_estimate)))



More information about the Gcc-patches mailing list