diff options
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cfgloop.h | 4 | ||||
-rw-r--r-- | gcc/cfgloopanal.c | 35 |
3 files changed, 35 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 021f64e5bd8..7f5f87f293f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 2016-05-20 Jan Hubicka <hubicka@ucw.cz> + * 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. + +2016-05-20 Jan Hubicka <hubicka@ucw.cz> + * loop-doloop.c (doloop_optimize): Use get_estimated_loop_iterations_int and get_max_loop_iterations_int. diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h index 54e738f20f4..173fda84ba4 100644 --- a/gcc/cfgloop.h +++ b/gcc/cfgloop.h @@ -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); diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c index 4d35820b729..938ac43879a 100644 --- a/gcc/cfgloopanal.c +++ b/gcc/cfgloopanal.c @@ -231,14 +231,20 @@ average_num_loop_insns (const struct loop *loop) value. */ gcov_type -expected_loop_iterations_unbounded (const struct loop *loop) +expected_loop_iterations_unbounded (struct loop *loop) { edge e; edge_iterator ei; - - if (loop->latch->count || loop->header->count) + gcov_type expected; + + + /* 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 (const struct loop *loop) expected = count_latch * 2; else expected = (count_latch + count_in - 1) / count_in; - - return expected; } else { @@ -270,17 +274,28 @@ expected_loop_iterations_unbounded (const struct loop *loop) 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); |