> gcc/ChangeLog:
> 
> 2022-11-11  Martin Jambor  <mjam...@suse.cz>
> 
>       * ipa-sra.c (ipa_sra_analysis): Move top-down analysis before
>       bottom-up analysis.  Replace FOR_EACH_VEC_ELT with C++11 iteration.
> 
> gcc/testsuite/ChangeLog:
> 
> 2021-12-14  Martin Jambor  <mjam...@suse.cz>
> 
>       * gcc.dg/ipa/ipa-sra-25.c: New test
OK,
Thanks!
Honza
> ---
>  gcc/ipa-sra.cc                        | 145 +++++++++++++-------------
>  gcc/testsuite/gcc.dg/ipa/ipa-sra-25.c |  17 +++
>  2 files changed, 89 insertions(+), 73 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/ipa/ipa-sra-25.c
> 
> diff --git a/gcc/ipa-sra.cc b/gcc/ipa-sra.cc
> index e8a4cd47429..fa5a01ec07c 100644
> --- a/gcc/ipa-sra.cc
> +++ b/gcc/ipa-sra.cc
> @@ -3925,95 +3925,28 @@ ipa_sra_analysis (void)
>    auto_vec <cgraph_node *, 16> stack;
>    int node_scc_count = ipa_reduced_postorder (order, true, NULL);
>  
> -  /* One sweep from callees to callers for parameter removal and splitting.  
> */
> -  for (int i = 0; i < node_scc_count; i++)
> +  /* One sweep from callers to callees for return value removal.  */
> +  for (int i = node_scc_count - 1; i >= 0 ; i--)
>      {
>        cgraph_node *scc_rep = order[i];
>        vec<cgraph_node *> cycle_nodes = ipa_get_nodes_in_cycle (scc_rep);
> -      unsigned j;
>  
> -      /* Preliminary IPA function level checks and first step of parameter
> -      removal.  */
> -      cgraph_node *v;
> -      FOR_EACH_VEC_ELT (cycle_nodes, j, v)
> +      /* Preliminary IPA function level checks.  */
> +      for (cgraph_node *v : cycle_nodes)
>       {
>         isra_func_summary *ifs = func_sums->get (v);
>         if (!ifs || !ifs->m_candidate)
>           continue;
>         if (!ipa_sra_ipa_function_checks (v)
>             || check_all_callers_for_issues (v))
> -         {
> -           ifs->zap ();
> -           continue;
> -         }
> -       if (disable_unavailable_parameters (v, ifs))
> -         continue;
> -       for (cgraph_edge *cs = v->indirect_calls; cs; cs = cs->next_callee)
> -         process_edge_to_unknown_caller (cs);
> -       for (cgraph_edge *cs = v->callees; cs; cs = cs->next_callee)
> -         if (!ipa_edge_within_scc (cs))
> -           param_removal_cross_scc_edge (cs);
> +         ifs->zap ();
>       }
>  
> -      /* Look at edges within the current SCC and propagate used-ness across
> -      them, pushing onto the stack all notes which might need to be
> -      revisited.  */
> -      FOR_EACH_VEC_ELT (cycle_nodes, j, v)
> -     v->call_for_symbol_thunks_and_aliases (propagate_used_to_scc_callers,
> -                                            &stack, true);
> -
> -      /* Keep revisiting and pushing until nothing changes.  */
> -      while (!stack.is_empty ())
> -     {
> -       cgraph_node *v = stack.pop ();
> -       isra_func_summary *ifs = func_sums->get (v);
> -       gcc_checking_assert (ifs && ifs->m_queued);
> -       ifs->m_queued = false;
> -
> -       v->call_for_symbol_thunks_and_aliases (propagate_used_to_scc_callers,
> -                                              &stack, true);
> -     }
> -
> -      /* Parameter splitting.  */
> -      bool repeat_scc_access_propagation;
> -      do
> -     {
> -       repeat_scc_access_propagation = false;
> -       FOR_EACH_VEC_ELT (cycle_nodes, j, v)
> -         {
> -           isra_func_summary *ifs = func_sums->get (v);
> -           if (!ifs
> -               || !ifs->m_candidate
> -               || vec_safe_is_empty (ifs->m_parameters))
> -             continue;
> -           for (cgraph_edge *cs = v->callees; cs; cs = cs->next_callee)
> -             if (param_splitting_across_edge (cs))
> -               repeat_scc_access_propagation = true;
> -         }
> -     }
> -      while (repeat_scc_access_propagation);
> -
> -      if (flag_checking)
> -     FOR_EACH_VEC_ELT (cycle_nodes, j, v)
> -       verify_splitting_accesses (v, true);
> -
> -      cycle_nodes.release ();
> -    }
> -
> -  /* One sweep from caller to callees for result removal.  */
> -  for (int i = node_scc_count - 1; i >= 0 ; i--)
> -    {
> -      cgraph_node *scc_rep = order[i];
> -      vec<cgraph_node *> cycle_nodes = ipa_get_nodes_in_cycle (scc_rep);
> -      unsigned j;
> -
> -      cgraph_node *v;
> -      FOR_EACH_VEC_ELT (cycle_nodes, j, v)
> +      for (cgraph_node *v : cycle_nodes)
>       {
>         isra_func_summary *ifs = func_sums->get (v);
>         if (!ifs || !ifs->m_candidate)
>           continue;
> -
>         bool return_needed
>           = (ifs->m_returns_value
>              && (!dbg_cnt (ipa_sra_retvalues)
> @@ -4048,6 +3981,72 @@ ipa_sra_analysis (void)
>        cycle_nodes.release ();
>      }
>  
> +  /* One sweep from callees to callers for parameter removal and splitting.  
> */
> +  for (int i = 0; i < node_scc_count; i++)
> +    {
> +      cgraph_node *scc_rep = order[i];
> +      vec<cgraph_node *> cycle_nodes = ipa_get_nodes_in_cycle (scc_rep);
> +
> +      /* First step of parameter removal.  */
> +      for (cgraph_node *v : cycle_nodes)
> +     {
> +       isra_func_summary *ifs = func_sums->get (v);
> +       if (!ifs || !ifs->m_candidate)
> +         continue;
> +       if (disable_unavailable_parameters (v, ifs))
> +         continue;
> +       for (cgraph_edge *cs = v->indirect_calls; cs; cs = cs->next_callee)
> +         process_edge_to_unknown_caller (cs);
> +       for (cgraph_edge *cs = v->callees; cs; cs = cs->next_callee)
> +         if (!ipa_edge_within_scc (cs))
> +           param_removal_cross_scc_edge (cs);
> +     }
> +
> +      /* Look at edges within the current SCC and propagate used-ness across
> +      them, pushing onto the stack all notes which might need to be
> +      revisited.  */
> +      for (cgraph_node *v : cycle_nodes)
> +     v->call_for_symbol_thunks_and_aliases (propagate_used_to_scc_callers,
> +                                            &stack, true);
> +
> +      /* Keep revisiting and pushing until nothing changes.  */
> +      while (!stack.is_empty ())
> +     {
> +       cgraph_node *v = stack.pop ();
> +       isra_func_summary *ifs = func_sums->get (v);
> +       gcc_checking_assert (ifs && ifs->m_queued);
> +       ifs->m_queued = false;
> +
> +       v->call_for_symbol_thunks_and_aliases (propagate_used_to_scc_callers,
> +                                              &stack, true);
> +     }
> +
> +      /* Parameter splitting.  */
> +      bool repeat_scc_access_propagation;
> +      do
> +     {
> +       repeat_scc_access_propagation = false;
> +       for (cgraph_node *v : cycle_nodes)
> +         {
> +           isra_func_summary *ifs = func_sums->get (v);
> +           if (!ifs
> +               || !ifs->m_candidate
> +               || vec_safe_is_empty (ifs->m_parameters))
> +             continue;
> +           for (cgraph_edge *cs = v->callees; cs; cs = cs->next_callee)
> +             if (param_splitting_across_edge (cs))
> +               repeat_scc_access_propagation = true;
> +         }
> +     }
> +      while (repeat_scc_access_propagation);
> +
> +      if (flag_checking)
> +     for (cgraph_node *v : cycle_nodes)
> +       verify_splitting_accesses (v, true);
> +
> +      cycle_nodes.release ();
> +    }
> +
>    ipa_free_postorder_info ();
>    free (order);
>  
> diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-25.c 
> b/gcc/testsuite/gcc.dg/ipa/ipa-sra-25.c
> new file mode 100644
> index 00000000000..46fc1a54571
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-25.c
> @@ -0,0 +1,17 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -Wmaybe-uninitialized -Werror"  } */
> +
> +int cbos();
> +static int aos() {
> +  cbos();
> +  return 0;
> +}
> +int cbos_ptr;
> +long cbos_psize;
> +int cbos() {
> +  if (cbos_ptr)
> +    return aos();
> +  if (cbos_psize)
> +    return 1;
> +  return 0;
> +}
> -- 
> 2.38.1
> 

Reply via email to