This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Make profile updating after loop transforms bit more robust
- From: Jan Hubicka <hubicka at ucw dot cz>
- To: gcc-patches at gcc dot gnu dot org, dje dot gcc at gmail dot com
- Date: Fri, 20 May 2016 15:17:17 +0200
- Subject: Make profile updating after loop transforms bit more robust
- Authentication-results: sourceware.org; auth=none
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.
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);