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