loop-unswitch-2.c: New testcase.
* gcc.dg/loop-unswitch-2.c: New testcase. * gcc.dg/loop-unswitch-1.c: New testcase. * tree-ssa-loop-unswitch.c (hoist_guard): Update profile. From-SVN: r245311
This commit is contained in:
parent
192b048b5c
commit
0b90c54148
5 changed files with 75 additions and 1 deletions
|
@ -1,3 +1,7 @@
|
|||
2017-02-09 Jan Hubicka <hubicka@ucw.cz>
|
||||
|
||||
* tree-ssa-loop-unswitch.c (hoist_guard): Update profile.
|
||||
|
||||
2017-02-09 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* omp-offload.c (oacc_loop_auto_partitions): Use || instead of |
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2017-02-09 Jan Hubicka <hubicka@ucw.cz>
|
||||
|
||||
* gcc.dg/loop-unswitch-2.c: Update testcase.
|
||||
* gcc.dg/loop-unswitch-1.c: Update testcase.
|
||||
|
||||
2017-02-09 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
PR c/79428
|
||||
|
|
|
@ -12,4 +12,5 @@ void foo (float **a, float **b, float *c, int n, int m, int l)
|
|||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "guard hoisted" 3 "unswitch" } } */
|
||||
/* { dg-final { scan-tree-dump-not "Invalid sum" "unswitch" } } */
|
||||
|
||||
|
|
|
@ -22,5 +22,6 @@ float *foo(int ustride, int size, float *src)
|
|||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "guard hoisted" 1 "unswitch" } } */
|
||||
/* { dg-final { scan-tree-dump-not "Invalid sum" "unswitch" } } */
|
||||
|
||||
|
||||
|
|
|
@ -787,6 +787,7 @@ hoist_guard (struct loop *loop, edge guard)
|
|||
edge te, fe, e, new_edge;
|
||||
gimple *stmt;
|
||||
basic_block guard_bb = guard->src;
|
||||
edge not_guard;
|
||||
gimple_stmt_iterator gsi;
|
||||
int flags = 0;
|
||||
bool fix_dom_of_exit;
|
||||
|
@ -818,18 +819,80 @@ hoist_guard (struct loop *loop, edge guard)
|
|||
update_stmt (cond_stmt);
|
||||
/* Create new loop pre-header. */
|
||||
e = split_block (pre_header, last_stmt (pre_header));
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
fprintf (dump_file, " Moving guard %i->%i (prob %i) to bb %i, "
|
||||
"new preheader is %i\n",
|
||||
guard->src->index, guard->dest->index, guard->probability,
|
||||
e->src->index, e->dest->index);
|
||||
|
||||
gcc_assert (loop_preheader_edge (loop)->src == e->dest);
|
||||
|
||||
if (guard == fe)
|
||||
{
|
||||
e->flags = EDGE_TRUE_VALUE;
|
||||
flags |= EDGE_FALSE_VALUE;
|
||||
not_guard = te;
|
||||
}
|
||||
else
|
||||
{
|
||||
e->flags = EDGE_FALSE_VALUE;
|
||||
flags |= EDGE_TRUE_VALUE;
|
||||
not_guard = fe;
|
||||
}
|
||||
new_edge = make_edge (pre_header, exit->dest, flags);
|
||||
|
||||
/* Determine the probability that we skip the loop. Assume that loop has
|
||||
same average number of iterations regardless outcome of guard. */
|
||||
new_edge->probability = guard->probability;
|
||||
int skip_count = guard->src->count
|
||||
? RDIV (guard->count * pre_header->count, guard->src->count)
|
||||
: apply_probability (guard->count, new_edge->probability);
|
||||
|
||||
if (skip_count > e->count)
|
||||
{
|
||||
fprintf (dump_file, " Capping count; expect profile inconsistency\n");
|
||||
skip_count = e->count;
|
||||
}
|
||||
new_edge->count = skip_count;
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
fprintf (dump_file, " Estimated probability of skipping loop is %i\n",
|
||||
new_edge->probability);
|
||||
|
||||
/* Update profile after the transform:
|
||||
|
||||
First decrease count of path from newly hoisted loop guard
|
||||
to loop header... */
|
||||
e->count -= skip_count;
|
||||
e->probability = REG_BR_PROB_BASE - new_edge->probability;
|
||||
e->dest->count = e->count;
|
||||
e->dest->frequency = EDGE_FREQUENCY (e);
|
||||
|
||||
/* ... now update profile to represent that original guard will be optimized
|
||||
away ... */
|
||||
guard->probability = 0;
|
||||
guard->count = 0;
|
||||
not_guard->probability = REG_BR_PROB_BASE;
|
||||
/* This count is wrong (frequency of not_guard does not change),
|
||||
but will be scaled later. */
|
||||
not_guard->count = guard->src->count;
|
||||
|
||||
/* ... finally scale everything in the loop except for guarded basic blocks
|
||||
where profile does not change. */
|
||||
basic_block *body = get_loop_body (loop);
|
||||
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
fprintf (dump_file, " Scaling nonguarded BBs in loop:");
|
||||
for (unsigned int i = 0; i < loop->num_nodes; i++)
|
||||
{
|
||||
basic_block bb = body[i];
|
||||
if (!dominated_by_p (CDI_DOMINATORS, bb, not_guard->dest))
|
||||
{
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
fprintf (dump_file, " %i", bb->index);
|
||||
scale_bbs_frequencies_int (&bb, 1, e->probability, REG_BR_PROB_BASE);
|
||||
}
|
||||
}
|
||||
|
||||
if (fix_dom_of_exit)
|
||||
set_immediate_dominator (CDI_DOMINATORS, exit->dest, pre_header);
|
||||
/* Add NEW_ADGE argument for all phi in post-header block. */
|
||||
|
@ -856,7 +919,7 @@ hoist_guard (struct loop *loop, edge guard)
|
|||
}
|
||||
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
fprintf (dump_file, " guard hoisted.\n");
|
||||
fprintf (dump_file, "\n guard hoisted.\n");
|
||||
}
|
||||
|
||||
/* Return true if phi argument for exit edge can be used
|
||||
|
|
Loading…
Add table
Reference in a new issue