Since match and simplify can add unused statements to the sequence
in some cases, we should remove them before call phiopt_early_allow.
This is needed for 2 future patches. One is to allowing of comparisons,
optionally with a cast and optional with a negative expression.
The other is about supporting a way to handling
cond_removal_in_builtin_zero_pattern in match and also adding a new match
pattern to fix PR 126035 (ctz split back into one).

Bootstrapped and tested on x86_64-linux-gnu.

gcc/ChangeLog:

        * tree-ssa-phiopt.cc (remove_unused_stmts): New function.
        (gimple_simplify_phiopt): Call remove_unused_stmts before
        phiopt_early_allow.

Signed-off-by: Andrew Pinski <[email protected]>
---
 gcc/tree-ssa-phiopt.cc | 48 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
index e12dc7a8b0c..fd173ec01f4 100644
--- a/gcc/tree-ssa-phiopt.cc
+++ b/gcc/tree-ssa-phiopt.cc
@@ -688,6 +688,52 @@ phiopt_early_allow (gimple_seq &seq, gimple_match_op &op)
     }
 }
 
+/* Remove unused statements in SEQ. That are used in OP.
+   This is needed for the way resimplify/match and simplify
+   works as it will place some unneeded statements in the sequence
+   which can get in the way of handling phiopt_early_allow.  */
+
+static void
+remove_unused_stmts (gimple_seq *seq, const gimple_match_op &op)
+{
+  if (*seq == nullptr)
+    return;
+
+  /* Since the sequence of statements are not part of
+     a basic block yet, have to manually go through the operands
+     to mark the uses.  */
+  auto_bitmap uses;
+  for (unsigned i = 0; i < op.num_ops; i++)
+    {
+      tree use = op.ops[i];
+      if (TREE_CODE (use) == SSA_NAME)
+       bitmap_set_bit (uses, SSA_NAME_VERSION (use));
+    }
+  gimple_stmt_iterator gsi = gsi_last (*seq);
+  while (!gsi_end_p (gsi))
+    {
+      gimple *s = *gsi;
+      tree lhs = gimple_get_lhs (s);
+      if (bitmap_bit_p (uses, SSA_NAME_VERSION (lhs)))
+       {
+         for (unsigned i = 0; i < gimple_num_ops (s); i++)
+           {
+             tree use = gimple_op (s, i);
+             if (TREE_CODE (use) == SSA_NAME)
+               bitmap_set_bit (uses, SSA_NAME_VERSION (use));
+           }
+         gsi_prev (&gsi);
+         continue;
+       }
+      gsi_remove (&gsi, true);
+      release_defs (s);
+      ggc_free (s);
+      /* If this was the last statement, start over.  */
+      if (gsi_end_p (gsi))
+       gsi = gsi_last (*seq);
+    }
+}
+
 /* gimple_simplify_phiopt is like gimple_simplify but designed for PHIOPT.
    Return NULL if nothing can be simplified or the resulting simplified value
    with parts pushed if EARLY_P was true. Also rejects non allowed tree code
@@ -729,6 +775,7 @@ gimple_simplify_phiopt (bool early_p, tree type, gimple 
*comp_stmt,
 
   if (op.resimplify (&seq1, follow_all_ssa_edges))
     {
+      remove_unused_stmts (&seq1, op);
       bool allowed = !early_p || phiopt_early_allow (seq1, op);
       tree result = maybe_push_res_to_seq (&op, &seq1);
       if (dump_file && (dump_flags & TDF_FOLDING))
@@ -783,6 +830,7 @@ gimple_simplify_phiopt (bool early_p, tree type, gimple 
*comp_stmt,
 
   if (op1.resimplify (&seq1, follow_all_ssa_edges))
     {
+      remove_unused_stmts (&seq1, op1);
       bool allowed = !early_p || phiopt_early_allow (seq1, op1);
       tree result = maybe_push_res_to_seq (&op1, &seq1);
       if (dump_file && (dump_flags & TDF_FOLDING))
-- 
2.43.0

Reply via email to