diff mbox series

[5/9] ipa-sra: Move caller->callee propagation before callee->caller one

Message ID ri61qp4imwz.fsf@suse.cz
State New
Headers show
Series [1/9] ipa-cp: Write transformation summaries of all functions | expand

Commit Message

Martin Jambor Dec. 12, 2022, 4:53 p.m. UTC
Hi,

I'm re-posting patches which I have posted at the end of stage 1 but
which have not passed review yet.

8<--------------------------------------------------------------------

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 individually when I originally posted it and
now bootstrapped and LTO-bootstrapped and tested as part of the whole
series.  OK for master?


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

Comments

Jan Hubicka Dec. 12, 2022, 9:48 p.m. UTC | #1
> 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
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
>
diff mbox series

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