re PR tree-optimization/80218 (tree-call-cdce does not update block frequencies)
gcc/ PR tree-optimization/80218 * tree-call-cdce.c (shrink_wrap_one_built_in_call_with_conds): Update block frequencies and counts. gcc/testsuite/ PR tree-optimization/80218 * gcc.dg/pr80218.c: New test. From-SVN: r246538
This commit is contained in:
parent
ea7d7da886
commit
522818b971
|
@ -1,3 +1,9 @@
|
||||||
|
2017-03-28 Richard Sandiford <richard.sandiford@arm.com>
|
||||||
|
|
||||||
|
PR tree-optimization/80218
|
||||||
|
* tree-call-cdce.c (shrink_wrap_one_built_in_call_with_conds):
|
||||||
|
Update block frequencies and counts.
|
||||||
|
|
||||||
2017-03-28 Richard Biener <rguenther@suse.de>
|
2017-03-28 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
PR tree-optimization/78644
|
PR tree-optimization/78644
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
2017-03-28 Richard Sandiford <richard.sandiford@arm.com>
|
||||||
|
|
||||||
|
PR tree-optimization/80218
|
||||||
|
* gcc.dg/pr80218.c: New test.
|
||||||
|
|
||||||
2017-03-28 Richard Biener <rguenther@suse.de>
|
2017-03-28 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
PR tree-optimization/78644
|
PR tree-optimization/78644
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
/* { dg-options "-O2 -fdump-rtl-ira-details-blocks" } */
|
||||||
|
/* { dg-require-effective-target c99_runtime } */
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
void foo (float *);
|
||||||
|
|
||||||
|
void
|
||||||
|
f1 (float *x)
|
||||||
|
{
|
||||||
|
x[0] = sqrtf (x[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
f2 (float *x)
|
||||||
|
{
|
||||||
|
sqrtf (x[0]);
|
||||||
|
foo (x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
f3 (float *x)
|
||||||
|
{
|
||||||
|
acosf (x[0]);
|
||||||
|
foo (x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* { dg-final { scan-rtl-dump-not "Invalid sum" "ira" } } */
|
|
@ -847,10 +847,12 @@ shrink_wrap_one_built_in_call_with_conds (gcall *bi_call, vec <gimple *> conds,
|
||||||
gsi_insert_before (&bi_call_bsi, c, GSI_SAME_STMT);
|
gsi_insert_before (&bi_call_bsi, c, GSI_SAME_STMT);
|
||||||
cond_expr = c;
|
cond_expr = c;
|
||||||
}
|
}
|
||||||
nconds--;
|
|
||||||
ci++;
|
ci++;
|
||||||
gcc_assert (cond_expr && gimple_code (cond_expr) == GIMPLE_COND);
|
gcc_assert (cond_expr && gimple_code (cond_expr) == GIMPLE_COND);
|
||||||
|
|
||||||
|
typedef std::pair<edge, edge> edge_pair;
|
||||||
|
auto_vec<edge_pair, 8> edges;
|
||||||
|
|
||||||
bi_call_in_edge0 = split_block (bi_call_bb, cond_expr);
|
bi_call_in_edge0 = split_block (bi_call_bb, cond_expr);
|
||||||
bi_call_in_edge0->flags &= ~EDGE_FALLTHRU;
|
bi_call_in_edge0->flags &= ~EDGE_FALLTHRU;
|
||||||
bi_call_in_edge0->flags |= EDGE_FALSE_VALUE;
|
bi_call_in_edge0->flags |= EDGE_FALSE_VALUE;
|
||||||
|
@ -859,17 +861,11 @@ shrink_wrap_one_built_in_call_with_conds (gcall *bi_call, vec <gimple *> conds,
|
||||||
join_tgt_in_edge_fall_thru = make_edge (guard_bb, join_tgt_bb,
|
join_tgt_in_edge_fall_thru = make_edge (guard_bb, join_tgt_bb,
|
||||||
EDGE_TRUE_VALUE);
|
EDGE_TRUE_VALUE);
|
||||||
|
|
||||||
bi_call_in_edge0->probability = REG_BR_PROB_BASE * ERR_PROB;
|
edges.reserve (nconds);
|
||||||
bi_call_in_edge0->count =
|
edges.quick_push (edge_pair (bi_call_in_edge0, join_tgt_in_edge_fall_thru));
|
||||||
apply_probability (guard_bb->count,
|
|
||||||
bi_call_in_edge0->probability);
|
|
||||||
join_tgt_in_edge_fall_thru->probability =
|
|
||||||
inverse_probability (bi_call_in_edge0->probability);
|
|
||||||
join_tgt_in_edge_fall_thru->count =
|
|
||||||
guard_bb->count - bi_call_in_edge0->count;
|
|
||||||
|
|
||||||
/* Code generation for the rest of the conditions */
|
/* Code generation for the rest of the conditions */
|
||||||
while (nconds > 0)
|
for (unsigned int i = 1; i < nconds; ++i)
|
||||||
{
|
{
|
||||||
unsigned ci0;
|
unsigned ci0;
|
||||||
edge bi_call_in_edge;
|
edge bi_call_in_edge;
|
||||||
|
@ -885,7 +881,6 @@ shrink_wrap_one_built_in_call_with_conds (gcall *bi_call, vec <gimple *> conds,
|
||||||
gsi_insert_before (&guard_bsi, c, GSI_SAME_STMT);
|
gsi_insert_before (&guard_bsi, c, GSI_SAME_STMT);
|
||||||
cond_expr = c;
|
cond_expr = c;
|
||||||
}
|
}
|
||||||
nconds--;
|
|
||||||
ci++;
|
ci++;
|
||||||
gcc_assert (cond_expr && gimple_code (cond_expr) == GIMPLE_COND);
|
gcc_assert (cond_expr && gimple_code (cond_expr) == GIMPLE_COND);
|
||||||
guard_bb_in_edge = split_block (guard_bb, cond_expr);
|
guard_bb_in_edge = split_block (guard_bb, cond_expr);
|
||||||
|
@ -893,14 +888,51 @@ shrink_wrap_one_built_in_call_with_conds (gcall *bi_call, vec <gimple *> conds,
|
||||||
guard_bb_in_edge->flags |= EDGE_TRUE_VALUE;
|
guard_bb_in_edge->flags |= EDGE_TRUE_VALUE;
|
||||||
|
|
||||||
bi_call_in_edge = make_edge (guard_bb, bi_call_bb, EDGE_FALSE_VALUE);
|
bi_call_in_edge = make_edge (guard_bb, bi_call_bb, EDGE_FALSE_VALUE);
|
||||||
|
edges.quick_push (edge_pair (bi_call_in_edge, guard_bb_in_edge));
|
||||||
|
}
|
||||||
|
|
||||||
bi_call_in_edge->probability = REG_BR_PROB_BASE * ERR_PROB;
|
/* Now update the probability and profile information, processing the
|
||||||
bi_call_in_edge->count =
|
guards in order of execution.
|
||||||
apply_probability (guard_bb->count,
|
|
||||||
bi_call_in_edge->probability);
|
There are two approaches we could take here. On the one hand we
|
||||||
guard_bb_in_edge->probability =
|
could assign a probability of X to the call block and distribute
|
||||||
inverse_probability (bi_call_in_edge->probability);
|
that probability among its incoming edges. On the other hand we
|
||||||
guard_bb_in_edge->count = guard_bb->count - bi_call_in_edge->count;
|
could assign a probability of X to each individual call edge.
|
||||||
|
|
||||||
|
The choice only affects calls that have more than one condition.
|
||||||
|
In those cases, the second approach would give the call block
|
||||||
|
a greater probability than the first. However, the difference
|
||||||
|
is only small, and our chosen X is a pure guess anyway.
|
||||||
|
|
||||||
|
Here we take the second approach because it's slightly simpler
|
||||||
|
and because it's easy to see that it doesn't lose profile counts. */
|
||||||
|
bi_call_bb->count = 0;
|
||||||
|
bi_call_bb->frequency = 0;
|
||||||
|
while (!edges.is_empty ())
|
||||||
|
{
|
||||||
|
edge_pair e = edges.pop ();
|
||||||
|
edge call_edge = e.first;
|
||||||
|
edge nocall_edge = e.second;
|
||||||
|
basic_block src_bb = call_edge->src;
|
||||||
|
gcc_assert (src_bb == nocall_edge->src);
|
||||||
|
|
||||||
|
call_edge->probability = REG_BR_PROB_BASE * ERR_PROB;
|
||||||
|
call_edge->count = apply_probability (src_bb->count,
|
||||||
|
call_edge->probability);
|
||||||
|
nocall_edge->probability = inverse_probability (call_edge->probability);
|
||||||
|
nocall_edge->count = src_bb->count - call_edge->count;
|
||||||
|
|
||||||
|
unsigned int call_frequency = apply_probability (src_bb->frequency,
|
||||||
|
call_edge->probability);
|
||||||
|
|
||||||
|
bi_call_bb->count += call_edge->count;
|
||||||
|
bi_call_bb->frequency += call_frequency;
|
||||||
|
|
||||||
|
if (nocall_edge->dest != join_tgt_bb)
|
||||||
|
{
|
||||||
|
nocall_edge->dest->count = nocall_edge->count;
|
||||||
|
nocall_edge->dest->frequency = src_bb->frequency - call_frequency;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dom_info_available_p (CDI_DOMINATORS))
|
if (dom_info_available_p (CDI_DOMINATORS))
|
||||||
|
|
Loading…
Reference in New Issue