diff mbox series

[stage1] Construct ipa_reduced_postorder always for overwritable (PR ipa/89009).

Message ID b6c7fda5-bcee-f0b1-b796-4b58ee6f972e@suse.cz
State New
Headers show
Series [stage1] Construct ipa_reduced_postorder always for overwritable (PR ipa/89009). | expand

Commit Message

Martin Liška Feb. 19, 2019, 12:43 p.m. UTC
On 2/14/19 11:19 AM, Jan Hubicka wrote:
>> Hi.
>>
>> This is patch candidate I created and tested. It's not adding
>> filtering based on opt_for_fn which I would defer to the next
>> stage1.
>>
>> Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
>>
>> Ready to be installed?
>> Thanks,
>> Martin
> 
>> From d036f75a880bc91f67a5473767b35ba2f8a4ffe3 Mon Sep 17 00:00:00 2001
>> From: marxin <mliska@suse.cz>
>> Date: Mon, 11 Feb 2019 16:47:06 +0100
>> Subject: [PATCH] Reduce SCCs in IPA postorder.
>>
>> gcc/ChangeLog:
>>
>> 2019-02-13  Martin Liska  <mliska@suse.cz>
>>
>> 	* ipa-cp.c (build_toporder_info): Use
>> 	ignore_edge_if_not_available as edge filter.
>> 	* ipa-inline.c (inline_small_functions): Likewise.
>> 	* ipa-pure-const.c (ignore_edge_for_pure_const):
>> 	Move to ipa-utils.h and rename to ignore_edge_if_not_available.
>> 	(propagate_pure_const): Use ignore_edge_if_not_available
>> 	as edge filter.
>> 	* ipa-reference.c (ignore_edge_p): Make SCCs more fine
>> 	based on availability and ECF_LEAF attribute.
>> 	* ipa-utils.c (searchc): Refactor code.
>> 	* ipa-utils.h (ignore_edge_if_not_available): New.
> 
> OK, I think it is safe to wait for stage1 - it is bit fragile to
> propagate across different graph then postorder is computed (as
> manifested by the bug) but it should be safe if SCCs are simply bigger
> then they should be.
> 
> Next stage1 we should also teach the callback to ignore edges of calls
> that are not being optimized.

I'm sending patch for that.

Patch can bootstrap on x86_64-linux-gnu and survives regression tests.

Ready to be installed after we enter stage1?
Thanks,
Martin

> 
> Honza
>> ---
>>  gcc/ipa-cp.c         |  3 ++-
>>  gcc/ipa-inline.c     |  2 +-
>>  gcc/ipa-pure-const.c | 13 +------------
>>  gcc/ipa-reference.c  | 13 ++++++++++---
>>  gcc/ipa-utils.c      |  3 +--
>>  gcc/ipa-utils.h      | 10 ++++++++++
>>  6 files changed, 25 insertions(+), 19 deletions(-)
>>
>> diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
>> index 442d5c63eff..2253b0cef63 100644
>> --- a/gcc/ipa-cp.c
>> +++ b/gcc/ipa-cp.c
>> @@ -815,7 +815,8 @@ build_toporder_info (struct ipa_topo_info *topo)
>>    topo->stack = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
>>  
>>    gcc_checking_assert (topo->stack_top == 0);
>> -  topo->nnodes = ipa_reduced_postorder (topo->order, true, NULL);
>> +  topo->nnodes = ipa_reduced_postorder (topo->order, true,
>> +					ignore_edge_if_not_available);
>>  }
>>  
>>  /* Free information about strongly connected components and the arrays in
>> diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
>> index 360c3de3289..c7e68a73706 100644
>> --- a/gcc/ipa-inline.c
>> +++ b/gcc/ipa-inline.c
>> @@ -1778,7 +1778,7 @@ inline_small_functions (void)
>>       metrics.  */
>>  
>>    max_count = profile_count::uninitialized ();
>> -  ipa_reduced_postorder (order, true, NULL);
>> +  ipa_reduced_postorder (order, true, ignore_edge_if_not_available);
>>    free (order);
>>  
>>    FOR_EACH_DEFINED_FUNCTION (node)
>> diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
>> index a8a3956d2d5..e61d279289e 100644
>> --- a/gcc/ipa-pure-const.c
>> +++ b/gcc/ipa-pure-const.c
>> @@ -1395,17 +1395,6 @@ cdtor_p (cgraph_node *n, void *)
>>    return false;
>>  }
>>  
>> -/* We only propagate across edges with non-interposable callee.  */
>> -
>> -static bool
>> -ignore_edge_for_pure_const (struct cgraph_edge *e)
>> -{
>> -  enum availability avail;
>> -  e->callee->function_or_virtual_thunk_symbol (&avail, e->caller);
>> -  return (avail <= AVAIL_INTERPOSABLE);
>> -}
>> -
>> -
>>  /* Produce transitive closure over the callgraph and compute pure/const
>>     attributes.  */
>>  
>> @@ -1423,7 +1412,7 @@ propagate_pure_const (void)
>>    bool has_cdtor;
>>  
>>    order_pos = ipa_reduced_postorder (order, true,
>> -				     ignore_edge_for_pure_const);
>> +				     ignore_edge_if_not_available);
>>    if (dump_file)
>>      {
>>        cgraph_node::dump_cgraph (dump_file);
>> diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c
>> index d1759a374bc..16cc4cf44f9 100644
>> --- a/gcc/ipa-reference.c
>> +++ b/gcc/ipa-reference.c
>> @@ -677,14 +677,21 @@ get_read_write_all_from_node (struct cgraph_node *node,
>>        }
>>  }
>>  
>> -/* Skip edges from and to nodes without ipa_reference enables.  This leave
>> -   them out of strongy connected coponents and makes them easyto skip in the
>> +/* Skip edges from and to nodes without ipa_reference enabled.
>> +   Ignore not available symbols.  This leave
>> +   them out of strongly connected components and makes them easy to skip in the
>>     propagation loop bellow.  */
>>  
>>  static bool
>>  ignore_edge_p (cgraph_edge *e)
>>  {
>> -  return (!opt_for_fn (e->caller->decl, flag_ipa_reference)
>> +  enum availability avail;
>> +  e->callee->function_or_virtual_thunk_symbol (&avail, e->caller);
>> +
>> +  return (avail < AVAIL_INTERPOSABLE
>> +	  || (avail == AVAIL_INTERPOSABLE
>> +	      && !(flags_from_decl_or_type (e->callee->decl) & ECF_LEAF))
>> +	  || !opt_for_fn (e->caller->decl, flag_ipa_reference)
>>            || !opt_for_fn (e->callee->function_symbol ()->decl,
>>  			  flag_ipa_reference));
>>  }
>> diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c
>> index 79b250c3943..25c2e2cf789 100644
>> --- a/gcc/ipa-utils.c
>> +++ b/gcc/ipa-utils.c
>> @@ -103,8 +103,7 @@ searchc (struct searchc_env* env, struct cgraph_node *v,
>>          continue;
>>  
>>        if (w->aux
>> -	  && (avail > AVAIL_INTERPOSABLE
>> -	      || avail == AVAIL_INTERPOSABLE))
>> +	  && (avail >= AVAIL_INTERPOSABLE))
>>  	{
>>  	  w_info = (struct ipa_dfs_info *) w->aux;
>>  	  if (w_info->new_node)
>> diff --git a/gcc/ipa-utils.h b/gcc/ipa-utils.h
>> index b70e8c57108..aad08148348 100644
>> --- a/gcc/ipa-utils.h
>> +++ b/gcc/ipa-utils.h
>> @@ -262,6 +262,16 @@ odr_type_p (const_tree t)
>>    return false;
>>  }
>>  
>> +/* We only propagate across edges with non-interposable callee.  */
>> +
>> +inline bool
>> +ignore_edge_if_not_available (struct cgraph_edge *e)
>> +{
>> +  enum availability avail;
>> +  e->callee->function_or_virtual_thunk_symbol (&avail, e->caller);
>> +  return (avail <= AVAIL_INTERPOSABLE);
>> +}
>> +
>>  #endif  /* GCC_IPA_UTILS_H  */
>>  
>>  
>> -- 
>> 2.20.1
>>
>

Comments

Martin Jambor Feb. 19, 2019, 1:25 p.m. UTC | #1
Hi,

On Tue, Feb 19 2019, Martin Liška wrote:
> On 2/14/19 11:19 AM, Jan Hubicka wrote:
>>

...

>> Next stage1 we should also teach the callback to ignore edges of calls
>> that are not being optimized.
>
> I'm sending patch for that.

...

> gcc/ChangeLog:
>
> 2019-02-19  Martin Liska  <mliska@suse.cz>
>
> 	* ipa-cp.c (ignore_edge_p): New function.
> 	(build_toporder_info): Use it.
> 	* ipa-inline.c (ignore_edge_p): New function/
> 	(inline_small_functions): Use it.
> 	* ipa-pure-const.c (ignore_edge_for_nothrow):
> 	Verify opt_for_fn for caller and callee.
> 	(ignore_edge_for_pure_const): Likewise.
> 	* ipa-reference.c (ignore_edge_p): Extend to check
> 	for opt_for_fn.
> 	* ipa-utils.c (searchc): Refactor.
> 	* ipa-utils.h: Fix coding style.
> ---
>  gcc/ipa-cp.c         | 18 +++++++++++++++++-
>  gcc/ipa-inline.c     | 12 +++++++++++-
>  gcc/ipa-pure-const.c | 17 ++++++++++++-----
>  gcc/ipa-reference.c  | 13 ++++++++++---
>  gcc/ipa-utils.c      |  3 +--
>  gcc/ipa-utils.h      |  2 --
>  6 files changed, 51 insertions(+), 14 deletions(-)
>
> diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
> index 442d5c63eff..004b3a34b1c 100644
> --- a/gcc/ipa-cp.c
> +++ b/gcc/ipa-cp.c
> @@ -806,6 +806,21 @@ public:
>    {}
>  };
>  
> +/* Skip edges from and to nodes without ipa_cp enabled.
> +   Ignore not available symbols.  */
> +
> +static bool
> +ignore_edge_p (cgraph_edge *e)
> +{
> +  enum availability avail;
> +  e->callee->function_or_virtual_thunk_symbol (&avail, e->caller);

Can't the return value of this call be directly fed...

> +
> +  return (avail <= AVAIL_INTERPOSABLE
> +	  || !opt_for_fn (e->caller->decl, flag_ipa_cp)
> +	  || !opt_for_fn (e->callee->function_symbol ()->decl,

...here instead of calling function_symbol... which does not look
through thunks which IMHO you want, even if only for consistency.

Otherwise, it the IPA-CP bits obviously look good,

Martin
Martin Liška Feb. 20, 2019, 9:10 a.m. UTC | #2
On 2/19/19 2:25 PM, Martin Jambor wrote:
> Hi,
> 
> On Tue, Feb 19 2019, Martin Liška wrote:
>> On 2/14/19 11:19 AM, Jan Hubicka wrote:
>>>
> 
> ...
> 
>>> Next stage1 we should also teach the callback to ignore edges of calls
>>> that are not being optimized.
>>
>> I'm sending patch for that.
> 
> ...
> 
>> gcc/ChangeLog:
>>
>> 2019-02-19  Martin Liska  <mliska@suse.cz>
>>
>> 	* ipa-cp.c (ignore_edge_p): New function.
>> 	(build_toporder_info): Use it.
>> 	* ipa-inline.c (ignore_edge_p): New function/
>> 	(inline_small_functions): Use it.
>> 	* ipa-pure-const.c (ignore_edge_for_nothrow):
>> 	Verify opt_for_fn for caller and callee.
>> 	(ignore_edge_for_pure_const): Likewise.
>> 	* ipa-reference.c (ignore_edge_p): Extend to check
>> 	for opt_for_fn.
>> 	* ipa-utils.c (searchc): Refactor.
>> 	* ipa-utils.h: Fix coding style.
>> ---
>>  gcc/ipa-cp.c         | 18 +++++++++++++++++-
>>  gcc/ipa-inline.c     | 12 +++++++++++-
>>  gcc/ipa-pure-const.c | 17 ++++++++++++-----
>>  gcc/ipa-reference.c  | 13 ++++++++++---
>>  gcc/ipa-utils.c      |  3 +--
>>  gcc/ipa-utils.h      |  2 --
>>  6 files changed, 51 insertions(+), 14 deletions(-)
>>
>> diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
>> index 442d5c63eff..004b3a34b1c 100644
>> --- a/gcc/ipa-cp.c
>> +++ b/gcc/ipa-cp.c
>> @@ -806,6 +806,21 @@ public:
>>    {}
>>  };
>>  
>> +/* Skip edges from and to nodes without ipa_cp enabled.
>> +   Ignore not available symbols.  */
>> +
>> +static bool
>> +ignore_edge_p (cgraph_edge *e)
>> +{
>> +  enum availability avail;
>> +  e->callee->function_or_virtual_thunk_symbol (&avail, e->caller);
> 
> Can't the return value of this call be directly fed...
> 
>> +
>> +  return (avail <= AVAIL_INTERPOSABLE
>> +	  || !opt_for_fn (e->caller->decl, flag_ipa_cp)
>> +	  || !opt_for_fn (e->callee->function_symbol ()->decl,
> 
> ...here instead of calling function_symbol... which does not look
> through thunks which IMHO you want, even if only for consistency.

Yes, I like it.

There's a new version of the patch I've just tested.

Martin

> 
> Otherwise, it the IPA-CP bits obviously look good,
> 
> Martin
>
From 2f18f1610640013fbc3a1eea9360b400b0d322e9 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Mon, 11 Feb 2019 16:47:06 +0100
Subject: [PATCH] Reduce SCCs in IPA postorder.

gcc/ChangeLog:

2019-02-19  Martin Liska  <mliska@suse.cz>

	* ipa-cp.c (ignore_edge_p): New function.
	(build_toporder_info): Use it.
	* ipa-inline.c (ignore_edge_p): New function/
	(inline_small_functions): Use it.
	* ipa-pure-const.c (ignore_edge_for_nothrow):
	Verify opt_for_fn for caller and callee.
	(ignore_edge_for_pure_const): Likewise.
	* ipa-reference.c (ignore_edge_p): Extend to check
	for opt_for_fn.
	* ipa-utils.c (searchc): Refactor.
	* ipa-utils.h: Fix coding style.
---
 gcc/ipa-cp.c         | 18 +++++++++++++++++-
 gcc/ipa-inline.c     | 12 +++++++++++-
 gcc/ipa-pure-const.c | 25 ++++++++++++++++---------
 gcc/ipa-reference.c  | 17 ++++++++++++-----
 gcc/ipa-utils.c      |  3 +--
 gcc/ipa-utils.h      |  2 --
 6 files changed, 57 insertions(+), 20 deletions(-)

diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 442d5c63eff..6959b7db1aa 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -806,6 +806,21 @@ public:
   {}
 };
 
+/* Skip edges from and to nodes without ipa_cp enabled.
+   Ignore not available symbols.  */
+
+static bool
+ignore_edge_p (cgraph_edge *e)
+{
+  enum availability avail;
+  cgraph_node *ultimate_target
+    = e->callee->function_or_virtual_thunk_symbol (&avail, e->caller);
+
+  return (avail <= AVAIL_INTERPOSABLE
+	  || !opt_for_fn (e->caller->decl, flag_ipa_cp)
+	  || !opt_for_fn (ultimate_target->decl, flag_ipa_cp));
+}
+
 /* Allocate the arrays in TOPO and topologically sort the nodes into order.  */
 
 static void
@@ -815,7 +830,8 @@ build_toporder_info (struct ipa_topo_info *topo)
   topo->stack = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
 
   gcc_checking_assert (topo->stack_top == 0);
-  topo->nnodes = ipa_reduced_postorder (topo->order, true, NULL);
+  topo->nnodes = ipa_reduced_postorder (topo->order, true,
+					ignore_edge_p);
 }
 
 /* Free information about strongly connected components and the arrays in
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 360c3de3289..d6314bc0e57 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -1751,6 +1751,16 @@ sum_callers (struct cgraph_node *node, void *data)
   return false;
 }
 
+/* We only propagate across edges with non-interposable callee.  */
+
+inline bool
+ignore_edge_p (struct cgraph_edge *e)
+{
+  enum availability avail;
+  e->callee->function_or_virtual_thunk_symbol (&avail, e->caller);
+  return (avail <= AVAIL_INTERPOSABLE);
+}
+
 /* We use greedy algorithm for inlining of small functions:
    All inline candidates are put into prioritized heap ordered in
    increasing badness.
@@ -1778,7 +1788,7 @@ inline_small_functions (void)
      metrics.  */
 
   max_count = profile_count::uninitialized ();
-  ipa_reduced_postorder (order, true, NULL);
+  ipa_reduced_postorder (order, true, ignore_edge_p);
   free (order);
 
   FOR_EACH_DEFINED_FUNCTION (node)
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index bb561d00853..f5e53967df1 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -1361,12 +1361,14 @@ ignore_edge_for_nothrow (struct cgraph_edge *e)
     return true;
 
   enum availability avail;
-  cgraph_node *n = e->callee->function_or_virtual_thunk_symbol (&avail,
-							        e->caller);
-  if (avail <= AVAIL_INTERPOSABLE || TREE_NOTHROW (n->decl))
+  cgraph_node *ultimate_target
+    = e->callee->function_or_virtual_thunk_symbol (&avail, e->caller);
+  if (avail <= AVAIL_INTERPOSABLE || TREE_NOTHROW (ultimate_target->decl))
     return true;
-  return opt_for_fn (e->callee->decl, flag_non_call_exceptions)
-	 && !e->callee->binds_to_current_def_p (e->caller);
+  return ((opt_for_fn (e->callee->decl, flag_non_call_exceptions)
+	   && !e->callee->binds_to_current_def_p (e->caller))
+	  || !opt_for_fn (e->caller->decl, flag_ipa_pure_const)
+	  || !opt_for_fn (ultimate_target->decl, flag_ipa_pure_const));
 }
 
 /* Return true if NODE is self recursive function.
@@ -1396,16 +1398,21 @@ cdtor_p (cgraph_node *n, void *)
   return false;
 }
 
-/* We only propagate across edges with non-interposable callee.  */
+/* Skip edges from and to nodes without ipa_pure_const enabled.
+   Ignore not available symbols.  */
 
 static bool
 ignore_edge_for_pure_const (struct cgraph_edge *e)
 {
   enum availability avail;
-  e->callee->function_or_virtual_thunk_symbol (&avail, e->caller);
-  return (avail <= AVAIL_INTERPOSABLE);
-}
+  cgraph_node *ultimate_target
+    = e->callee->function_or_virtual_thunk_symbol (&avail, e->caller);
 
+  return (avail <= AVAIL_INTERPOSABLE
+	  || !opt_for_fn (e->caller->decl, flag_ipa_pure_const)
+	  || !opt_for_fn (ultimate_target->decl,
+			  flag_ipa_pure_const));
+}
 
 /* Produce transitive closure over the callgraph and compute pure/const
    attributes.  */
diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c
index 9ef03c2505b..7b2614ffa28 100644
--- a/gcc/ipa-reference.c
+++ b/gcc/ipa-reference.c
@@ -676,16 +676,23 @@ get_read_write_all_from_node (struct cgraph_node *node,
       }
 }
 
-/* Skip edges from and to nodes without ipa_reference enables.  This leave
-   them out of strongy connected coponents and makes them easyto skip in the
+/* Skip edges from and to nodes without ipa_reference enabled.
+   Ignore not available symbols.  This leave
+   them out of strongly connected components and makes them easy to skip in the
    propagation loop bellow.  */
 
 static bool
 ignore_edge_p (cgraph_edge *e)
 {
-  return (!opt_for_fn (e->caller->decl, flag_ipa_reference)
-          || !opt_for_fn (e->callee->function_symbol ()->decl,
-			  flag_ipa_reference));
+  enum availability avail;
+  cgraph_node *ultimate_target
+    = e->callee->function_or_virtual_thunk_symbol (&avail, e->caller);
+
+  return (avail < AVAIL_INTERPOSABLE
+	  || (avail == AVAIL_INTERPOSABLE
+	      && !(flags_from_decl_or_type (e->callee->decl) & ECF_LEAF))
+	  || !opt_for_fn (e->caller->decl, flag_ipa_reference)
+          || !opt_for_fn (ultimate_target->decl, flag_ipa_reference));
 }
 
 /* Produce the global information by preforming a transitive closure
diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c
index 79b250c3943..25c2e2cf789 100644
--- a/gcc/ipa-utils.c
+++ b/gcc/ipa-utils.c
@@ -103,8 +103,7 @@ searchc (struct searchc_env* env, struct cgraph_node *v,
         continue;
 
       if (w->aux
-	  && (avail > AVAIL_INTERPOSABLE
-	      || avail == AVAIL_INTERPOSABLE))
+	  && (avail >= AVAIL_INTERPOSABLE))
 	{
 	  w_info = (struct ipa_dfs_info *) w->aux;
 	  if (w_info->new_node)
diff --git a/gcc/ipa-utils.h b/gcc/ipa-utils.h
index b70e8c57108..c4a9664852a 100644
--- a/gcc/ipa-utils.h
+++ b/gcc/ipa-utils.h
@@ -263,5 +263,3 @@ odr_type_p (const_tree t)
 }
 
 #endif  /* GCC_IPA_UTILS_H  */
-
-
Martin Liška March 6, 2019, 10:05 a.m. UTC | #3
@Honza: PING^1

On 2/20/19 10:10 AM, Martin Liška wrote:
> On 2/19/19 2:25 PM, Martin Jambor wrote:
>> Hi,
>>
>> On Tue, Feb 19 2019, Martin Liška wrote:
>>> On 2/14/19 11:19 AM, Jan Hubicka wrote:
>>>>
>>
>> ...
>>
>>>> Next stage1 we should also teach the callback to ignore edges of calls
>>>> that are not being optimized.
>>>
>>> I'm sending patch for that.
>>
>> ...
>>
>>> gcc/ChangeLog:
>>>
>>> 2019-02-19  Martin Liska  <mliska@suse.cz>
>>>
>>> 	* ipa-cp.c (ignore_edge_p): New function.
>>> 	(build_toporder_info): Use it.
>>> 	* ipa-inline.c (ignore_edge_p): New function/
>>> 	(inline_small_functions): Use it.
>>> 	* ipa-pure-const.c (ignore_edge_for_nothrow):
>>> 	Verify opt_for_fn for caller and callee.
>>> 	(ignore_edge_for_pure_const): Likewise.
>>> 	* ipa-reference.c (ignore_edge_p): Extend to check
>>> 	for opt_for_fn.
>>> 	* ipa-utils.c (searchc): Refactor.
>>> 	* ipa-utils.h: Fix coding style.
>>> ---
>>>  gcc/ipa-cp.c         | 18 +++++++++++++++++-
>>>  gcc/ipa-inline.c     | 12 +++++++++++-
>>>  gcc/ipa-pure-const.c | 17 ++++++++++++-----
>>>  gcc/ipa-reference.c  | 13 ++++++++++---
>>>  gcc/ipa-utils.c      |  3 +--
>>>  gcc/ipa-utils.h      |  2 --
>>>  6 files changed, 51 insertions(+), 14 deletions(-)
>>>
>>> diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
>>> index 442d5c63eff..004b3a34b1c 100644
>>> --- a/gcc/ipa-cp.c
>>> +++ b/gcc/ipa-cp.c
>>> @@ -806,6 +806,21 @@ public:
>>>    {}
>>>  };
>>>  
>>> +/* Skip edges from and to nodes without ipa_cp enabled.
>>> +   Ignore not available symbols.  */
>>> +
>>> +static bool
>>> +ignore_edge_p (cgraph_edge *e)
>>> +{
>>> +  enum availability avail;
>>> +  e->callee->function_or_virtual_thunk_symbol (&avail, e->caller);
>>
>> Can't the return value of this call be directly fed...
>>
>>> +
>>> +  return (avail <= AVAIL_INTERPOSABLE
>>> +	  || !opt_for_fn (e->caller->decl, flag_ipa_cp)
>>> +	  || !opt_for_fn (e->callee->function_symbol ()->decl,
>>
>> ...here instead of calling function_symbol... which does not look
>> through thunks which IMHO you want, even if only for consistency.
> 
> Yes, I like it.
> 
> There's a new version of the patch I've just tested.
> 
> Martin
> 
>>
>> Otherwise, it the IPA-CP bits obviously look good,
>>
>> Martin
>>
>
Martin Liška April 30, 2019, 12:52 p.m. UTC | #4
PING^2

On 3/6/19 11:05 AM, Martin Liška wrote:
> @Honza: PING^1
> 
> On 2/20/19 10:10 AM, Martin Liška wrote:
>> On 2/19/19 2:25 PM, Martin Jambor wrote:
>>> Hi,
>>>
>>> On Tue, Feb 19 2019, Martin Liška wrote:
>>>> On 2/14/19 11:19 AM, Jan Hubicka wrote:
>>>>>
>>>
>>> ...
>>>
>>>>> Next stage1 we should also teach the callback to ignore edges of calls
>>>>> that are not being optimized.
>>>>
>>>> I'm sending patch for that.
>>>
>>> ...
>>>
>>>> gcc/ChangeLog:
>>>>
>>>> 2019-02-19  Martin Liska  <mliska@suse.cz>
>>>>
>>>> 	* ipa-cp.c (ignore_edge_p): New function.
>>>> 	(build_toporder_info): Use it.
>>>> 	* ipa-inline.c (ignore_edge_p): New function/
>>>> 	(inline_small_functions): Use it.
>>>> 	* ipa-pure-const.c (ignore_edge_for_nothrow):
>>>> 	Verify opt_for_fn for caller and callee.
>>>> 	(ignore_edge_for_pure_const): Likewise.
>>>> 	* ipa-reference.c (ignore_edge_p): Extend to check
>>>> 	for opt_for_fn.
>>>> 	* ipa-utils.c (searchc): Refactor.
>>>> 	* ipa-utils.h: Fix coding style.
>>>> ---
>>>>  gcc/ipa-cp.c         | 18 +++++++++++++++++-
>>>>  gcc/ipa-inline.c     | 12 +++++++++++-
>>>>  gcc/ipa-pure-const.c | 17 ++++++++++++-----
>>>>  gcc/ipa-reference.c  | 13 ++++++++++---
>>>>  gcc/ipa-utils.c      |  3 +--
>>>>  gcc/ipa-utils.h      |  2 --
>>>>  6 files changed, 51 insertions(+), 14 deletions(-)
>>>>
>>>> diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
>>>> index 442d5c63eff..004b3a34b1c 100644
>>>> --- a/gcc/ipa-cp.c
>>>> +++ b/gcc/ipa-cp.c
>>>> @@ -806,6 +806,21 @@ public:
>>>>    {}
>>>>  };
>>>>  
>>>> +/* Skip edges from and to nodes without ipa_cp enabled.
>>>> +   Ignore not available symbols.  */
>>>> +
>>>> +static bool
>>>> +ignore_edge_p (cgraph_edge *e)
>>>> +{
>>>> +  enum availability avail;
>>>> +  e->callee->function_or_virtual_thunk_symbol (&avail, e->caller);
>>>
>>> Can't the return value of this call be directly fed...
>>>
>>>> +
>>>> +  return (avail <= AVAIL_INTERPOSABLE
>>>> +	  || !opt_for_fn (e->caller->decl, flag_ipa_cp)
>>>> +	  || !opt_for_fn (e->callee->function_symbol ()->decl,
>>>
>>> ...here instead of calling function_symbol... which does not look
>>> through thunks which IMHO you want, even if only for consistency.
>>
>> Yes, I like it.
>>
>> There's a new version of the patch I've just tested.
>>
>> Martin
>>
>>>
>>> Otherwise, it the IPA-CP bits obviously look good,
>>>
>>> Martin
>>>
>>
>
diff mbox series

Patch

From cd7ad04cd1e0ec0d10dc858c22f7e486a3fab183 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Mon, 11 Feb 2019 16:47:06 +0100
Subject: [PATCH] Reduce SCCs in IPA postorder.

gcc/ChangeLog:

2019-02-19  Martin Liska  <mliska@suse.cz>

	* ipa-cp.c (ignore_edge_p): New function.
	(build_toporder_info): Use it.
	* ipa-inline.c (ignore_edge_p): New function/
	(inline_small_functions): Use it.
	* ipa-pure-const.c (ignore_edge_for_nothrow):
	Verify opt_for_fn for caller and callee.
	(ignore_edge_for_pure_const): Likewise.
	* ipa-reference.c (ignore_edge_p): Extend to check
	for opt_for_fn.
	* ipa-utils.c (searchc): Refactor.
	* ipa-utils.h: Fix coding style.
---
 gcc/ipa-cp.c         | 18 +++++++++++++++++-
 gcc/ipa-inline.c     | 12 +++++++++++-
 gcc/ipa-pure-const.c | 17 ++++++++++++-----
 gcc/ipa-reference.c  | 13 ++++++++++---
 gcc/ipa-utils.c      |  3 +--
 gcc/ipa-utils.h      |  2 --
 6 files changed, 51 insertions(+), 14 deletions(-)

diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 442d5c63eff..004b3a34b1c 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -806,6 +806,21 @@  public:
   {}
 };
 
+/* Skip edges from and to nodes without ipa_cp enabled.
+   Ignore not available symbols.  */
+
+static bool
+ignore_edge_p (cgraph_edge *e)
+{
+  enum availability avail;
+  e->callee->function_or_virtual_thunk_symbol (&avail, e->caller);
+
+  return (avail <= AVAIL_INTERPOSABLE
+	  || !opt_for_fn (e->caller->decl, flag_ipa_cp)
+	  || !opt_for_fn (e->callee->function_symbol ()->decl,
+			  flag_ipa_cp));
+}
+
 /* Allocate the arrays in TOPO and topologically sort the nodes into order.  */
 
 static void
@@ -815,7 +830,8 @@  build_toporder_info (struct ipa_topo_info *topo)
   topo->stack = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
 
   gcc_checking_assert (topo->stack_top == 0);
-  topo->nnodes = ipa_reduced_postorder (topo->order, true, NULL);
+  topo->nnodes = ipa_reduced_postorder (topo->order, true,
+					ignore_edge_p);
 }
 
 /* Free information about strongly connected components and the arrays in
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 360c3de3289..d6314bc0e57 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -1751,6 +1751,16 @@  sum_callers (struct cgraph_node *node, void *data)
   return false;
 }
 
+/* We only propagate across edges with non-interposable callee.  */
+
+inline bool
+ignore_edge_p (struct cgraph_edge *e)
+{
+  enum availability avail;
+  e->callee->function_or_virtual_thunk_symbol (&avail, e->caller);
+  return (avail <= AVAIL_INTERPOSABLE);
+}
+
 /* We use greedy algorithm for inlining of small functions:
    All inline candidates are put into prioritized heap ordered in
    increasing badness.
@@ -1778,7 +1788,7 @@  inline_small_functions (void)
      metrics.  */
 
   max_count = profile_count::uninitialized ();
-  ipa_reduced_postorder (order, true, NULL);
+  ipa_reduced_postorder (order, true, ignore_edge_p);
   free (order);
 
   FOR_EACH_DEFINED_FUNCTION (node)
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index bb561d00853..ce69457cbbf 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -1365,8 +1365,11 @@  ignore_edge_for_nothrow (struct cgraph_edge *e)
 							        e->caller);
   if (avail <= AVAIL_INTERPOSABLE || TREE_NOTHROW (n->decl))
     return true;
-  return opt_for_fn (e->callee->decl, flag_non_call_exceptions)
-	 && !e->callee->binds_to_current_def_p (e->caller);
+  return ((opt_for_fn (e->callee->decl, flag_non_call_exceptions)
+	   && !e->callee->binds_to_current_def_p (e->caller))
+	  || !opt_for_fn (e->caller->decl, flag_ipa_pure_const)
+	  || !opt_for_fn (e->callee->function_symbol ()->decl,
+			  flag_ipa_pure_const));
 }
 
 /* Return true if NODE is self recursive function.
@@ -1396,16 +1399,20 @@  cdtor_p (cgraph_node *n, void *)
   return false;
 }
 
-/* We only propagate across edges with non-interposable callee.  */
+/* Skip edges from and to nodes without ipa_pure_const enabled.
+   Ignore not available symbols.  */
 
 static bool
 ignore_edge_for_pure_const (struct cgraph_edge *e)
 {
   enum availability avail;
   e->callee->function_or_virtual_thunk_symbol (&avail, e->caller);
-  return (avail <= AVAIL_INTERPOSABLE);
-}
 
+  return (avail <= AVAIL_INTERPOSABLE
+	  || !opt_for_fn (e->caller->decl, flag_ipa_pure_const)
+	  || !opt_for_fn (e->callee->function_symbol ()->decl,
+			  flag_ipa_pure_const));
+}
 
 /* Produce transitive closure over the callgraph and compute pure/const
    attributes.  */
diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c
index 9ef03c2505b..8074d767781 100644
--- a/gcc/ipa-reference.c
+++ b/gcc/ipa-reference.c
@@ -676,14 +676,21 @@  get_read_write_all_from_node (struct cgraph_node *node,
       }
 }
 
-/* Skip edges from and to nodes without ipa_reference enables.  This leave
-   them out of strongy connected coponents and makes them easyto skip in the
+/* Skip edges from and to nodes without ipa_reference enabled.
+   Ignore not available symbols.  This leave
+   them out of strongly connected components and makes them easy to skip in the
    propagation loop bellow.  */
 
 static bool
 ignore_edge_p (cgraph_edge *e)
 {
-  return (!opt_for_fn (e->caller->decl, flag_ipa_reference)
+  enum availability avail;
+  e->callee->function_or_virtual_thunk_symbol (&avail, e->caller);
+
+  return (avail < AVAIL_INTERPOSABLE
+	  || (avail == AVAIL_INTERPOSABLE
+	      && !(flags_from_decl_or_type (e->callee->decl) & ECF_LEAF))
+	  || !opt_for_fn (e->caller->decl, flag_ipa_reference)
           || !opt_for_fn (e->callee->function_symbol ()->decl,
 			  flag_ipa_reference));
 }
diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c
index 79b250c3943..25c2e2cf789 100644
--- a/gcc/ipa-utils.c
+++ b/gcc/ipa-utils.c
@@ -103,8 +103,7 @@  searchc (struct searchc_env* env, struct cgraph_node *v,
         continue;
 
       if (w->aux
-	  && (avail > AVAIL_INTERPOSABLE
-	      || avail == AVAIL_INTERPOSABLE))
+	  && (avail >= AVAIL_INTERPOSABLE))
 	{
 	  w_info = (struct ipa_dfs_info *) w->aux;
 	  if (w_info->new_node)
diff --git a/gcc/ipa-utils.h b/gcc/ipa-utils.h
index b70e8c57108..c4a9664852a 100644
--- a/gcc/ipa-utils.h
+++ b/gcc/ipa-utils.h
@@ -263,5 +263,3 @@  odr_type_p (const_tree t)
 }
 
 #endif  /* GCC_IPA_UTILS_H  */
-
-
-- 
2.20.1