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