Improve simple_dce for phis that only used in itself

Message ID 20230511151719.1394582-1-apinski@marvell.com
State Accepted
Headers
Series Improve simple_dce for phis that only used in itself |

Checks

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

Commit Message

Andrew Pinski May 11, 2023, 3:17 p.m. UTC
  While I was looking at differences before and after
r14-569-g21e2ef2dc25de3, I noticed that one phi node was
not being removed.
For an example, while compiling combine.cc, in expand_field_assignment,
we would remove `# pos_51 = PHI <pos_221(31), pos_51(30)>`
but we don't any more since pos_51 has more than zero users
but in this case it is only itself.
This patch improves simple_dce_from_worklist to detect that
case and now we able to remove this phi statement again.

OK? Bootstrapped and tested on x86_64-linux-gnu.

gcc/ChangeLog:

	* tree-ssa-dce.cc (simple_dce_from_worklist): For ssa names
	defined by a phi node with more than one uses, allow for the
	only uses are in that same defining statement.
---
 gcc/tree-ssa-dce.cc | 31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)
  

Comments

Richard Biener May 11, 2023, 4:57 p.m. UTC | #1
> Am 11.05.2023 um 17:18 schrieb Andrew Pinski via Gcc-patches <gcc-patches@gcc.gnu.org>:
> 
> While I was looking at differences before and after
> r14-569-g21e2ef2dc25de3, I noticed that one phi node was
> not being removed.
> For an example, while compiling combine.cc, in expand_field_assignment,
> we would remove `# pos_51 = PHI <pos_221(31), pos_51(30)>`
> but we don't any more since pos_51 has more than zero users
> but in this case it is only itself.
> This patch improves simple_dce_from_worklist to detect that
> case and now we able to remove this phi statement again.
> 
> OK? Bootstrapped and tested on x86_64-linux-gnu.
> 
> gcc/ChangeLog:
> 
>    * tree-ssa-dce.cc (simple_dce_from_worklist): For ssa names
>    defined by a phi node with more than one uses, allow for the
>    only uses are in that same defining statement.
> ---
> gcc/tree-ssa-dce.cc | 31 +++++++++++++++++++++++++++++--
> 1 file changed, 29 insertions(+), 2 deletions(-)
> 
> diff --git a/gcc/tree-ssa-dce.cc b/gcc/tree-ssa-dce.cc
> index 6554b5db03e..045c64a9c02 100644
> --- a/gcc/tree-ssa-dce.cc
> +++ b/gcc/tree-ssa-dce.cc
> @@ -2107,9 +2107,36 @@ simple_dce_from_worklist (bitmap worklist, bitmap need_eh_cleanup)
>       unsigned i = bitmap_clear_first_set_bit (worklist);
> 
>       tree def = ssa_name (i);
> -      /* Removed by somebody else or still in use.  */
> +      /* Removed by somebody else or still in use.
> +     Note use in itself for a phi node is not counted as still in use.  */
>       if (! def || ! has_zero_uses (def))
> -    continue;
> +    {
> +
> +      if (!def)
> +        continue;

Please split the guarding if and handle this separately.  Ok with that change.

Richard 

> +
> +      gimple *def_stmt = SSA_NAME_DEF_STMT (def);
> +      if (gimple_code (def_stmt) != GIMPLE_PHI)
> +        continue;
> +
> +      gimple *use_stmt;
> +      imm_use_iterator use_iter;
> +      bool canremove = true;
> +
> +      FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, def)
> +        {
> +          /* Ignore debug statements. */
> +          if (is_gimple_debug (use_stmt))
> +        continue;
> +          if (use_stmt != def_stmt)
> +        {
> +          canremove = false;
> +          break;
> +        }
> +        }
> +      if (!canremove)
> +        continue;
> +    }
> 
>       gimple *t = SSA_NAME_DEF_STMT (def);
>       if (gimple_has_side_effects (t))
> -- 
> 2.31.1
>
  

Patch

diff --git a/gcc/tree-ssa-dce.cc b/gcc/tree-ssa-dce.cc
index 6554b5db03e..045c64a9c02 100644
--- a/gcc/tree-ssa-dce.cc
+++ b/gcc/tree-ssa-dce.cc
@@ -2107,9 +2107,36 @@  simple_dce_from_worklist (bitmap worklist, bitmap need_eh_cleanup)
       unsigned i = bitmap_clear_first_set_bit (worklist);
 
       tree def = ssa_name (i);
-      /* Removed by somebody else or still in use.  */
+      /* Removed by somebody else or still in use.
+	 Note use in itself for a phi node is not counted as still in use.  */
       if (! def || ! has_zero_uses (def))
-	continue;
+	{
+
+	  if (!def)
+	    continue;
+
+	  gimple *def_stmt = SSA_NAME_DEF_STMT (def);
+	  if (gimple_code (def_stmt) != GIMPLE_PHI)
+	    continue;
+
+	  gimple *use_stmt;
+	  imm_use_iterator use_iter;
+	  bool canremove = true;
+
+	  FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, def)
+	    {
+	      /* Ignore debug statements. */
+	      if (is_gimple_debug (use_stmt))
+		continue;
+	      if (use_stmt != def_stmt)
+		{
+		  canremove = false;
+		  break;
+		}
+	    }
+	  if (!canremove)
+	    continue;
+	}
 
       gimple *t = SSA_NAME_DEF_STMT (def);
       if (gimple_has_side_effects (t))