Commit 41f0e819 by Jan Hubicka Committed by Jan Hubicka

cgraph.c (cgraph_edge::sreal_frequency): New function.


	* cgraph.c (cgraph_edge::sreal_frequency): New function.
	* cgraph.h (cgraph_edge::sreal_frequency): Declare.
	* ipa-fnsummary.c (dump_ipa_call_summary): Use sreal_frequency.
	(estimate_edge_size_and_time): Likewise.
	(ipa_merge_fn_summary_after_inlining): Likewise.
	* ipa-inline.c (cgraph_freq_base_rec): Remove.
	(compute_uninlined_call_time): Use sreal_frequency.
	(compute_inlined_call_time): Likewise.
	(ipa_inline): Do not initialize cgraph_freq_base_rec.
	* profile-count.c: Include sreal.h.
	(profile_count::to_sreal_scale): New.
	* profile-count.h: Forward declare sreal.
	(profile_count::to_sreal_scale): Declare.

From-SVN: r254696
parent 8f2b097e
2017-11-13 Jan Hubicka <hubicka@ucw.cz>
* cgraph.c (cgraph_edge::sreal_frequency): New function.
* cgraph.h (cgraph_edge::sreal_frequency): Declare.
* ipa-fnsummary.c (dump_ipa_call_summary): Use sreal_frequency.
(estimate_edge_size_and_time): Likewise.
(ipa_merge_fn_summary_after_inlining): Likewise.
* ipa-inline.c (cgraph_freq_base_rec): Remove.
(compute_uninlined_call_time): Use sreal_frequency.
(compute_inlined_call_time): Likewise.
(ipa_inline): Do not initialize cgraph_freq_base_rec.
* profile-count.c: Include sreal.h.
(profile_count::to_sreal_scale): New.
* profile-count.h: Forward declare sreal.
(profile_count::to_sreal_scale): Declare.
2017-11-13 Nathan Sidwell <nathan@acm.org> 2017-11-13 Nathan Sidwell <nathan@acm.org>
* diagnostic.c (maybe_line_and_column): New. * diagnostic.c (maybe_line_and_column): New.
...@@ -3880,4 +3880,16 @@ cgraph_node::has_thunk_p (cgraph_node *node, void *) ...@@ -3880,4 +3880,16 @@ cgraph_node::has_thunk_p (cgraph_node *node, void *)
return false; return false;
} }
/* Expected frequency of executions within the function.
When set to CGRAPH_FREQ_BASE, the edge is expected to be called once
per function call. The range is 0 to CGRAPH_FREQ_MAX. */
sreal
cgraph_edge::sreal_frequency ()
{
return count.to_sreal_scale (caller->global.inlined_to
? caller->global.inlined_to->count
: caller->count);
}
#include "gt-cgraph.h" #include "gt-cgraph.h"
...@@ -1766,6 +1766,9 @@ struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"), ...@@ -1766,6 +1766,9 @@ struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"),
When set to CGRAPH_FREQ_BASE, the edge is expected to be called once When set to CGRAPH_FREQ_BASE, the edge is expected to be called once
per function call. The range is 0 to CGRAPH_FREQ_MAX. */ per function call. The range is 0 to CGRAPH_FREQ_MAX. */
int frequency (); int frequency ();
/* Expected frequency of executions within the function. */
sreal sreal_frequency ();
private: private:
/* Remove the edge from the list of the callers of the callee. */ /* Remove the edge from the list of the callers of the callee. */
void remove_caller (void); void remove_caller (void);
...@@ -3120,6 +3123,7 @@ cgraph_edge::frequency () ...@@ -3120,6 +3123,7 @@ cgraph_edge::frequency ()
: caller->count); : caller->count);
} }
/* Return true if the TM_CLONE bit is set for a given FNDECL. */ /* Return true if the TM_CLONE bit is set for a given FNDECL. */
static inline bool static inline bool
decl_is_tm_clone (const_tree fndecl) decl_is_tm_clone (const_tree fndecl)
......
...@@ -817,12 +817,12 @@ dump_ipa_call_summary (FILE *f, int indent, struct cgraph_node *node, ...@@ -817,12 +817,12 @@ dump_ipa_call_summary (FILE *f, int indent, struct cgraph_node *node,
int i; int i;
fprintf (f, fprintf (f,
"%*s%s/%i %s\n%*s loop depth:%2i freq:%4i size:%2i" "%*s%s/%i %s\n%*s loop depth:%2i freq:%4.2f size:%2i"
" time: %2i callee size:%2i stack:%2i", " time: %2i callee size:%2i stack:%2i",
indent, "", callee->name (), callee->order, indent, "", callee->name (), callee->order,
!edge->inline_failed !edge->inline_failed
? "inlined" : cgraph_inline_failed_string (edge-> inline_failed), ? "inlined" : cgraph_inline_failed_string (edge-> inline_failed),
indent, "", es->loop_depth, edge->frequency (), indent, "", es->loop_depth, edge->sreal_frequency ().to_double (),
es->call_stmt_size, es->call_stmt_time, es->call_stmt_size, es->call_stmt_time,
(int) ipa_fn_summaries->get (callee)->size / ipa_fn_summary::size_scale, (int) ipa_fn_summaries->get (callee)->size / ipa_fn_summary::size_scale,
(int) ipa_fn_summaries->get (callee)->estimated_stack_size); (int) ipa_fn_summaries->get (callee)->estimated_stack_size);
...@@ -860,11 +860,12 @@ dump_ipa_call_summary (FILE *f, int indent, struct cgraph_node *node, ...@@ -860,11 +860,12 @@ dump_ipa_call_summary (FILE *f, int indent, struct cgraph_node *node,
for (edge = node->indirect_calls; edge; edge = edge->next_callee) for (edge = node->indirect_calls; edge; edge = edge->next_callee)
{ {
struct ipa_call_summary *es = ipa_call_summaries->get (edge); struct ipa_call_summary *es = ipa_call_summaries->get (edge);
fprintf (f, "%*sindirect call loop depth:%2i freq:%4i size:%2i" fprintf (f, "%*sindirect call loop depth:%2i freq:%4.2f size:%2i"
" time: %2i", " time: %2i",
indent, "", indent, "",
es->loop_depth, es->loop_depth,
edge->frequency (), es->call_stmt_size, es->call_stmt_time); edge->sreal_frequency ().to_double (), es->call_stmt_size,
es->call_stmt_time);
if (es->predicate) if (es->predicate)
{ {
fprintf (f, "predicate: "); fprintf (f, "predicate: ");
...@@ -2578,10 +2579,10 @@ estimate_edge_size_and_time (struct cgraph_edge *e, int *size, int *min_size, ...@@ -2578,10 +2579,10 @@ estimate_edge_size_and_time (struct cgraph_edge *e, int *size, int *min_size,
if (min_size) if (min_size)
*min_size += cur_size; *min_size += cur_size;
if (prob == REG_BR_PROB_BASE) if (prob == REG_BR_PROB_BASE)
*time += ((sreal)(call_time * e->frequency ())) / CGRAPH_FREQ_BASE; *time += ((sreal)call_time) * e->sreal_frequency ();
else else
*time += ((sreal)call_time) * (prob * e->frequency ()) *time += ((sreal)call_time * prob) * e->sreal_frequency ()
/ (CGRAPH_FREQ_BASE * REG_BR_PROB_BASE); / CGRAPH_FREQ_BASE;
} }
...@@ -3058,7 +3059,7 @@ ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge) ...@@ -3058,7 +3059,7 @@ ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge)
toplev_predicate); toplev_predicate);
if (p != false && nonconstp != false) if (p != false && nonconstp != false)
{ {
sreal add_time = ((sreal)e->time * edge->frequency ()) / CGRAPH_FREQ_BASE; sreal add_time = ((sreal)e->time * edge->sreal_frequency ());
int prob = e->nonconst_predicate.probability (callee_info->conds, int prob = e->nonconst_predicate.probability (callee_info->conds,
clause, es->param); clause, es->param);
add_time = add_time * prob / REG_BR_PROB_BASE; add_time = add_time * prob / REG_BR_PROB_BASE;
......
...@@ -129,8 +129,8 @@ static int overall_size; ...@@ -129,8 +129,8 @@ static int overall_size;
static profile_count max_count; static profile_count max_count;
static profile_count spec_rem; static profile_count spec_rem;
/* Pre-computed constants 1/CGRAPH_FREQ_BASE and 1/100. */ /* Pre-computed constant 1/100. */
static sreal cgraph_freq_base_rec, percent_rec; static sreal percent_rec;
/* Return false when inlining edge E would lead to violating /* Return false when inlining edge E would lead to violating
limits on function unit growth or stack usage growth. limits on function unit growth or stack usage growth.
...@@ -644,8 +644,9 @@ compute_uninlined_call_time (struct cgraph_edge *edge, ...@@ -644,8 +644,9 @@ compute_uninlined_call_time (struct cgraph_edge *edge,
&& caller->count.ipa ().nonzero_p ()) && caller->count.ipa ().nonzero_p ())
uninlined_call_time *= (sreal)edge->count.ipa ().to_gcov_type () uninlined_call_time *= (sreal)edge->count.ipa ().to_gcov_type ()
/ caller->count.ipa ().to_gcov_type (); / caller->count.ipa ().to_gcov_type ();
if (edge->frequency ()) sreal freq = edge->sreal_frequency ();
uninlined_call_time *= cgraph_freq_base_rec * edge->frequency (); if (freq != 0)
uninlined_call_time *= freq;
else else
uninlined_call_time = uninlined_call_time >> 11; uninlined_call_time = uninlined_call_time >> 11;
...@@ -668,8 +669,9 @@ compute_inlined_call_time (struct cgraph_edge *edge, ...@@ -668,8 +669,9 @@ compute_inlined_call_time (struct cgraph_edge *edge,
if (edge->count.ipa ().nonzero_p () if (edge->count.ipa ().nonzero_p ()
&& caller->count.ipa ().nonzero_p ()) && caller->count.ipa ().nonzero_p ())
time *= (sreal)edge->count.to_gcov_type () / caller->count.to_gcov_type (); time *= (sreal)edge->count.to_gcov_type () / caller->count.to_gcov_type ();
if (edge->frequency ()) sreal freq = edge->sreal_frequency ();
time *= cgraph_freq_base_rec * edge->frequency (); if (freq != 0)
time *= freq;
else else
time = time >> 11; time = time >> 11;
...@@ -2390,7 +2392,6 @@ ipa_inline (void) ...@@ -2390,7 +2392,6 @@ ipa_inline (void)
int cold; int cold;
bool remove_functions = false; bool remove_functions = false;
cgraph_freq_base_rec = (sreal) 1 / (sreal) CGRAPH_FREQ_BASE;
percent_rec = (sreal) 1 / (sreal) 100; percent_rec = (sreal) 1 / (sreal) 100;
order = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count); order = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
......
...@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see
#include "data-streamer.h" #include "data-streamer.h"
#include "cgraph.h" #include "cgraph.h"
#include "wide-int.h" #include "wide-int.h"
#include "sreal.h"
/* Dump THIS to F. */ /* Dump THIS to F. */
...@@ -256,6 +257,32 @@ profile_count::to_cgraph_frequency (profile_count entry_bb_count) const ...@@ -256,6 +257,32 @@ profile_count::to_cgraph_frequency (profile_count entry_bb_count) const
return MIN (scale, CGRAPH_FREQ_MAX); return MIN (scale, CGRAPH_FREQ_MAX);
} }
/* Return THIS/IN as sreal value. */
sreal
profile_count::to_sreal_scale (profile_count in, bool *known) const
{
if (!initialized_p ())
{
if (known)
*known = false;
return CGRAPH_FREQ_BASE;
}
if (known)
*known = true;
if (*this == profile_count::zero ())
return 0;
gcc_checking_assert (in.initialized_p ());
if (!in.m_val)
{
if (!m_val)
return 1;
return m_val * 4;
}
return (sreal)m_val / (sreal)in.m_val;
}
/* We want to scale profile across function boundary from NUM to DEN. /* We want to scale profile across function boundary from NUM to DEN.
Take care of the side case when DEN is zeros. We still want to behave Take care of the side case when DEN is zeros. We still want to behave
sanely here which means sanely here which means
......
...@@ -601,6 +601,8 @@ public: ...@@ -601,6 +601,8 @@ public:
*/ */
class sreal;
class GTY(()) profile_count class GTY(()) profile_count
{ {
/* Use 62bit to hold basic block counters. Should be at least /* Use 62bit to hold basic block counters. Should be at least
...@@ -1034,6 +1036,7 @@ public: ...@@ -1034,6 +1036,7 @@ public:
int to_frequency (struct function *fun) const; int to_frequency (struct function *fun) const;
int to_cgraph_frequency (profile_count entry_bb_count) const; int to_cgraph_frequency (profile_count entry_bb_count) const;
sreal to_sreal_scale (profile_count in, bool *known = NULL) const;
/* Output THIS to F. */ /* Output THIS to F. */
void dump (FILE *f) const; void dump (FILE *f) const;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment