[08/12] ipa-sra: Move caller->callee propagation before callee->caller one

Message ID ri6leohkkq8.fsf@suse.cz
State Accepted
Headers
Series [01/12] ipa: IPA-SRA split detection simplification |

Checks

Context Check Description
snail/gcc-patch-check success Github commit url

Commit Message

Martin Jambor Nov. 12, 2022, 1:46 a.m. UTC
  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  <mjambor@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  <mjambor@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
  

Patch

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;
+}