===================================================================
@@ -3880,4 +3880,16 @@ cgraph_node::has_thunk_p (cgraph_node *n
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"
===================================================================
@@ -1766,6 +1766,9 @@ struct GTY((chain_next ("%h.next_caller"
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);
===================================================================
@@ -817,12 +817,12 @@ dump_ipa_call_summary (FILE *f, int inde
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);
@@ -860,11 +860,12 @@ dump_ipa_call_summary (FILE *f, int inde
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: ");
@@ -2578,10 +2579,10 @@ estimate_edge_size_and_time (struct cgra
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;
}
@@ -3058,7 +3059,7 @@ ipa_merge_fn_summary_after_inlining (str
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;
===================================================================
@@ -129,8 +129,8 @@ static int overall_size;
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.
@@ -644,8 +644,9 @@ compute_uninlined_call_time (struct cgra
&& 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;
@@ -668,8 +669,9 @@ compute_inlined_call_time (struct cgraph
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;
@@ -2390,7 +2392,6 @@ ipa_inline (void)
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);
===================================================================
@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3.
#include "data-streamer.h"
#include "cgraph.h"
#include "wide-int.h"
+#include "sreal.h"
/* Dump THIS to F. */
@@ -256,6 +257,32 @@ profile_count::to_cgraph_frequency (prof
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
===================================================================
@@ -601,6 +601,8 @@ public:
*/
+class sreal;
+
class GTY(()) profile_count
{
/* Use 62bit to hold basic block counters. Should be at least
@@ -1034,6 +1036,7 @@ public:
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;