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

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.

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
> 

Reply via email to