[PATCH] Make EVRP propagate into PHIs and remove dead stmts
Richard Biener
rguenther@suse.de
Tue Oct 18 13:57:00 GMT 2016
On Tue, 18 Oct 2016, Trevor Saunders wrote:
> On Tue, Oct 18, 2016 at 02:34:58PM +0200, Richard Biener wrote:
> >
> > The following patch makes EVRP remove stmts that will become dead
> > after propagation. For this to work we have to propagate into PHIs
> > (sth we missed as well).
> >
> > Bootstrap and regtest running on x86_64-unknown-linux-gnu.
> >
> > Richard.
> >
> > 2016-10-18 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.
> >
> > Index: gcc/tree-vrp.c
> > ===================================================================
> > --- gcc/tree-vrp.c (revision 241302)
> > +++ gcc/tree-vrp.c (working copy)
> > @@ -10643,11 +10643,13 @@ public:
> > : dom_walker (CDI_DOMINATORS), stack (10)
> > {
> > stmts_to_fixup.create (0);
> > + stmts_to_remove.create (0);
> > need_eh_cleanup = BITMAP_ALLOC (NULL);
> > }
> > ~evrp_dom_walker ()
> > {
> > stmts_to_fixup.release ();
> > + stmts_to_remove.release ();
> > BITMAP_FREE (need_eh_cleanup);
> > }
> > virtual edge before_dom_children (basic_block);
> > @@ -10660,6 +10662,7 @@ public:
> > auto_vec<std::pair <const_tree, value_range*> > stack;
> > bitmap need_eh_cleanup;
> > vec<gimple *> stmts_to_fixup;
> > + vec<gimple *> stmts_to_remove;
>
> That might as well be an auto_vec right?
>
> > };
> >
> >
> > @@ -10769,6 +10772,15 @@ evrp_dom_walker::before_dom_children (ba
> > 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;
> > + if ((val = op_with_constant_singleton_value_range (lhs))
> > + && may_propagate_copy (lhs, val))
>
> wouldn't it be clearer to write that as
>
> tree val = op_with_constant_singleton_value_range (lhs);
> if (val && may_propagate_copy (lhs, val))
>
> > + {
> > + stmts_to_remove.safe_push (phi);
> > + continue;
> > + }
> > }
> >
> > edge taken_edge = NULL;
> > @@ -10806,7 +10818,6 @@ evrp_dom_walker::before_dom_children (ba
> > 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 +10835,17 @@ evrp_dom_walker::before_dom_children (ba
> > && 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))
>
> similar.
Fixed. Testing the following.
Richard.
2016-10-18 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.
Index: gcc/tree-vrp.c
===================================================================
--- gcc/tree-vrp.c (revision 241302)
+++ gcc/tree-vrp.c (working copy)
@@ -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 (ba
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 (ba
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 (ba
&& 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 (ba
}
}
}
+
+ /* 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 ();
More information about the Gcc-patches
mailing list