predict.c (determine_unlikely_bbs): Forward declare...
* predict.c (determine_unlikely_bbs): Forward declare; also determine edges that are always known to be taken because it is only likely edge out of given BB. (tree_estimate_probability): Call before profile guessing to get bit of extra precision. * gcc.dg/predict-13.c: Update template. * gcc.dg/predict-13b.c: New testcase. * gcc.dg/predict-22.c: New testcase. * gcc.dg/tree-ssa/ipa-split-4.c: Change abort to other function to get sane profile. From-SVN: r266587
This commit is contained in:
parent
ad42aa96b6
commit
410902c31c
7 changed files with 142 additions and 14 deletions
|
@ -1,3 +1,11 @@
|
|||
2018-11-28 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* predict.c (determine_unlikely_bbs): Forward declare; also determine
|
||||
edges that are always known to be taken because it is only likely
|
||||
edge out of given BB.
|
||||
(tree_estimate_probability): Call before profile guessing to get bit
|
||||
of extra precision.
|
||||
|
||||
2018-11-28 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* tree-ssa-ifcombine.c (update_profile_after_ifcombine): Handle
|
||||
|
|
|
@ -93,6 +93,7 @@ static void predict_paths_leading_to_edge (edge, enum br_predictor,
|
|||
struct loop *in_loop = NULL);
|
||||
static bool can_predict_insn_p (const rtx_insn *);
|
||||
static HOST_WIDE_INT get_predictor_value (br_predictor, HOST_WIDE_INT);
|
||||
static void determine_unlikely_bbs ();
|
||||
|
||||
/* Information we hold about each branch predictor.
|
||||
Filled using information from predict.def. */
|
||||
|
@ -3063,6 +3064,9 @@ tree_estimate_probability (bool dry_run)
|
|||
preheaders. */
|
||||
create_preheaders (CP_SIMPLE_PREHEADERS);
|
||||
calculate_dominance_info (CDI_POST_DOMINATORS);
|
||||
/* Decide which edges are known to be unlikely. This improves later
|
||||
branch prediction. */
|
||||
determine_unlikely_bbs ();
|
||||
|
||||
bb_predictions = new hash_map<const_basic_block, edge_prediction *>;
|
||||
tree_bb_level_predictions ();
|
||||
|
@ -3768,17 +3772,40 @@ determine_unlikely_bbs ()
|
|||
}
|
||||
/* Finally all edges from non-0 regions to 0 are unlikely. */
|
||||
FOR_ALL_BB_FN (bb, cfun)
|
||||
if (!(bb->count == profile_count::zero ()))
|
||||
{
|
||||
if (!(bb->count == profile_count::zero ()))
|
||||
FOR_EACH_EDGE (e, ei, bb->succs)
|
||||
if (!(e->probability == profile_probability::never ())
|
||||
&& e->dest->count == profile_count::zero ())
|
||||
{
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
fprintf (dump_file, "Edge %i->%i is unlikely because "
|
||||
"it enters unlikely block\n",
|
||||
bb->index, e->dest->index);
|
||||
e->probability = profile_probability::never ();
|
||||
}
|
||||
|
||||
edge other = NULL;
|
||||
|
||||
FOR_EACH_EDGE (e, ei, bb->succs)
|
||||
if (!(e->probability == profile_probability::never ())
|
||||
&& e->dest->count == profile_count::zero ())
|
||||
{
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
fprintf (dump_file, "Edge %i->%i is unlikely because "
|
||||
"it enters unlikely block\n",
|
||||
bb->index, e->dest->index);
|
||||
e->probability = profile_probability::never ();
|
||||
}
|
||||
if (e->probability == profile_probability::never ())
|
||||
;
|
||||
else if (other)
|
||||
{
|
||||
other = NULL;
|
||||
break;
|
||||
}
|
||||
else
|
||||
other = e;
|
||||
if (other
|
||||
&& !(other->probability == profile_probability::always ()))
|
||||
{
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
fprintf (dump_file, "Edge %i->%i is locally likely\n",
|
||||
bb->index, other->dest->index);
|
||||
other->probability = profile_probability::always ();
|
||||
}
|
||||
}
|
||||
if (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count == profile_count::zero ())
|
||||
cgraph_node::get (current_function_decl)->count = profile_count::zero ();
|
||||
}
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
2018-11-28 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* gcc.dg/predict-13.c: Update template.
|
||||
* gcc.dg/predict-13b.c: New testcase.
|
||||
* gcc.dg/predict-22.c: New testcase.
|
||||
* gcc.dg/tree-ssa/ipa-split-4.c: Change abort to other function to
|
||||
get sane profile.
|
||||
|
||||
2018-11-28 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
PR c++/88222 - ICE with bit-field with invalid type.
|
||||
|
|
|
@ -20,5 +20,5 @@ int main(int argc, char **argv)
|
|||
return 10;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "combined heuristics of edge\[^:\]*: 33.30%" 3 "profile_estimate"} } */
|
||||
/* { dg-final { scan-tree-dump-times "combined heuristics of edge\[^:\]*: 0.05%" 2 "profile_estimate"} } */
|
||||
/* { dg-final { scan-tree-dump-times "33.33%" 3 "profile_estimate"} } */
|
||||
/* { dg-final { scan-tree-dump-times "0.00%" 3 "profile_estimate"} } */
|
||||
|
|
26
gcc/testsuite/gcc.dg/predict-13b.c
Normal file
26
gcc/testsuite/gcc.dg/predict-13b.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-profile_estimate" } */
|
||||
|
||||
void exit(int);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
switch (argc)
|
||||
{
|
||||
case 1:
|
||||
return 1;
|
||||
case 2:
|
||||
return 2;
|
||||
case 3:
|
||||
exit(1);
|
||||
case 4:
|
||||
exit(2);
|
||||
default:
|
||||
return 5;
|
||||
}
|
||||
|
||||
return 10;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "combined heuristics of edge\[^:\]*: 33.30%" 3 "profile_estimate"} } */
|
||||
/* { dg-final { scan-tree-dump-times "combined heuristics of edge\[^:\]*: 0.05%" 2 "profile_estimate"} } */
|
59
gcc/testsuite/gcc.dg/predict-22.c
Normal file
59
gcc/testsuite/gcc.dg/predict-22.c
Normal file
|
@ -0,0 +1,59 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-optimized-details-blocks -fdump-rtl-bbpart-details-blocks -freorder-blocks-and-partition" } */
|
||||
volatile int v;
|
||||
void bar (void) __attribute__((leaf, cold));
|
||||
void baz (int *);
|
||||
|
||||
void
|
||||
foo (int x, int y, int z)
|
||||
{
|
||||
static int f __attribute__((section ("mysection")));
|
||||
f = 1;
|
||||
if (__builtin_expect (x, 0))
|
||||
if (__builtin_expect (y, 0))
|
||||
if (__builtin_expect (z, 0))
|
||||
{
|
||||
f = 2;
|
||||
bar ();
|
||||
v += 1;
|
||||
v *= 2;
|
||||
v /= 2;
|
||||
v -= 1;
|
||||
v += 1;
|
||||
v *= 2;
|
||||
v /= 2;
|
||||
v -= 1;
|
||||
v += 1;
|
||||
v *= 2;
|
||||
v /= 2;
|
||||
v -= 1;
|
||||
v += 1;
|
||||
v *= 2;
|
||||
v /= 2;
|
||||
v -= 1;
|
||||
v += 1;
|
||||
v *= 2;
|
||||
v /= 2;
|
||||
v -= 1;
|
||||
v += 1;
|
||||
v *= 2;
|
||||
v /= 2;
|
||||
v -= 1;
|
||||
v += 1;
|
||||
v *= 2;
|
||||
v /= 2;
|
||||
v -= 1;
|
||||
v += 1;
|
||||
v *= 2;
|
||||
v /= 2;
|
||||
v -= 1;
|
||||
f = 3;
|
||||
__builtin_abort ();
|
||||
}
|
||||
f = 4;
|
||||
f = 5;
|
||||
baz (&f);
|
||||
}
|
||||
/* { dg-final { scan-tree-dump-times "Invalid sum" 0 "optimized"} } */
|
||||
/* { dg-final { scan-tree-dump-times "count 0," 1 "optimized"} } */
|
||||
/* { dg-final { scan-rtl-dump-times "COLD_PARTITION" 1 "bbpart"} } */
|
|
@ -1,14 +1,14 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O3 -fdump-tree-fnsplit" } */
|
||||
int make_me_big (void);
|
||||
void abort (void);
|
||||
void do_work (void);
|
||||
|
||||
int
|
||||
split_me (int a)
|
||||
{
|
||||
if (__builtin_expect(a<10, 1))
|
||||
{
|
||||
abort ();
|
||||
do_work ();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue