Hi,

this patch does not do any functional changes, it merely moves
top-down propagation in the IPA-SRA WPA phase before bottom-up one.
This also meant moving some preliminary checks from the latter to the
former - where they need to be in their own loop over each SCC because
the subsequent one looks at callers.

Currently the propagations are independent (top-down is used for
return value rermoval, bottom-up for parameter removal and splitting)
but subsequent patches will introduce flags about parameters which
should be propagated from callers first and used in splitting.  I
separated this change to test ir independently and make those
subsequent patches cleaner.

While at it, I also replaced couple of FOR_EACH_VEC_ELT macros with
C++11 style iteration.

Bootstrapped and tested on x86_64-linux.  OK for master?

Thanks,

Martin


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

Reply via email to