Maintain loop iteration count estimates

Jan Hubicka hubicka@ucw.cz
Thu Jun 9 09:58:00 GMT 2016


Hi,
after we read the profile, we know expected number of iterations.
Currently we use profile each time estimate_numbers_of_iterations_loop
is called to recompute this value.  This is not very safe because the
profile may be misupdated.  It seems safer to compute it at once and
maintain thorough the compilation.

Notice that I removed:
-  /* Force estimate compuation but leave any existing upper bound in place.  */
-  loop->any_estimate = false;
>From beggining of estimate_numbers_of_iterations_loop.  I can not make sense of
this. Even w/o profile if we have estimate, we are better to maintain it because
later we may not be able to derive it again.
There seems to be no code that is forced by setting loop->any_estimate = true.
Only code that cares seems to be record_niter_bound that only decreases existing
estimates. THis seems sane procedure - we don't roll loops.

Bootstrapped/regtested x86_64-linux, OK?

Honza

	* profile.c: Include cfgloop.h.
	(branch_prob): Compute estimated number of iterations.
	* tree-ssa-loop-niter.c (estimate_numbers_of_iterations_loop): Do not
	recompute estimate number of iterations from profile.
Index: profile.c
===================================================================
--- profile.c	(revision 237221)
+++ profile.c	(working copy)
@@ -63,6 +63,7 @@ along with GCC; see the file COPYING3.
 #include "gimple-iterator.h"
 #include "tree-cfg.h"
 #include "dumpfile.h"
+#include "cfgloop.h"
 
 #include "profile.h"
 
@@ -1329,9 +1330,21 @@ branch_prob (void)
   coverage_end_function (lineno_checksum, cfg_checksum);
   if (flag_branch_probabilities && profile_info)
     {
+      struct loop *loop;
       if (dump_file && (dump_flags & TDF_DETAILS))
 	report_predictor_hitrates ();
       profile_status_for_fn (cfun) = PROFILE_READ;
+
+      /* At this moment we have precise loop iteration count estimates.
+	 Record them to loop structure before the profile gets out of date. */
+      FOR_EACH_LOOP (loop, 0)
+	if (loop->header->count)
+	  {
+	    gcov_type nit = expected_loop_iterations_unbounded (loop);
+	    widest_int bound = gcov_type_to_wide_int (nit);
+	    loop->any_estimate = false;
+	    record_niter_bound (loop, bound, true, false);
+	  }
       compute_function_frequency ();
     }
 }
Index: tree-ssa-loop-niter.c
===================================================================
--- tree-ssa-loop-niter.c	(revision 237221)
+++ tree-ssa-loop-niter.c	(working copy)
@@ -3721,8 +3721,26 @@ estimate_numbers_of_iterations_loop (str
     return;
 
   loop->estimate_state = EST_AVAILABLE;
-  /* Force estimate compuation but leave any existing upper bound in place.  */
-  loop->any_estimate = false;
+
+  /* If we have a measured profile, use it to estimate the number of
+     iterations.  Normally this is recorded by branch_prob right after
+     reading the profile.  In case we however found a new loop, record the
+     information here.
+
+     Explicitly check for profile status so we do not report
+     wrong prediction hitrates for guessed loop iterations heuristics.
+     Do not recompute already recorded bounds - we ought to be better on
+     updating iteration bounds than updating profile in general and thus
+     recomputing iteration bounds later in the compilation process will just
+     introduce random roundoff errors.  */
+  if (!loop->any_estimate
+      && loop->header->count != 0
+      && profile_status_for_fn (cfun) >= PROFILE_READ)
+    {
+      gcov_type nit = expected_loop_iterations_unbounded (loop);
+      bound = gcov_type_to_wide_int (nit);
+      record_niter_bound (loop, bound, true, false);
+    }
 
   /* Ensure that loop->nb_iterations is computed if possible.  If it turns out
      to be constant, we avoid undefined behavior implied bounds and instead
@@ -3756,17 +3774,6 @@ estimate_numbers_of_iterations_loop (str
 
   maybe_lower_iteration_bound (loop);
 
-  /* If we have a measured profile, use it to estimate the number of
-     iterations.  Explicitly check for profile status so we do not report
-     wrong prediction hitrates for guessed loop iterations heuristics.  */
-  if (loop->header->count != 0
-      && profile_status_for_fn (cfun) >= PROFILE_READ)
-    {
-      gcov_type nit = expected_loop_iterations_unbounded (loop);
-      bound = gcov_type_to_wide_int (nit);
-      record_niter_bound (loop, bound, true, false);
-    }
-
   /* If we know the exact number of iterations of this loop, try to
      not break code with undefined behavior by not recording smaller
      maximum number of iterations.  */



More information about the Gcc-patches mailing list