diff mbox

Make profile updating after loop transforms bit more robust

Message ID 20160520131717.GA82494@kam.mff.cuni.cz
State New
Headers show

Commit Message

Jan Hubicka May 20, 2016, 1:17 p.m. UTC
Hi,
this patch makes expected_loop_iterations to be bit saner in coner cases.
First expected_loop_iterations currently return 0 when
-fguess-branch-probabiliteis is off and also in case the frequencies are
downscaled to 0.
Originally the function was intended to be used only for loops with profile
computed, but this is not current practice so it is better to do something
at least resonably sane.  The patch makes expected_loop_iterations_unbounded
to guess 3 iterations which is about the avreage number of iterations of a
given loop in program.

On the other hand it may return bigger values than maximal number of iterations
which we now have readily available from loop infrastructure. So it is good idea
to cap the value by this.

This makes updates after loop unrolling and similar transformations more sane.

Bootstrapped/regtested x86_64-linux, will commit it shortly.

Honza

	* cfgloop.h (expected_loop_iterations_unbounded,
	expected_loop_iterations): Unconstify.
	* cfgloopanal.c (expected_loop_iterations_unbounded): Sanity check the
	profile with known upper bound; return 3 when profile is absent.
	(expected_loop_iterations): Update.
diff mbox

Patch

Index: cfgloop.h
===================================================================
--- cfgloop.h	(revision 236507)
+++ cfgloop.h	(working copy)
@@ -316,8 +316,8 @@  extern void verify_loop_structure (void)
 
 /* Loop analysis.  */
 extern bool just_once_each_iteration_p (const struct loop *, const_basic_block);
-gcov_type expected_loop_iterations_unbounded (const struct loop *);
-extern unsigned expected_loop_iterations (const struct loop *);
+gcov_type expected_loop_iterations_unbounded (struct loop *);
+extern unsigned expected_loop_iterations (struct loop *);
 extern rtx doloop_condition_get (rtx);
 
 void mark_loop_for_removal (loop_p);
Index: cfgloopanal.c
===================================================================
--- cfgloopanal.c	(revision 236507)
+++ cfgloopanal.c	(working copy)
@@ -231,14 +231,20 @@  average_num_loop_insns (const struct loo
    value.  */
 
 gcov_type
-expected_loop_iterations_unbounded (const struct loop *loop)
+expected_loop_iterations_unbounded (struct loop *loop)
 {
   edge e;
   edge_iterator ei;
+  gcov_type expected;
+  
 
-  if (loop->latch->count || loop->header->count)
+  /* Average loop rolls about 3 times. If we have no profile at all, it is
+     best we can do.  */
+  if (profile_status_for_fn (cfun) == PROFILE_ABSENT)
+    expected = 3;
+  else if (loop->latch->count || loop->header->count)
     {
-      gcov_type count_in, count_latch, expected;
+      gcov_type count_in, count_latch;
 
       count_in = 0;
       count_latch = 0;
@@ -253,8 +259,6 @@  expected_loop_iterations_unbounded (cons
 	expected = count_latch * 2;
       else
 	expected = (count_latch + count_in - 1) / count_in;
-
-      return expected;
     }
   else
     {
@@ -270,17 +274,28 @@  expected_loop_iterations_unbounded (cons
 	  freq_in += EDGE_FREQUENCY (e);
 
       if (freq_in == 0)
-	return freq_latch * 2;
-
-      return (freq_latch + freq_in - 1) / freq_in;
+	{
+	  /* If we have no profile at all, expect 3 iterations.  */
+	  if (!freq_latch)
+	    expected = 3;
+	  else
+	    expected = freq_latch * 2;
+	}
+      else
+        expected = (freq_latch + freq_in - 1) / freq_in;
     }
+
+  HOST_WIDE_INT max = get_max_loop_iterations_int (loop);
+  if (max != -1 && max < expected)
+    return max;
+  return expected;
 }
 
 /* Returns expected number of LOOP iterations.  The returned value is bounded
    by REG_BR_PROB_BASE.  */
 
 unsigned
-expected_loop_iterations (const struct loop *loop)
+expected_loop_iterations (struct loop *loop)
 {
   gcov_type expected = expected_loop_iterations_unbounded (loop);
   return (expected > REG_BR_PROB_BASE ? REG_BR_PROB_BASE : expected);