aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vrp.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2016-10-19 07:42:19 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2016-10-19 07:42:19 +0000
commitd9700bdb8906e5dbba9bd966cf256aa2c4e45eda (patch)
tree2575a2e9a856579290cdf5913772d994ee0b05ae /gcc/tree-vrp.c
parentae4206cb7cf8a4e261b339bdb2032fc3a109aa40 (diff)
downloadgcc-d9700bdb8906e5dbba9bd966cf256aa2c4e45eda.zip
gcc-d9700bdb8906e5dbba9bd966cf256aa2c4e45eda.tar.gz
gcc-d9700bdb8906e5dbba9bd966cf256aa2c4e45eda.tar.bz2
tree-vrp.c (evrp_dom_walker::evrp_dom_walker): Initialize stmts_to_remove.
2016-10-19 Richard Biener <rguenther@suse.de> * tree-vrp.c (evrp_dom_walker::evrp_dom_walker): Initialize stmts_to_remove. (evrp_dom_walker::~evrp_dom_walker): Free it. (evrp_dom_walker::stmts_to_remove): Add. (evrp_dom_walker::before_dom_children): Mark PHIs and stmts whose output we fully propagate for removal. Propagate into BB destination PHI arguments. (execute_early_vrp): Remove queued stmts. Dump value ranges before stmt removal. * gcc.dg/tree-ssa/pr61839_2.c: Fix testcase. From-SVN: r241327
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r--gcc/tree-vrp.c75
1 files changed, 65 insertions, 10 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 6a7adae..c1750d0 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -10642,12 +10642,10 @@ public:
evrp_dom_walker ()
: dom_walker (CDI_DOMINATORS), stack (10)
{
- stmts_to_fixup.create (0);
need_eh_cleanup = BITMAP_ALLOC (NULL);
}
~evrp_dom_walker ()
{
- stmts_to_fixup.release ();
BITMAP_FREE (need_eh_cleanup);
}
virtual edge before_dom_children (basic_block);
@@ -10659,7 +10657,8 @@ public:
/* Cond_stack holds the old VR. */
auto_vec<std::pair <const_tree, value_range*> > stack;
bitmap need_eh_cleanup;
- vec<gimple *> stmts_to_fixup;
+ auto_vec<gimple *> stmts_to_fixup;
+ auto_vec<gimple *> stmts_to_remove;
};
@@ -10769,6 +10768,11 @@ evrp_dom_walker::before_dom_children (basic_block bb)
else
set_value_range_to_varying (&vr_result);
update_value_range (lhs, &vr_result);
+
+ /* Mark PHIs whose lhs we fully propagate for removal. */
+ tree val = op_with_constant_singleton_value_range (lhs);
+ if (val && may_propagate_copy (lhs, val))
+ stmts_to_remove.safe_push (phi);
}
edge taken_edge = NULL;
@@ -10806,7 +10810,6 @@ evrp_dom_walker::before_dom_children (basic_block bb)
update_value_range (output, &vr);
vr = *get_value_range (output);
-
/* Set the SSA with the value range. */
if (INTEGRAL_TYPE_P (TREE_TYPE (output)))
{
@@ -10824,6 +10827,17 @@ evrp_dom_walker::before_dom_children (basic_block bb)
&& range_includes_zero_p (vr.min,
vr.max) == 1)))
set_ptr_nonnull (output);
+
+ /* Mark stmts whose output we fully propagate for removal. */
+ tree val;
+ if ((val = op_with_constant_singleton_value_range (output))
+ && may_propagate_copy (output, val)
+ && !stmt_could_throw_p (stmt)
+ && !gimple_has_side_effects (stmt))
+ {
+ stmts_to_remove.safe_push (stmt);
+ continue;
+ }
}
else
set_defs_to_varying (stmt);
@@ -10860,6 +10874,25 @@ evrp_dom_walker::before_dom_children (basic_block bb)
}
}
}
+
+ /* Visit BB successor PHI nodes and replace PHI args. */
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ {
+ for (gphi_iterator gpi = gsi_start_phis (e->dest);
+ !gsi_end_p (gpi); gsi_next (&gpi))
+ {
+ gphi *phi = gpi.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 = op_with_constant_singleton_value_range (arg);
+ if (val && may_propagate_copy (arg, val))
+ propagate_value (use_p, val);
+ }
+ }
+
bb->flags |= BB_VISITED;
return taken_edge;
@@ -10941,6 +10974,34 @@ execute_early_vrp ()
evrp_dom_walker walker;
walker.walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
+ if (dump_file)
+ {
+ fprintf (dump_file, "\nValue ranges after Early VRP:\n\n");
+ dump_all_value_ranges (dump_file);
+ fprintf (dump_file, "\n");
+ }
+
+ /* Remove stmts in reverse order to make debug stmt creation possible. */
+ while (! walker.stmts_to_remove.is_empty ())
+ {
+ gimple *stmt = walker.stmts_to_remove.pop ();
+ if (dump_file && dump_flags & TDF_DETAILS)
+ {
+ fprintf (dump_file, "Removing dead stmt ");
+ print_gimple_stmt (dump_file, stmt, 0, 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);
+ }
+ }
+
if (!bitmap_empty_p (walker.need_eh_cleanup))
gimple_purge_all_dead_eh_edges (walker.need_eh_cleanup);
@@ -10954,12 +11015,6 @@ execute_early_vrp ()
fixup_noreturn_call (stmt);
}
- if (dump_file)
- {
- fprintf (dump_file, "\nValue ranges after Early VRP:\n\n");
- dump_all_value_ranges (dump_file);
- fprintf (dump_file, "\n");
- }
vrp_free_lattice ();
scev_finalize ();
loop_optimizer_finalize ();