* 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
+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>
* diagnostic.c (maybe_line_and_column): New.
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"
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. */
int frequency ();
+
+ /* Expected frequency of executions within the function. */
+ sreal sreal_frequency ();
private:
/* Remove the edge from the list of the callers of the callee. */
void remove_caller (void);
: caller->count);
}
+
/* Return true if the TM_CLONE bit is set for a given FNDECL. */
static inline bool
decl_is_tm_clone (const_tree fndecl)
int i;
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",
indent, "", callee->name (), callee->order,
!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,
(int) ipa_fn_summaries->get (callee)->size / ipa_fn_summary::size_scale,
(int) ipa_fn_summaries->get (callee)->estimated_stack_size);
for (edge = node->indirect_calls; edge; edge = edge->next_callee)
{
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",
indent, "",
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)
{
fprintf (f, "predicate: ");
if (min_size)
*min_size += cur_size;
if (prob == REG_BR_PROB_BASE)
- *time += ((sreal)(call_time * e->frequency ())) / CGRAPH_FREQ_BASE;
+ *time += ((sreal)call_time) * e->sreal_frequency ();
else
- *time += ((sreal)call_time) * (prob * e->frequency ())
- / (CGRAPH_FREQ_BASE * REG_BR_PROB_BASE);
+ *time += ((sreal)call_time * prob) * e->sreal_frequency ()
+ / CGRAPH_FREQ_BASE;
}
toplev_predicate);
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,
clause, es->param);
add_time = add_time * prob / REG_BR_PROB_BASE;
static profile_count max_count;
static profile_count spec_rem;
-/* Pre-computed constants 1/CGRAPH_FREQ_BASE and 1/100. */
-static sreal cgraph_freq_base_rec, percent_rec;
+/* Pre-computed constant 1/100. */
+static sreal percent_rec;
/* Return false when inlining edge E would lead to violating
limits on function unit growth or stack usage growth.
&& caller->count.ipa ().nonzero_p ())
uninlined_call_time *= (sreal)edge->count.ipa ().to_gcov_type ()
/ caller->count.ipa ().to_gcov_type ();
- if (edge->frequency ())
- uninlined_call_time *= cgraph_freq_base_rec * edge->frequency ();
+ sreal freq = edge->sreal_frequency ();
+ if (freq != 0)
+ uninlined_call_time *= freq;
else
uninlined_call_time = uninlined_call_time >> 11;
if (edge->count.ipa ().nonzero_p ()
&& caller->count.ipa ().nonzero_p ())
time *= (sreal)edge->count.to_gcov_type () / caller->count.to_gcov_type ();
- if (edge->frequency ())
- time *= cgraph_freq_base_rec * edge->frequency ();
+ sreal freq = edge->sreal_frequency ();
+ if (freq != 0)
+ time *= freq;
else
time = time >> 11;
int cold;
bool remove_functions = false;
- cgraph_freq_base_rec = (sreal) 1 / (sreal) CGRAPH_FREQ_BASE;
percent_rec = (sreal) 1 / (sreal) 100;
order = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
#include "data-streamer.h"
#include "cgraph.h"
#include "wide-int.h"
+#include "sreal.h"
/* Dump THIS to F. */
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.
Take care of the side case when DEN is zeros. We still want to behave
sanely here which means
*/
+class sreal;
+
class GTY(()) profile_count
{
/* Use 62bit to hold basic block counters. Should be at least
int to_frequency (struct function *fun) 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. */
void dump (FILE *f) const;