cgraph.c (cgraph_edge::sreal_frequency): New function.
authorJan Hubicka <hubicka@ucw.cz>
Mon, 13 Nov 2017 17:23:25 +0000 (18:23 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Mon, 13 Nov 2017 17:23:25 +0000 (17:23 +0000)
* 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

gcc/ChangeLog
gcc/cgraph.c
gcc/cgraph.h
gcc/ipa-fnsummary.c
gcc/ipa-inline.c
gcc/profile-count.c
gcc/profile-count.h

index 316bd020c072214f06b90bf12a1f46b97cdb2db8..87d200b24f1d8bdd646c3c9b9d76446cf882aac0 100644 (file)
@@ -1,3 +1,19 @@
+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.
index 83e496b42398d85830784a79b2d0635095a06a7d..bc60fc90f566e09562397c1ca485f672276800d2 100644 (file)
@@ -3880,4 +3880,16 @@ cgraph_node::has_thunk_p (cgraph_node *node, void *)
   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"
index 8da8f605b6f2a37fde28791bb56422e212b46b1d..1c952eb509466f1bdd3ed97a7292743d8d9ff119 100644 (file)
@@ -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
      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);
@@ -3120,6 +3123,7 @@ cgraph_edge::frequency ()
                                    : 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)
index 6c0e4370066221dc0986d71667e1d44bd0a8710d..ddc16bd50d7d6068db1339e08781f0f2761eb1f2 100644 (file)
@@ -817,12 +817,12 @@ dump_ipa_call_summary (FILE *f, int indent, struct cgraph_node *node,
       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 indent, struct cgraph_node *node,
   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 cgraph_edge *e, int *size, int *min_size,
   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 (struct cgraph_edge *edge)
                                      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;
index 3128f320bddc5d9f508b51a13e5bd2ffe16d2b7a..8a2fd4baeeb5d4c27a81a87ae8ffef2346bad2e8 100644 (file)
@@ -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 cgraph_edge *edge,
       && 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_edge *edge,
   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);
index 9c57323db6e3c09db3985cc264fabdcb1907bbc7..51c3b74fefa1d3d14e734f33547d4cba9b20ccf4 100644 (file)
@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3.  If not see
 #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 (profile_count entry_bb_count) const
   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
index aa42b4e2397ad8ef07ca963daead459112ec7b72..90d1bc747eeaccda030326fac87525efc8c4353a 100644 (file)
@@ -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;