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 <rguent...@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 <rguent...@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 ();