Commit cc19f80c by Richard Biener Committed by Richard Biener

tree-ssa-forwprop.c (simplify_builtin_call): Do not remove stmt at gsi_p,…

tree-ssa-forwprop.c (simplify_builtin_call): Do not remove stmt at gsi_p, instead replace it with a NOP removed later.

2019-08-16  Richard Biener  <rguenther@suse.de>

	* tree-ssa-forwprop.c (simplify_builtin_call): Do not remove
	stmt at gsi_p, instead replace it with a NOP removed later.
	(pass_forwprop::execute): Fully propagate lattice, DCE stmts
	that became dead because of that.

	fortran/
	* trans-intrinsic.c (gfc_conv_intrinsic_findloc): Initialize
	forward_branch to avoid bogus uninitialized warning.

	* gcc.dg/tree-ssa/forwprop-31.c: Adjust.

From-SVN: r274563
parent 4f4af789
2019-08-16 Richard Biener <rguenther@suse.de>
* tree-ssa-forwprop.c (simplify_builtin_call): Do not remove
stmt at gsi_p, instead replace it with a NOP removed later.
(pass_forwprop::execute): Fully propagate lattice, DCE stmts
that became dead because of that.
2019-08-16 Aldy Hernandez <aldyh@redhat.com> 2019-08-16 Aldy Hernandez <aldyh@redhat.com>
* gimple-ssa-evrp-analyze.c (record_ranges_from_phis): Skip PHIs * gimple-ssa-evrp-analyze.c (record_ranges_from_phis): Skip PHIs
......
2019-08-16 Richard Biener <rguenther@suse.de>
* trans-intrinsic.c (gfc_conv_intrinsic_findloc): Initialize
forward_branch to avoid bogus uninitialized warning.
2019-08-15 Thomas Koenig <tkoenig@gcc.gnu.org> 2019-08-15 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/91443 PR fortran/91443
......
...@@ -5428,7 +5428,7 @@ gfc_conv_intrinsic_findloc (gfc_se *se, gfc_expr *expr) ...@@ -5428,7 +5428,7 @@ gfc_conv_intrinsic_findloc (gfc_se *se, gfc_expr *expr)
tree type; tree type;
tree tmp; tree tmp;
tree found; tree found;
tree forward_branch; tree forward_branch = NULL_TREE;
tree back_branch; tree back_branch;
gfc_loopinfo loop; gfc_loopinfo loop;
gfc_ss *arrayss; gfc_ss *arrayss;
......
2019-08-16 Richard Biener <rguenther@suse.de>
* gcc.dg/tree-ssa/forwprop-31.c: Adjust.
2019-08-16 Martin Liska <mliska@suse.cz> 2019-08-16 Martin Liska <mliska@suse.cz>
PR ipa/91447 PR ipa/91447
......
...@@ -9,7 +9,6 @@ int foo (int x) ...@@ -9,7 +9,6 @@ int foo (int x)
return w - z; /* becomes 0 */ return w - z; /* becomes 0 */
} }
/* The original y = 0 stmt is also retained. */ /* Only z = x + 1 is retained. */
/* { dg-final { scan-tree-dump-times "= 0;" 2 "forwprop1" } } */ /* { dg-final { scan-tree-dump-times " = " 1 "forwprop1" } } */
/* { dg-final { scan-tree-dump-times "-" 0 "forwprop1" } } */ /* { dg-final { scan-tree-dump "return 0;" "forwprop1" } } */
/* { dg-final { scan-tree-dump-times "\\+" 1 "forwprop1" } } */
...@@ -1403,7 +1403,7 @@ simplify_builtin_call (gimple_stmt_iterator *gsi_p, tree callee2) ...@@ -1403,7 +1403,7 @@ simplify_builtin_call (gimple_stmt_iterator *gsi_p, tree callee2)
build_int_cst (TREE_TYPE (len1), src_len)); build_int_cst (TREE_TYPE (len1), src_len));
update_stmt (stmt1); update_stmt (stmt1);
unlink_stmt_vdef (stmt2); unlink_stmt_vdef (stmt2);
gsi_remove (gsi_p, true); gsi_replace (gsi_p, gimple_build_nop (), false);
fwprop_invalidate_lattice (gimple_get_lhs (stmt2)); fwprop_invalidate_lattice (gimple_get_lhs (stmt2));
release_defs (stmt2); release_defs (stmt2);
if (lhs1 && DECL_FUNCTION_CODE (callee1) == BUILT_IN_MEMPCPY) if (lhs1 && DECL_FUNCTION_CODE (callee1) == BUILT_IN_MEMPCPY)
...@@ -2299,13 +2299,14 @@ pass_forwprop::execute (function *fun) ...@@ -2299,13 +2299,14 @@ pass_forwprop::execute (function *fun)
int postorder_num = pre_and_rev_post_order_compute_fn (cfun, NULL, int postorder_num = pre_and_rev_post_order_compute_fn (cfun, NULL,
postorder, false); postorder, false);
auto_vec<gimple *, 4> to_fixup; auto_vec<gimple *, 4> to_fixup;
auto_vec<gimple *, 32> to_remove;
to_purge = BITMAP_ALLOC (NULL); to_purge = BITMAP_ALLOC (NULL);
for (int i = 0; i < postorder_num; ++i) for (int i = 0; i < postorder_num; ++i)
{ {
gimple_stmt_iterator gsi; gimple_stmt_iterator gsi;
basic_block bb = BASIC_BLOCK_FOR_FN (fun, postorder[i]); basic_block bb = BASIC_BLOCK_FOR_FN (fun, postorder[i]);
/* Propagate into PHIs and record degenerate ones in the lattice. */ /* Record degenerate PHIs in the lattice. */
for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si); for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);
gsi_next (&si)) gsi_next (&si))
{ {
...@@ -2321,18 +2322,21 @@ pass_forwprop::execute (function *fun) ...@@ -2321,18 +2322,21 @@ pass_forwprop::execute (function *fun)
FOR_EACH_PHI_ARG (use_p, phi, it, SSA_OP_USE) FOR_EACH_PHI_ARG (use_p, phi, it, SSA_OP_USE)
{ {
tree use = USE_FROM_PTR (use_p); tree use = USE_FROM_PTR (use_p);
tree tem = fwprop_ssa_val (use);
if (! first) if (! first)
first = tem; first = use;
else if (! operand_equal_p (first, tem, 0)) else if (! operand_equal_p (first, use, 0))
{
all_same = false; all_same = false;
if (tem != use break;
&& may_propagate_copy (use, tem)) }
propagate_value (use_p, tem);
} }
if (all_same) if (all_same)
{
if (may_propagate_copy (res, first))
to_remove.safe_push (phi);
fwprop_set_lattice_val (res, first); fwprop_set_lattice_val (res, first);
} }
}
/* Apply forward propagation to all stmts in the basic-block. /* Apply forward propagation to all stmts in the basic-block.
Note we update GSI within the loop as necessary. */ Note we update GSI within the loop as necessary. */
...@@ -2648,33 +2652,61 @@ pass_forwprop::execute (function *fun) ...@@ -2648,33 +2652,61 @@ pass_forwprop::execute (function *fun)
/* Combine stmts with the stmts defining their operands. /* Combine stmts with the stmts defining their operands.
Note we update GSI within the loop as necessary. */ Note we update GSI within the loop as necessary. */
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);) for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{ {
gimple *stmt = gsi_stmt (gsi); gimple *stmt = gsi_stmt (gsi);
gimple *orig_stmt = stmt;
bool changed = false;
bool was_noreturn = (is_gimple_call (stmt)
&& gimple_call_noreturn_p (stmt));
/* Mark stmt as potentially needing revisiting. */ /* Mark stmt as potentially needing revisiting. */
gimple_set_plf (stmt, GF_PLF_1, false); gimple_set_plf (stmt, GF_PLF_1, false);
/* Substitute from our lattice. We need to do so only once. */
bool substituted_p = false;
use_operand_p usep;
ssa_op_iter iter;
FOR_EACH_SSA_USE_OPERAND (usep, stmt, iter, SSA_OP_USE)
{
tree use = USE_FROM_PTR (usep);
tree val = fwprop_ssa_val (use);
if (val && val != use && may_propagate_copy (use, val))
{
propagate_value (usep, val);
substituted_p = true;
}
}
if (substituted_p
&& is_gimple_assign (stmt)
&& gimple_assign_rhs_code (stmt) == ADDR_EXPR)
recompute_tree_invariant_for_addr_expr (gimple_assign_rhs1 (stmt));
bool changed;
do
{
gimple *orig_stmt = stmt = gsi_stmt (gsi);
bool was_noreturn = (is_gimple_call (stmt)
&& gimple_call_noreturn_p (stmt));
changed = false;
if (fold_stmt (&gsi, fwprop_ssa_val)) if (fold_stmt (&gsi, fwprop_ssa_val))
{ {
changed = true; changed = true;
stmt = gsi_stmt (gsi); stmt = gsi_stmt (gsi);
if (maybe_clean_or_replace_eh_stmt (orig_stmt, stmt))
bitmap_set_bit (to_purge, bb->index);
if (!was_noreturn
&& is_gimple_call (stmt) && gimple_call_noreturn_p (stmt))
to_fixup.safe_push (stmt);
/* Cleanup the CFG if we simplified a condition to /* Cleanup the CFG if we simplified a condition to
true or false. */ true or false. */
if (gcond *cond = dyn_cast <gcond *> (stmt)) if (gcond *cond = dyn_cast <gcond *> (stmt))
if (gimple_cond_true_p (cond) if (gimple_cond_true_p (cond)
|| gimple_cond_false_p (cond)) || gimple_cond_false_p (cond))
cfg_changed = true; cfg_changed = true;
}
if (changed || substituted_p)
{
if (maybe_clean_or_replace_eh_stmt (orig_stmt, stmt))
bitmap_set_bit (to_purge, bb->index);
if (!was_noreturn
&& is_gimple_call (stmt) && gimple_call_noreturn_p (stmt))
to_fixup.safe_push (stmt);
update_stmt (stmt); update_stmt (stmt);
substituted_p = false;
} }
switch (gimple_code (stmt)) switch (gimple_code (stmt))
...@@ -2730,8 +2762,8 @@ pass_forwprop::execute (function *fun) ...@@ -2730,8 +2762,8 @@ pass_forwprop::execute (function *fun)
case GIMPLE_COND: case GIMPLE_COND:
{ {
int did_something int did_something = forward_propagate_into_gimple_cond
= forward_propagate_into_gimple_cond (as_a <gcond *> (stmt)); (as_a <gcond *> (stmt));
if (did_something == 2) if (did_something == 2)
cfg_changed = true; cfg_changed = true;
changed = did_something != 0; changed = did_something != 0;
...@@ -2762,9 +2794,12 @@ pass_forwprop::execute (function *fun) ...@@ -2762,9 +2794,12 @@ pass_forwprop::execute (function *fun)
else else
gsi_next (&gsi); gsi_next (&gsi);
} }
else }
{ while (changed);
/* Stmt no longer needs to be revisited. */ /* Stmt no longer needs to be revisited. */
stmt = gsi_stmt (gsi);
gcc_checking_assert (!gimple_plf (stmt, GF_PLF_1));
gimple_set_plf (stmt, GF_PLF_1, true); gimple_set_plf (stmt, GF_PLF_1, true);
/* Fill up the lattice. */ /* Fill up the lattice. */
...@@ -2779,17 +2814,61 @@ pass_forwprop::execute (function *fun) ...@@ -2779,17 +2814,61 @@ pass_forwprop::execute (function *fun)
val = fwprop_ssa_val (rhs); val = fwprop_ssa_val (rhs);
else if (is_gimple_min_invariant (rhs)) else if (is_gimple_min_invariant (rhs))
val = rhs; val = rhs;
/* If we can propagate the lattice-value mark the
stmt for removal. */
if (val != lhs
&& may_propagate_copy (lhs, val))
to_remove.safe_push (stmt);
fwprop_set_lattice_val (lhs, val); fwprop_set_lattice_val (lhs, val);
} }
} }
else if (gimple_nop_p (stmt))
gsi_next (&gsi); to_remove.safe_push (stmt);
} }
/* Substitute in destination PHI arguments. */
edge_iterator ei;
edge e;
FOR_EACH_EDGE (e, ei, bb->succs)
for (gphi_iterator gsi = gsi_start_phis (e->dest);
!gsi_end_p (gsi); gsi_next (&gsi))
{
gphi *phi = gsi.phi ();
use_operand_p use_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e);
tree arg = USE_FROM_PTR (use_p);
if (TREE_CODE (arg) != SSA_NAME
|| virtual_operand_p (arg))
continue;
tree val = fwprop_ssa_val (arg);
if (val != arg
&& may_propagate_copy (arg, val))
propagate_value (use_p, val);
} }
} }
free (postorder); free (postorder);
lattice.release (); lattice.release ();
/* Remove stmts in reverse order to make debug stmt creation possible. */
while (!to_remove.is_empty())
{
gimple *stmt = to_remove.pop ();
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "Removing dead stmt ");
print_gimple_stmt (dump_file, stmt, 0);
fprintf (dump_file, "\n");
}
gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
if (gimple_code (stmt) == GIMPLE_PHI)
remove_phi_node (&gsi, true);
else
{
unlink_stmt_vdef (stmt);
gsi_remove (&gsi, true);
release_defs (stmt);
}
}
/* Fixup stmts that became noreturn calls. This may require splitting /* Fixup stmts that became noreturn calls. This may require splitting
blocks and thus isn't possible during the walk. Do this blocks and thus isn't possible during the walk. Do this
in reverse order so we don't inadvertedly remove a stmt we want to in reverse order so we don't inadvertedly remove a stmt we want to
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment