mirror of git://gcc.gnu.org/git/gcc.git
predict.c (maybe_hot_bb_p): Do not check profile status.
* predict.c (maybe_hot_bb_p): Do not check profile status. (maybe_hot_edge_p): Likewise. (probably_never_executed): Check for zero counts even if profile is not read. (unlikely_executed_edge_p): New function. (unlikely_executed_stmt_p): New function. (unlikely_executed_bb_p): New function. (set_even_probabilities): Use unlikely predicates. (combine_predictions_for_bb): Likewise. (predict_paths_for_bb): Likewise. (predict_paths_leading_to_edge): Likewise. (determine_unlikely_bbs): New function. (estimate_bb_frequencies): Use it. (compute_function_frequency): Use zero counts even if profile is not read. * profile-count.h: Fix typo. * g++.dg/tree-ssa/counts-1.C: New testcase. * gcc.dg/tree-ssa/counts-1.c: New testcase. From-SVN: r249013
This commit is contained in:
parent
c46f905165
commit
b69d9ac6a9
|
|
@ -1,3 +1,22 @@
|
||||||
|
2017-06-08 Jan Hubicka <hubicka@ucw.cz>
|
||||||
|
|
||||||
|
* predict.c (maybe_hot_bb_p): Do not check profile status.
|
||||||
|
(maybe_hot_edge_p): Likewise.
|
||||||
|
(probably_never_executed): Check for zero counts even if profile
|
||||||
|
is not read.
|
||||||
|
(unlikely_executed_edge_p): New function.
|
||||||
|
(unlikely_executed_stmt_p): New function.
|
||||||
|
(unlikely_executed_bb_p): New function.
|
||||||
|
(set_even_probabilities): Use unlikely predicates.
|
||||||
|
(combine_predictions_for_bb): Likewise.
|
||||||
|
(predict_paths_for_bb): Likewise.
|
||||||
|
(predict_paths_leading_to_edge): Likewise.
|
||||||
|
(determine_unlikely_bbs): New function.
|
||||||
|
(estimate_bb_frequencies): Use it.
|
||||||
|
(compute_function_frequency): Use zero counts even if profile is
|
||||||
|
not read.
|
||||||
|
* profile-count.h: Fix typo.
|
||||||
|
|
||||||
2017-08-08 Julia Koval <julia.koval@intel.com>
|
2017-08-08 Julia Koval <julia.koval@intel.com>
|
||||||
|
|
||||||
* config/i386/avx512bwintrin.h (_mm512_mask_cvtepi16_storeu_epi8,
|
* config/i386/avx512bwintrin.h (_mm512_mask_cvtepi16_storeu_epi8,
|
||||||
|
|
|
||||||
241
gcc/predict.c
241
gcc/predict.c
|
|
@ -189,8 +189,8 @@ bool
|
||||||
maybe_hot_bb_p (struct function *fun, const_basic_block bb)
|
maybe_hot_bb_p (struct function *fun, const_basic_block bb)
|
||||||
{
|
{
|
||||||
gcc_checking_assert (fun);
|
gcc_checking_assert (fun);
|
||||||
if (profile_status_for_fn (fun) == PROFILE_READ)
|
if (!maybe_hot_count_p (fun, bb->count))
|
||||||
return maybe_hot_count_p (fun, bb->count);
|
return false;
|
||||||
return maybe_hot_frequency_p (fun, bb->frequency);
|
return maybe_hot_frequency_p (fun, bb->frequency);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -200,8 +200,8 @@ maybe_hot_bb_p (struct function *fun, const_basic_block bb)
|
||||||
bool
|
bool
|
||||||
maybe_hot_edge_p (edge e)
|
maybe_hot_edge_p (edge e)
|
||||||
{
|
{
|
||||||
if (profile_status_for_fn (cfun) == PROFILE_READ)
|
if (!maybe_hot_count_p (cfun, e->count))
|
||||||
return maybe_hot_count_p (cfun, e->count);
|
return false;
|
||||||
return maybe_hot_frequency_p (cfun, EDGE_FREQUENCY (e));
|
return maybe_hot_frequency_p (cfun, EDGE_FREQUENCY (e));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -213,11 +213,10 @@ probably_never_executed (struct function *fun,
|
||||||
profile_count count, int)
|
profile_count count, int)
|
||||||
{
|
{
|
||||||
gcc_checking_assert (fun);
|
gcc_checking_assert (fun);
|
||||||
if (count.initialized_p () && profile_status_for_fn (fun) == PROFILE_READ)
|
|
||||||
{
|
|
||||||
if (count == profile_count::zero ())
|
if (count == profile_count::zero ())
|
||||||
return true;
|
return true;
|
||||||
|
if (count.initialized_p () && profile_status_for_fn (fun) == PROFILE_READ)
|
||||||
|
{
|
||||||
int unlikely_count_fraction = PARAM_VALUE (UNLIKELY_BB_COUNT_FRACTION);
|
int unlikely_count_fraction = PARAM_VALUE (UNLIKELY_BB_COUNT_FRACTION);
|
||||||
if (count.apply_scale (unlikely_count_fraction, 1) >= profile_info->runs)
|
if (count.apply_scale (unlikely_count_fraction, 1) >= profile_info->runs)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -763,6 +762,69 @@ dump_prediction (FILE *file, enum br_predictor predictor, int probability,
|
||||||
fprintf (file, "\n");
|
fprintf (file, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return true if E is unlikely executed. */
|
||||||
|
|
||||||
|
static bool
|
||||||
|
unlikely_executed_edge_p (edge e)
|
||||||
|
{
|
||||||
|
return e->count == profile_count::zero ()
|
||||||
|
|| (e->flags & (EDGE_EH | EDGE_FAKE));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return true if STMT is known to be unlikely executed. */
|
||||||
|
|
||||||
|
static bool
|
||||||
|
unlikely_executed_stmt_p (gimple *stmt)
|
||||||
|
{
|
||||||
|
if (!is_gimple_call (stmt))
|
||||||
|
return false;
|
||||||
|
/* NORETURN attribute enough is not strong enough: exit() may be quite
|
||||||
|
likely executed once during program run. */
|
||||||
|
if (gimple_call_fntype (stmt)
|
||||||
|
&& lookup_attribute ("cold",
|
||||||
|
TYPE_ATTRIBUTES (gimple_call_fntype (stmt)))
|
||||||
|
&& !lookup_attribute ("cold", DECL_ATTRIBUTES (current_function_decl)))
|
||||||
|
return true;
|
||||||
|
tree decl = gimple_call_fndecl (stmt);
|
||||||
|
if (!decl)
|
||||||
|
return false;
|
||||||
|
if (lookup_attribute ("cold", DECL_ATTRIBUTES (decl))
|
||||||
|
&& !lookup_attribute ("cold", DECL_ATTRIBUTES (current_function_decl)))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
cgraph_node *n = cgraph_node::get (decl);
|
||||||
|
if (!n)
|
||||||
|
return false;
|
||||||
|
enum availability avail;
|
||||||
|
n = n->ultimate_alias_target (&avail);
|
||||||
|
if (avail < AVAIL_AVAILABLE)
|
||||||
|
return NULL;
|
||||||
|
if (!n->analyzed
|
||||||
|
|| n->decl == current_function_decl)
|
||||||
|
return false;
|
||||||
|
return n->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return true if BB is unlikely executed. */
|
||||||
|
|
||||||
|
static bool
|
||||||
|
unlikely_executed_bb_p (basic_block bb)
|
||||||
|
{
|
||||||
|
if (bb->count == profile_count::zero ())
|
||||||
|
return true;
|
||||||
|
if (bb == ENTRY_BLOCK_PTR_FOR_FN (cfun) || bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
|
||||||
|
return false;
|
||||||
|
for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
|
||||||
|
!gsi_end_p (gsi); gsi_next (&gsi))
|
||||||
|
{
|
||||||
|
if (unlikely_executed_stmt_p (gsi_stmt (gsi)))
|
||||||
|
return true;
|
||||||
|
if (stmt_can_terminate_bb_p (gsi_stmt (gsi)))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* We can not predict the probabilities of outgoing edges of bb. Set them
|
/* We can not predict the probabilities of outgoing edges of bb. Set them
|
||||||
evenly and hope for the best. If UNLIKELY_EDGES is not null, distribute
|
evenly and hope for the best. If UNLIKELY_EDGES is not null, distribute
|
||||||
even probability for all edges not mentioned in the set. These edges
|
even probability for all edges not mentioned in the set. These edges
|
||||||
|
|
@ -777,7 +839,7 @@ set_even_probabilities (basic_block bb,
|
||||||
edge_iterator ei;
|
edge_iterator ei;
|
||||||
|
|
||||||
FOR_EACH_EDGE (e, ei, bb->succs)
|
FOR_EACH_EDGE (e, ei, bb->succs)
|
||||||
if (!(e->flags & (EDGE_EH | EDGE_FAKE)))
|
if (!unlikely_executed_edge_p (e))
|
||||||
nedges ++;
|
nedges ++;
|
||||||
|
|
||||||
/* Make the distribution even if all edges are unlikely. */
|
/* Make the distribution even if all edges are unlikely. */
|
||||||
|
|
@ -791,7 +853,7 @@ set_even_probabilities (basic_block bb,
|
||||||
unsigned c = nedges - unlikely_count;
|
unsigned c = nedges - unlikely_count;
|
||||||
|
|
||||||
FOR_EACH_EDGE (e, ei, bb->succs)
|
FOR_EACH_EDGE (e, ei, bb->succs)
|
||||||
if (!(e->flags & (EDGE_EH | EDGE_FAKE)))
|
if (!unlikely_executed_edge_p (e))
|
||||||
{
|
{
|
||||||
if (unlikely_edges != NULL && unlikely_edges->contains (e))
|
if (unlikely_edges != NULL && unlikely_edges->contains (e))
|
||||||
e->probability = PROB_VERY_UNLIKELY;
|
e->probability = PROB_VERY_UNLIKELY;
|
||||||
|
|
@ -1056,7 +1118,7 @@ combine_predictions_for_bb (basic_block bb, bool dry_run)
|
||||||
edge_iterator ei;
|
edge_iterator ei;
|
||||||
|
|
||||||
FOR_EACH_EDGE (e, ei, bb->succs)
|
FOR_EACH_EDGE (e, ei, bb->succs)
|
||||||
if (!(e->flags & (EDGE_EH | EDGE_FAKE)))
|
if (!unlikely_executed_edge_p (e))
|
||||||
{
|
{
|
||||||
nedges ++;
|
nedges ++;
|
||||||
if (first && !second)
|
if (first && !second)
|
||||||
|
|
@ -1107,7 +1169,7 @@ combine_predictions_for_bb (basic_block bb, bool dry_run)
|
||||||
"%i edges in bb %i predicted with some unlikely edges\n",
|
"%i edges in bb %i predicted with some unlikely edges\n",
|
||||||
nedges, bb->index);
|
nedges, bb->index);
|
||||||
FOR_EACH_EDGE (e, ei, bb->succs)
|
FOR_EACH_EDGE (e, ei, bb->succs)
|
||||||
if (!(e->flags & (EDGE_EH | EDGE_FAKE)))
|
if (!unlikely_executed_edge_p (e))
|
||||||
dump_prediction (dump_file, PRED_COMBINED, e->probability,
|
dump_prediction (dump_file, PRED_COMBINED, e->probability,
|
||||||
bb, REASON_NONE, e);
|
bb, REASON_NONE, e);
|
||||||
}
|
}
|
||||||
|
|
@ -1758,7 +1820,7 @@ predict_loops (void)
|
||||||
|
|
||||||
exits = get_loop_exit_edges (loop);
|
exits = get_loop_exit_edges (loop);
|
||||||
FOR_EACH_VEC_ELT (exits, j, ex)
|
FOR_EACH_VEC_ELT (exits, j, ex)
|
||||||
if (!(ex->flags & (EDGE_EH | EDGE_ABNORMAL_CALL | EDGE_FAKE)))
|
if (!unlikely_executed_edge_p (ex) && !(ex->flags & EDGE_ABNORMAL_CALL))
|
||||||
n_exits ++;
|
n_exits ++;
|
||||||
if (!n_exits)
|
if (!n_exits)
|
||||||
{
|
{
|
||||||
|
|
@ -1792,7 +1854,8 @@ predict_loops (void)
|
||||||
enum br_predictor predictor;
|
enum br_predictor predictor;
|
||||||
widest_int nit;
|
widest_int nit;
|
||||||
|
|
||||||
if (ex->flags & (EDGE_EH | EDGE_ABNORMAL_CALL | EDGE_FAKE))
|
if (unlikely_executed_edge_p (ex)
|
||||||
|
|| (ex->flags & EDGE_ABNORMAL_CALL))
|
||||||
continue;
|
continue;
|
||||||
/* Loop heuristics do not expect exit conditional to be inside
|
/* Loop heuristics do not expect exit conditional to be inside
|
||||||
inner loop. We predict from innermost to outermost loop. */
|
inner loop. We predict from innermost to outermost loop. */
|
||||||
|
|
@ -2609,7 +2672,7 @@ tree_bb_level_predictions (void)
|
||||||
edge_iterator ei;
|
edge_iterator ei;
|
||||||
|
|
||||||
FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
|
FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
|
||||||
if (!(e->flags & (EDGE_ABNORMAL | EDGE_FAKE | EDGE_EH)))
|
if (!unlikely_executed_edge_p (e) && !(e->flags & EDGE_ABNORMAL_CALL))
|
||||||
{
|
{
|
||||||
has_return_edges = true;
|
has_return_edges = true;
|
||||||
break;
|
break;
|
||||||
|
|
@ -2863,7 +2926,7 @@ predict_paths_for_bb (basic_block cur, basic_block bb,
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
/* Ignore fake edges and eh, we predict them as not taken anyway. */
|
/* Ignore fake edges and eh, we predict them as not taken anyway. */
|
||||||
if (e->flags & (EDGE_EH | EDGE_FAKE))
|
if (unlikely_executed_edge_p (e))
|
||||||
continue;
|
continue;
|
||||||
gcc_assert (bb == cur || dominated_by_p (CDI_POST_DOMINATORS, cur, bb));
|
gcc_assert (bb == cur || dominated_by_p (CDI_POST_DOMINATORS, cur, bb));
|
||||||
|
|
||||||
|
|
@ -2871,7 +2934,7 @@ predict_paths_for_bb (basic_block cur, basic_block bb,
|
||||||
and does not lead to BB and does not exit the loop. */
|
and does not lead to BB and does not exit the loop. */
|
||||||
FOR_EACH_EDGE (e2, ei2, e->src->succs)
|
FOR_EACH_EDGE (e2, ei2, e->src->succs)
|
||||||
if (e2 != e
|
if (e2 != e
|
||||||
&& !(e2->flags & (EDGE_EH | EDGE_FAKE))
|
&& !unlikely_executed_edge_p (e2)
|
||||||
&& !dominated_by_p (CDI_POST_DOMINATORS, e2->dest, bb)
|
&& !dominated_by_p (CDI_POST_DOMINATORS, e2->dest, bb)
|
||||||
&& (!in_loop || !loop_exit_edge_p (in_loop, e2)))
|
&& (!in_loop || !loop_exit_edge_p (in_loop, e2)))
|
||||||
{
|
{
|
||||||
|
|
@ -2923,7 +2986,7 @@ predict_paths_leading_to_edge (edge e, enum br_predictor pred,
|
||||||
basic_block bb = e->src;
|
basic_block bb = e->src;
|
||||||
FOR_EACH_EDGE (e2, ei, bb->succs)
|
FOR_EACH_EDGE (e2, ei, bb->succs)
|
||||||
if (e2->dest != e->src && e2->dest != e->dest
|
if (e2->dest != e->src && e2->dest != e->dest
|
||||||
&& !(e->flags & (EDGE_EH | EDGE_FAKE))
|
&& !unlikely_executed_edge_p (e)
|
||||||
&& !dominated_by_p (CDI_POST_DOMINATORS, e->src, e2->dest))
|
&& !dominated_by_p (CDI_POST_DOMINATORS, e->src, e2->dest))
|
||||||
{
|
{
|
||||||
has_nonloop_edge = true;
|
has_nonloop_edge = true;
|
||||||
|
|
@ -3341,6 +3404,142 @@ expensive_function_p (int threshold)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Determine basic blocks/edges that are known to be unlikely executed and set
|
||||||
|
their counters to zero.
|
||||||
|
This is done with first identifying obviously unlikely BBs/edges and then
|
||||||
|
propagating in both directions. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
determine_unlikely_bbs ()
|
||||||
|
{
|
||||||
|
basic_block bb;
|
||||||
|
auto_vec<basic_block, 64> worklist;
|
||||||
|
edge_iterator ei;
|
||||||
|
edge e;
|
||||||
|
|
||||||
|
FOR_EACH_BB_FN (bb, cfun)
|
||||||
|
{
|
||||||
|
if (!(bb->count == profile_count::zero ())
|
||||||
|
&& unlikely_executed_bb_p (bb))
|
||||||
|
{
|
||||||
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||||
|
fprintf (dump_file, "Basic block %i is locally unlikely\n",
|
||||||
|
bb->index);
|
||||||
|
bb->count = profile_count::zero ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bb->count == profile_count::zero ())
|
||||||
|
{
|
||||||
|
bb->frequency = 0;
|
||||||
|
FOR_EACH_EDGE (e, ei, bb->preds)
|
||||||
|
e->count = profile_count::zero ();
|
||||||
|
}
|
||||||
|
|
||||||
|
FOR_EACH_EDGE (e, ei, bb->succs)
|
||||||
|
if (!(e->count == profile_count::zero ())
|
||||||
|
&& unlikely_executed_edge_p (e))
|
||||||
|
{
|
||||||
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||||
|
fprintf (dump_file, "Edge %i->%i is locally unlikely\n",
|
||||||
|
bb->index, e->dest->index);
|
||||||
|
e->count = profile_count::zero ();
|
||||||
|
}
|
||||||
|
|
||||||
|
gcc_checking_assert (!bb->aux);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(ENTRY_BLOCK_PTR_FOR_FN (cfun)->count == profile_count::zero ()))
|
||||||
|
{
|
||||||
|
ENTRY_BLOCK_PTR_FOR_FN (cfun)->aux = (void *)(size_t) 1;
|
||||||
|
worklist.safe_push (ENTRY_BLOCK_PTR_FOR_FN (cfun));
|
||||||
|
|
||||||
|
while (worklist.length () > 0)
|
||||||
|
{
|
||||||
|
bb = worklist.pop ();
|
||||||
|
FOR_EACH_EDGE (e, ei, bb->succs)
|
||||||
|
if (!(e->count == profile_count::zero ())
|
||||||
|
&& !(e->dest->count == profile_count::zero ())
|
||||||
|
&& !e->dest->aux)
|
||||||
|
{
|
||||||
|
e->dest->aux = (void *)(size_t) 1;
|
||||||
|
worklist.safe_push (e->dest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FOR_ALL_BB_FN (bb, cfun)
|
||||||
|
{
|
||||||
|
if (!bb->aux)
|
||||||
|
{
|
||||||
|
if (!(bb->count == profile_count::zero ())
|
||||||
|
&& (dump_file && (dump_flags & TDF_DETAILS)))
|
||||||
|
fprintf (dump_file,
|
||||||
|
"Basic block %i is marked unlikely by forward prop\n",
|
||||||
|
bb->index);
|
||||||
|
bb->count = profile_count::zero ();
|
||||||
|
bb->frequency = 0;
|
||||||
|
FOR_EACH_EDGE (e, ei, bb->succs)
|
||||||
|
e->count = profile_count::zero ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bb->aux = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto_vec<int, 64> nsuccs;
|
||||||
|
nsuccs.safe_grow_cleared (last_basic_block_for_fn (cfun));
|
||||||
|
FOR_ALL_BB_FN (bb, cfun)
|
||||||
|
if (!(bb->count == profile_count::zero ())
|
||||||
|
&& bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
|
||||||
|
{
|
||||||
|
nsuccs[bb->index] = 0;
|
||||||
|
FOR_EACH_EDGE (e, ei, bb->succs)
|
||||||
|
if (!(e->count == profile_count::zero ()))
|
||||||
|
nsuccs[bb->index]++;
|
||||||
|
if (!nsuccs[bb->index])
|
||||||
|
worklist.safe_push (bb);
|
||||||
|
}
|
||||||
|
while (worklist.length () > 0)
|
||||||
|
{
|
||||||
|
bb = worklist.pop ();
|
||||||
|
if (bb != ENTRY_BLOCK_PTR_FOR_FN (cfun))
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
|
||||||
|
!gsi_end_p (gsi); gsi_next (&gsi))
|
||||||
|
if (stmt_can_terminate_bb_p (gsi_stmt (gsi))
|
||||||
|
/* stmt_can_terminate_bb_p special cases noreturns because it
|
||||||
|
assumes that fake edges are created. We want to know that
|
||||||
|
noreturn alone does not imply BB to be unlikely. */
|
||||||
|
|| (is_gimple_call (gsi_stmt (gsi))
|
||||||
|
&& (gimple_call_flags (gsi_stmt (gsi)) & ECF_NORETURN)))
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (found)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!(bb->count == profile_count::zero ())
|
||||||
|
&& (dump_file && (dump_flags & TDF_DETAILS)))
|
||||||
|
fprintf (dump_file,
|
||||||
|
"Basic block %i is marked unlikely by backward prop\n",
|
||||||
|
bb->index);
|
||||||
|
bb->count = profile_count::zero ();
|
||||||
|
bb->frequency = 0;
|
||||||
|
FOR_EACH_EDGE (e, ei, bb->preds)
|
||||||
|
if (!(e->count == profile_count::zero ()))
|
||||||
|
{
|
||||||
|
e->count = profile_count::zero ();
|
||||||
|
if (!(e->src->count == profile_count::zero ()))
|
||||||
|
{
|
||||||
|
nsuccs[e->src->index]--;
|
||||||
|
if (!nsuccs[e->src->index])
|
||||||
|
worklist.safe_push (e->src);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Estimate and propagate basic block frequencies using the given branch
|
/* Estimate and propagate basic block frequencies using the given branch
|
||||||
probabilities. If FORCE is true, the frequencies are used to estimate
|
probabilities. If FORCE is true, the frequencies are used to estimate
|
||||||
the counts even when there are already non-zero profile counts. */
|
the counts even when there are already non-zero profile counts. */
|
||||||
|
|
@ -3351,7 +3550,10 @@ estimate_bb_frequencies (bool force)
|
||||||
basic_block bb;
|
basic_block bb;
|
||||||
sreal freq_max;
|
sreal freq_max;
|
||||||
|
|
||||||
if (force || profile_status_for_fn (cfun) != PROFILE_READ || !counts_to_freqs ())
|
determine_unlikely_bbs ();
|
||||||
|
|
||||||
|
if (force || profile_status_for_fn (cfun) != PROFILE_READ
|
||||||
|
|| !counts_to_freqs ())
|
||||||
{
|
{
|
||||||
static int real_values_initialized = 0;
|
static int real_values_initialized = 0;
|
||||||
|
|
||||||
|
|
@ -3423,7 +3625,8 @@ compute_function_frequency (void)
|
||||||
if (profile_status_for_fn (cfun) != PROFILE_READ)
|
if (profile_status_for_fn (cfun) != PROFILE_READ)
|
||||||
{
|
{
|
||||||
int flags = flags_from_decl_or_type (current_function_decl);
|
int flags = flags_from_decl_or_type (current_function_decl);
|
||||||
if (lookup_attribute ("cold", DECL_ATTRIBUTES (current_function_decl))
|
if (ENTRY_BLOCK_PTR_FOR_FN (cfun)->count == profile_count::zero ()
|
||||||
|
|| lookup_attribute ("cold", DECL_ATTRIBUTES (current_function_decl))
|
||||||
!= NULL)
|
!= NULL)
|
||||||
node->frequency = NODE_FREQUENCY_UNLIKELY_EXECUTED;
|
node->frequency = NODE_FREQUENCY_UNLIKELY_EXECUTED;
|
||||||
else if (lookup_attribute ("hot", DECL_ATTRIBUTES (current_function_decl))
|
else if (lookup_attribute ("hot", DECL_ATTRIBUTES (current_function_decl))
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ along with GCC; see the file COPYING3. If not see
|
||||||
profile counts known while other do not - for example when LTO optimizing
|
profile counts known while other do not - for example when LTO optimizing
|
||||||
partly profiled program or when profile was lost due to COMDAT merging.
|
partly profiled program or when profile was lost due to COMDAT merging.
|
||||||
|
|
||||||
For this information profile_count tracks more information than
|
For this reason profile_count tracks more information than
|
||||||
just unsigned integer and it is also ready for profile mismatches.
|
just unsigned integer and it is also ready for profile mismatches.
|
||||||
The API of this data type represent operations that are natural
|
The API of this data type represent operations that are natural
|
||||||
on profile counts - sum, difference and operation with scales and
|
on profile counts - sum, difference and operation with scales and
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
2017-06-08 Jan Hubicka <hubicka@ucw.cz>
|
||||||
|
|
||||||
|
* g++.dg/tree-ssa/counts-1.C: New testcase.
|
||||||
|
* gcc.dg/tree-ssa/counts-1.c: New testcase.
|
||||||
|
|
||||||
2017-08-08 Julia Koval <julia.koval@intel.com>
|
2017-08-08 Julia Koval <julia.koval@intel.com>
|
||||||
|
|
||||||
* gcc.target/i386/avx512bw-vpmovswb-1.c: Add new intrinsics to test.
|
* gcc.target/i386/avx512bw-vpmovswb-1.c: Add new intrinsics to test.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-O2 -fdump-tree-optimized" } */
|
||||||
|
void foo();
|
||||||
|
extern void abort (void);
|
||||||
|
|
||||||
|
static __attribute__ ((noinline))
|
||||||
|
void mark_me_unlikely ()
|
||||||
|
{
|
||||||
|
foo();
|
||||||
|
foo();
|
||||||
|
foo();
|
||||||
|
foo();
|
||||||
|
}
|
||||||
|
|
||||||
|
void i_am_not_unlikely()
|
||||||
|
{
|
||||||
|
try { foo(); }
|
||||||
|
catch (int) {mark_me_unlikely ();}
|
||||||
|
}
|
||||||
|
/* { dg-final { scan-tree-dump "mark_me_unlikely\[^\r\n\]*(unlikely executed)" "optimized"} } */
|
||||||
|
/* { dg-final { scan-tree-dump-not "i_am_not_unlikely\[^\r\n\]*(unlikely executed)" "optimized"} } */
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-O2 -fdump-tree-optimized" } */
|
||||||
|
void unlikely () __attribute__ ((cold));
|
||||||
|
void unlikely2 () __attribute__ ((cold));
|
||||||
|
|
||||||
|
__attribute__ ((noinline)) void
|
||||||
|
i_am_also_unlikely (int a)
|
||||||
|
{
|
||||||
|
if (a)
|
||||||
|
unlikely ();
|
||||||
|
else
|
||||||
|
unlikely2 ();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
i_am_also_unlikely2 (int a,int b)
|
||||||
|
{
|
||||||
|
if (b)
|
||||||
|
i_am_also_unlikely (a);
|
||||||
|
else
|
||||||
|
unlikely ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
i_am_not_unlikely (int a,int b,int c)
|
||||||
|
{
|
||||||
|
if (c)
|
||||||
|
__builtin_exit (0);
|
||||||
|
i_am_also_unlikely2 (a,b);
|
||||||
|
}
|
||||||
|
/* Detect i_am_also_unlikely i_am_also_unlikely2 as unlikely. */
|
||||||
|
/* { dg-final { scan-tree-dump "i_am_also_unlikely\[^\r\n\]*(unlikely executed)" "optimized"} } */
|
||||||
|
/* { dg-final { scan-tree-dump "i_am_also_unlikely2\[^\r\n\]*(unlikely executed)" "optimized"} } */
|
||||||
|
/* { dg-final { scan-tree-dump-not "i_am_not_unlikely\[^\r\n\]*(unlikely executed)" "optimized"} } */
|
||||||
Loading…
Reference in New Issue