Hi all,

The attached patch is an attempt to fix the bug PR ipa/63576.
As it is said in the comment to the bug,

Jan Hubicka wrote:
> THen you need to sum counts (instead of taking ones from BB) and
> turn them back to frequencies (because it is profile only counts
> should be non-0)

It seems that counts and frequencies are gathered in some special
manner, and this patch simply adds counts from speculative edges and
from basic blocks. Of course, I don't know whether this way is proper
one, so please correct me or redirect to right place where it is
documented :)

Anyway, the patch was bootstrapped and regtested on
x86_64-unknown-linux-gnu.

Ok for trunk? 

gcc/

2014-10-22  Ilya Palachev  <i.palac...@samsung.com>

        * ipa-utils.c (compute_edge_count_and_frequency): New function
        (ipa_merge_profiles): handle speculative case
---
 gcc/ipa-utils.c | 52 ++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 42 insertions(+), 10 deletions(-)

diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c
index 552071e..335ab05 100644
--- a/gcc/ipa-utils.c
+++ b/gcc/ipa-utils.c
@@ -380,6 +380,46 @@ get_base_var (tree t)
   return t;
 }
 
+/* Computes count and frequency for edges.  */
+
+static void
+compute_edge_count_and_frequency(struct cgraph_edge *e,
+                                struct cgraph_node *dst)
+{
+  basic_block bb = gimple_bb (e->call_stmt);
+  if (!e->speculative)
+    {
+      e->count = bb->count;
+      e->frequency = compute_call_stmt_bb_frequency (dst->decl, bb);
+    }
+  else
+    {
+      if (profile_status_for_fn (DECL_STRUCT_FUNCTION (dst->decl))
+                     == PROFILE_ABSENT)
+        {
+         e->count = bb->count;
+         e->frequency = CGRAPH_FREQ_BASE;
+       }
+      else
+        {
+         gcc_assert (e->count >= 0);
+         e->count += bb->count;
+         gcc_assert (e->frequency >= 0);
+
+         int entry_freq = ENTRY_BLOCK_PTR_FOR_FN
+                               (DECL_STRUCT_FUNCTION (dst->decl))->frequency;
+         int freq = e->frequency + bb->frequency;
+
+         if (!entry_freq)
+           entry_freq = 1, freq++;
+
+         freq = freq * CGRAPH_FREQ_BASE / entry_freq;
+         if (freq > CGRAPH_FREQ_MAX)
+           freq = CGRAPH_FREQ_MAX;
+         e->frequency = freq;
+       }
+    }
+}
 
 /* SRC and DST are going to be merged.  Take SRC's profile and merge it into
    DST so it is not going to be lost.  Destroy SRC's body on the way.  */
@@ -537,19 +577,11 @@ ipa_merge_profiles (struct cgraph_node *dst,
       pop_cfun ();
       for (e = dst->callees; e; e = e->next_callee)
        {
-         gcc_assert (!e->speculative);
-         e->count = gimple_bb (e->call_stmt)->count;
-         e->frequency = compute_call_stmt_bb_frequency
-                            (dst->decl,
-                             gimple_bb (e->call_stmt));
+         compute_edge_count_and_frequency(e, dst);
        }
       for (e = dst->indirect_calls; e; e = e->next_callee)
        {
-         gcc_assert (!e->speculative);
-         e->count = gimple_bb (e->call_stmt)->count;
-         e->frequency = compute_call_stmt_bb_frequency
-                            (dst->decl,
-                             gimple_bb (e->call_stmt));
+         compute_edge_count_and_frequency(e, dst);
        }
       src->release_body ();
       inline_update_overall_summary (dst);
-- 
2.1.1

Reply via email to