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 <mli...@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  <mli...@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.
---
 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

Reply via email to