summaryrefslogtreecommitdiff
path: root/gcc/loop-unroll.c
diff options
context:
space:
mode:
authorPat Haugen <pthaugen@us.ibm.com>2016-10-14 17:10:18 +0000
committerPat Haugen <pthaugen@gcc.gnu.org>2016-10-14 17:10:18 +0000
commitd4919e65cae926b962425ff3d8c71a668f63c209 (patch)
tree01bb186ac1edba171f8b6bac72910c624b865727 /gcc/loop-unroll.c
parenta4744f620f32b6b859a39c6876f5e21b52b1af4b (diff)
re PR rtl-optimization/68212 (Loop unroller breaks basic block frequencies)
PR rtl-optimization/68212 * cfgloopmanip.c (duplicate_loop_to_header_edge): Use preheader edge frequency when computing scale factor for peeled copies. * loop-unroll.c (unroll_loop_runtime_iterations): Fix freq/count values for switch/peel blocks/edges. From-SVN: r241170
Diffstat (limited to 'gcc/loop-unroll.c')
-rw-r--r--gcc/loop-unroll.c34
1 files changed, 31 insertions, 3 deletions
diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c
index 494504d61e6..f412698f170 100644
--- a/gcc/loop-unroll.c
+++ b/gcc/loop-unroll.c
@@ -859,7 +859,8 @@ unroll_loop_runtime_iterations (struct loop *loop)
rtx_insn *init_code, *branch_code;
unsigned i, j, p;
basic_block preheader, *body, swtch, ezc_swtch;
- int may_exit_copy;
+ int may_exit_copy, iter_freq, new_freq;
+ gcov_type iter_count, new_count;
unsigned n_peel;
edge e;
bool extra_zero_check, last_may_exit;
@@ -953,6 +954,15 @@ unroll_loop_runtime_iterations (struct loop *loop)
/* Record the place where switch will be built for preconditioning. */
swtch = split_edge (loop_preheader_edge (loop));
+ /* Compute frequency/count increments for each switch block and initialize
+ innermost switch block. Switch blocks and peeled loop copies are built
+ from innermost outward. */
+ iter_freq = new_freq = swtch->frequency / (max_unroll + 1);
+ iter_count = new_count = swtch->count / (max_unroll + 1);
+ swtch->frequency = new_freq;
+ swtch->count = new_count;
+ single_succ_edge (swtch)->count = new_count;
+
for (i = 0; i < n_peel; i++)
{
/* Peel the copy. */
@@ -970,6 +980,10 @@ unroll_loop_runtime_iterations (struct loop *loop)
p = REG_BR_PROB_BASE / (i + 2);
preheader = split_edge (loop_preheader_edge (loop));
+ /* Add in frequency/count of edge from switch block. */
+ preheader->frequency += iter_freq;
+ preheader->count += iter_count;
+ single_succ_edge (preheader)->count = preheader->count;
branch_code = compare_and_jump_seq (copy_rtx (niter), GEN_INT (j), EQ,
block_label (preheader), p,
NULL);
@@ -981,9 +995,14 @@ unroll_loop_runtime_iterations (struct loop *loop)
swtch = split_edge_and_insert (single_pred_edge (swtch), branch_code);
set_immediate_dominator (CDI_DOMINATORS, preheader, swtch);
single_succ_edge (swtch)->probability = REG_BR_PROB_BASE - p;
+ single_succ_edge (swtch)->count = new_count;
+ new_freq += iter_freq;
+ new_count += iter_count;
+ swtch->frequency = new_freq;
+ swtch->count = new_count;
e = make_edge (swtch, preheader,
single_succ_edge (swtch)->flags & EDGE_IRREDUCIBLE_LOOP);
- e->count = RDIV (preheader->count * REG_BR_PROB_BASE, p);
+ e->count = iter_count;
e->probability = p;
}
@@ -993,6 +1012,14 @@ unroll_loop_runtime_iterations (struct loop *loop)
p = REG_BR_PROB_BASE / (max_unroll + 1);
swtch = ezc_swtch;
preheader = split_edge (loop_preheader_edge (loop));
+ /* Recompute frequency/count adjustments since initial peel copy may
+ have exited and reduced those values that were computed above. */
+ iter_freq = swtch->frequency / (max_unroll + 1);
+ iter_count = swtch->count / (max_unroll + 1);
+ /* Add in frequency/count of edge from switch block. */
+ preheader->frequency += iter_freq;
+ preheader->count += iter_count;
+ single_succ_edge (preheader)->count = preheader->count;
branch_code = compare_and_jump_seq (copy_rtx (niter), const0_rtx, EQ,
block_label (preheader), p,
NULL);
@@ -1001,9 +1028,10 @@ unroll_loop_runtime_iterations (struct loop *loop)
swtch = split_edge_and_insert (single_succ_edge (swtch), branch_code);
set_immediate_dominator (CDI_DOMINATORS, preheader, swtch);
single_succ_edge (swtch)->probability = REG_BR_PROB_BASE - p;
+ single_succ_edge (swtch)->count -= iter_count;
e = make_edge (swtch, preheader,
single_succ_edge (swtch)->flags & EDGE_IRREDUCIBLE_LOOP);
- e->count = RDIV (preheader->count * REG_BR_PROB_BASE, p);
+ e->count = iter_count;
e->probability = p;
}