diff mbox

PR ipa/63576: Process speculative edges in ICF

Message ID 1414423835-7124-1-git-send-email-i.palachev@samsung.com
State New
Headers show

Commit Message

Ilya Palachev Oct. 27, 2014, 3:30 p.m. UTC
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.palachev@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(-)

Comments

Jiong Wang Oct. 27, 2014, 3:41 p.m. UTC | #1
On 27/10/14 15:30, Ilya Palachev wrote:
> 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.palachev@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;
> +	}
> +    }
> +}

how about using early exit for above code, something like:

   if (!e->speculative
       || profile_status_for_fn (DECL_STRUCT_FUNCTION (dst->decl))
		             == PROFILE_ABSEN))
     {
       e->count = bb->count;
       e->frequency = (e->speculative ? CGRAPH_FREQ_BASE
                       : compute_call_stmt_bb_frequency (dst->decl, bb));
       return;
     }
  
   gcc_assert (e->count >= 0);
   ...
   ...


>   
>   /* 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);
diff mbox

Patch

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);