Fix ICE in lsplit when built with -O3 -fno-guess-branch-probability [PR103793]
no-guess-branch-probability option requires profile_count scaling with initialized_p guard, use multiply instead of apply_scale, which will do the right thing to undefined probabilities and will not cause unnecesary roundoff errors and precision info loss. Also merge the missed part of r12-6086 of factor out function to avoid duplicate code. Regression testest pass on Power and X86. gcc/ChangeLog: PR tree-optimization/103793 * tree-ssa-loop-split.c (fix_loop_bb_probability): New function. (split_loop): Use multiply to scale loop1's exit probability. (do_split_loop_on_cond): Call fix_loop_bb_probability. gcc/testsuite/ChangeLog: PR tree-optimization/103793 * gcc.dg/pr103793.c: New test.
This commit is contained in:
parent
054e57e467
commit
44372676e8
|
@ -0,0 +1,12 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O3 -fno-guess-branch-probability" } */
|
||||
|
||||
extern void bar (void);
|
||||
|
||||
void
|
||||
foo (int x, int w)
|
||||
{
|
||||
for (int y; y < w; y++)
|
||||
if (y < x)
|
||||
bar ();
|
||||
}
|
|
@ -484,6 +484,39 @@ compute_new_first_bound (gimple_seq *stmts, class tree_niter_desc *niter,
|
|||
return newend;
|
||||
}
|
||||
|
||||
/* Fix the two loop's bb count after split based on the split edge probability,
|
||||
don't adjust the bbs dominated by true branches of that loop to avoid
|
||||
dropping 1s down. */
|
||||
static void
|
||||
fix_loop_bb_probability (class loop *loop1, class loop *loop2, edge true_edge,
|
||||
edge false_edge)
|
||||
{
|
||||
update_ssa (TODO_update_ssa);
|
||||
|
||||
/* Proportion first loop's bb counts except those dominated by true
|
||||
branch to avoid drop 1s down. */
|
||||
basic_block *bbs1, *bbs2;
|
||||
bbs1 = get_loop_body (loop1);
|
||||
unsigned j;
|
||||
for (j = 0; j < loop1->num_nodes; j++)
|
||||
if (bbs1[j] == loop1->latch
|
||||
|| !dominated_by_p (CDI_DOMINATORS, bbs1[j], true_edge->dest))
|
||||
bbs1[j]->count
|
||||
= bbs1[j]->count.apply_probability (true_edge->probability);
|
||||
free (bbs1);
|
||||
|
||||
/* Proportion second loop's bb counts except those dominated by false
|
||||
branch to avoid drop 1s down. */
|
||||
basic_block bbi_copy = get_bb_copy (false_edge->dest);
|
||||
bbs2 = get_loop_body (loop2);
|
||||
for (j = 0; j < loop2->num_nodes; j++)
|
||||
if (bbs2[j] == loop2->latch
|
||||
|| !dominated_by_p (CDI_DOMINATORS, bbs2[j], bbi_copy))
|
||||
bbs2[j]->count
|
||||
= bbs2[j]->count.apply_probability (true_edge->probability.invert ());
|
||||
free (bbs2);
|
||||
}
|
||||
|
||||
/* Checks if LOOP contains an conditional block whose condition
|
||||
depends on which side in the iteration space it is, and if so
|
||||
splits the iteration space into two loops. Returns true if the
|
||||
|
@ -610,38 +643,14 @@ split_loop (class loop *loop1)
|
|||
tree guard_next = PHI_ARG_DEF_FROM_EDGE (phi, loop_latch_edge (loop1));
|
||||
patch_loop_exit (loop1, guard_stmt, guard_next, newend, initial_true);
|
||||
|
||||
update_ssa (TODO_update_ssa);
|
||||
|
||||
/* Proportion first loop's bb counts except those dominated by true
|
||||
branch to avoid drop 1s down. */
|
||||
basic_block *bbs1, *bbs2;
|
||||
bbs1 = get_loop_body (loop1);
|
||||
unsigned j;
|
||||
for (j = 0; j < loop1->num_nodes; j++)
|
||||
if (bbs1[j] == loop1->latch
|
||||
|| !dominated_by_p (CDI_DOMINATORS, bbs1[j], true_edge->dest))
|
||||
bbs1[j]->count
|
||||
= bbs1[j]->count.apply_probability (true_edge->probability);
|
||||
free (bbs1);
|
||||
fix_loop_bb_probability (loop1, loop2, true_edge, false_edge);
|
||||
|
||||
/* Fix first loop's exit probability after scaling. */
|
||||
edge exit_to_latch1 = single_pred_edge (loop1->latch);
|
||||
exit_to_latch1->probability = exit_to_latch1->probability.apply_scale (
|
||||
true_edge->probability.to_reg_br_prob_base (), REG_BR_PROB_BASE);
|
||||
exit_to_latch1->probability *= true_edge->probability;
|
||||
single_exit (loop1)->probability
|
||||
= exit_to_latch1->probability.invert ();
|
||||
|
||||
/* Proportion second loop's bb counts except those dominated by false
|
||||
branch to avoid drop 1s down. */
|
||||
basic_block bbi_copy = get_bb_copy (false_edge->dest);
|
||||
bbs2 = get_loop_body (loop2);
|
||||
for (j = 0; j < loop2->num_nodes; j++)
|
||||
if (bbs2[j] == loop2->latch
|
||||
|| !dominated_by_p (CDI_DOMINATORS, bbs2[j], bbi_copy))
|
||||
bbs2[j]->count = bbs2[j]->count.apply_probability (
|
||||
true_edge->probability.invert ());
|
||||
free (bbs2);
|
||||
|
||||
/* Finally patch out the two copies of the condition to be always
|
||||
true/false (or opposite). */
|
||||
gcond *force_true = as_a<gcond *> (last_stmt (bbs[i]));
|
||||
|
@ -1570,40 +1579,17 @@ do_split_loop_on_cond (struct loop *loop1, edge invar_branch)
|
|||
between loop1 and loop2. */
|
||||
connect_loop_phis (loop1, loop2, to_loop2);
|
||||
|
||||
update_ssa (TODO_update_ssa);
|
||||
|
||||
edge true_edge, false_edge, skip_edge1, skip_edge2;
|
||||
extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
|
||||
|
||||
/* Proportion first loop's bb counts except those dominated by true
|
||||
branch to avoid drop 1s down. */
|
||||
skip_edge1 = true_invar ? false_edge : true_edge;
|
||||
skip_edge2 = true_invar ? true_edge : false_edge;
|
||||
basic_block *bbs1, *bbs2;
|
||||
bbs1 = get_loop_body (loop1);
|
||||
unsigned j;
|
||||
for (j = 0; j < loop1->num_nodes; j++)
|
||||
if (bbs1[j] == loop1->latch
|
||||
|| !dominated_by_p (CDI_DOMINATORS, bbs1[j], skip_edge1->dest))
|
||||
bbs1[j]->count
|
||||
= bbs1[j]->count.apply_probability (skip_edge1->probability);
|
||||
free (bbs1);
|
||||
fix_loop_bb_probability (loop1, loop2, skip_edge1, skip_edge2);
|
||||
|
||||
/* Fix first loop's exit probability after scaling. */
|
||||
to_loop1->probability = invar_branch->probability.invert ();
|
||||
to_loop2->probability = invar_branch->probability;
|
||||
|
||||
/* Proportion second loop's bb counts except those dominated by false
|
||||
branch to avoid drop 1s down. */
|
||||
basic_block bbi_copy = get_bb_copy (skip_edge2->dest);
|
||||
bbs2 = get_loop_body (loop2);
|
||||
for (j = 0; j < loop2->num_nodes; j++)
|
||||
if (bbs2[j] == loop2->latch
|
||||
|| !dominated_by_p (CDI_DOMINATORS, bbs2[j], bbi_copy))
|
||||
bbs2[j]->count
|
||||
= bbs2[j]->count.apply_probability (skip_edge2->probability);
|
||||
free (bbs2);
|
||||
|
||||
free_original_copy_tables ();
|
||||
|
||||
return true;
|
||||
|
|
Loading…
Reference in New Issue