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
This commit is contained in:
parent
a4744f620f
commit
d4919e65ca
@ -1,3 +1,11 @@
|
|||||||
|
2016-10-14 Pat Haugen <pthaugen@us.ibm.com>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
2016-10-14 Pedro Alves <palves@redhat.com>
|
2016-10-14 Pedro Alves <palves@redhat.com>
|
||||||
|
|
||||||
* coretypes.h (OVERRIDE, FINAL): Delete, moved to
|
* coretypes.h (OVERRIDE, FINAL): Delete, moved to
|
||||||
|
@ -1276,10 +1276,13 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
int preheader_freq = EDGE_FREQUENCY (e);
|
||||||
scale_main = REG_BR_PROB_BASE;
|
scale_main = REG_BR_PROB_BASE;
|
||||||
for (i = 0; i < ndupl; i++)
|
for (i = 0; i < ndupl; i++)
|
||||||
scale_main = combine_probabilities (scale_main, scale_step[i]);
|
scale_main = combine_probabilities (scale_main, scale_step[i]);
|
||||||
scale_act = REG_BR_PROB_BASE - prob_pass_thru;
|
if (preheader_freq > freq_in)
|
||||||
|
preheader_freq = freq_in;
|
||||||
|
scale_act = GCOV_COMPUTE_SCALE (preheader_freq, freq_in);
|
||||||
}
|
}
|
||||||
for (i = 0; i < ndupl; i++)
|
for (i = 0; i < ndupl; i++)
|
||||||
gcc_assert (scale_step[i] >= 0 && scale_step[i] <= REG_BR_PROB_BASE);
|
gcc_assert (scale_step[i] >= 0 && scale_step[i] <= REG_BR_PROB_BASE);
|
||||||
|
@ -859,7 +859,8 @@ unroll_loop_runtime_iterations (struct loop *loop)
|
|||||||
rtx_insn *init_code, *branch_code;
|
rtx_insn *init_code, *branch_code;
|
||||||
unsigned i, j, p;
|
unsigned i, j, p;
|
||||||
basic_block preheader, *body, swtch, ezc_swtch;
|
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;
|
unsigned n_peel;
|
||||||
edge e;
|
edge e;
|
||||||
bool extra_zero_check, last_may_exit;
|
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. */
|
/* Record the place where switch will be built for preconditioning. */
|
||||||
swtch = split_edge (loop_preheader_edge (loop));
|
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++)
|
for (i = 0; i < n_peel; i++)
|
||||||
{
|
{
|
||||||
/* Peel the copy. */
|
/* Peel the copy. */
|
||||||
@ -970,6 +980,10 @@ unroll_loop_runtime_iterations (struct loop *loop)
|
|||||||
p = REG_BR_PROB_BASE / (i + 2);
|
p = REG_BR_PROB_BASE / (i + 2);
|
||||||
|
|
||||||
preheader = split_edge (loop_preheader_edge (loop));
|
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,
|
branch_code = compare_and_jump_seq (copy_rtx (niter), GEN_INT (j), EQ,
|
||||||
block_label (preheader), p,
|
block_label (preheader), p,
|
||||||
NULL);
|
NULL);
|
||||||
@ -981,9 +995,14 @@ unroll_loop_runtime_iterations (struct loop *loop)
|
|||||||
swtch = split_edge_and_insert (single_pred_edge (swtch), branch_code);
|
swtch = split_edge_and_insert (single_pred_edge (swtch), branch_code);
|
||||||
set_immediate_dominator (CDI_DOMINATORS, preheader, swtch);
|
set_immediate_dominator (CDI_DOMINATORS, preheader, swtch);
|
||||||
single_succ_edge (swtch)->probability = REG_BR_PROB_BASE - p;
|
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,
|
e = make_edge (swtch, preheader,
|
||||||
single_succ_edge (swtch)->flags & EDGE_IRREDUCIBLE_LOOP);
|
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;
|
e->probability = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -993,6 +1012,14 @@ unroll_loop_runtime_iterations (struct loop *loop)
|
|||||||
p = REG_BR_PROB_BASE / (max_unroll + 1);
|
p = REG_BR_PROB_BASE / (max_unroll + 1);
|
||||||
swtch = ezc_swtch;
|
swtch = ezc_swtch;
|
||||||
preheader = split_edge (loop_preheader_edge (loop));
|
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,
|
branch_code = compare_and_jump_seq (copy_rtx (niter), const0_rtx, EQ,
|
||||||
block_label (preheader), p,
|
block_label (preheader), p,
|
||||||
NULL);
|
NULL);
|
||||||
@ -1001,9 +1028,10 @@ unroll_loop_runtime_iterations (struct loop *loop)
|
|||||||
swtch = split_edge_and_insert (single_succ_edge (swtch), branch_code);
|
swtch = split_edge_and_insert (single_succ_edge (swtch), branch_code);
|
||||||
set_immediate_dominator (CDI_DOMINATORS, preheader, swtch);
|
set_immediate_dominator (CDI_DOMINATORS, preheader, swtch);
|
||||||
single_succ_edge (swtch)->probability = REG_BR_PROB_BASE - p;
|
single_succ_edge (swtch)->probability = REG_BR_PROB_BASE - p;
|
||||||
|
single_succ_edge (swtch)->count -= iter_count;
|
||||||
e = make_edge (swtch, preheader,
|
e = make_edge (swtch, preheader,
|
||||||
single_succ_edge (swtch)->flags & EDGE_IRREDUCIBLE_LOOP);
|
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;
|
e->probability = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user