From d9700bdb8906e5dbba9bd966cf256aa2c4e45eda Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 19 Oct 2016 07:42:19 +0000 Subject: [PATCH] tree-vrp.c (evrp_dom_walker::evrp_dom_walker): Initialize stmts_to_remove. 2016-10-19 Richard Biener * 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 --- gcc/ChangeLog | 12 +++++ gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.dg/tree-ssa/pr61839_2.c | 18 ++++---- gcc/tree-vrp.c | 75 ++++++++++++++++++++++++++----- 4 files changed, 90 insertions(+), 19 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2431b30..ba1d460 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2016-10-19 Richard Biener + + * 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. + 2016-10-18 Aldy Hernandez * Makefile.in (OBJS): Add gimple-ssa-warn-alloca.o. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f80bc50..df73022 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2016-10-19 Richard Biener + + * gcc.dg/tree-ssa/pr61839_2.c: Fix testcase. + 2016-10-18 Kelvin Nilsen * gcc.target/powerpc/vsu/vec-all-ne-0.c: New test. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr61839_2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr61839_2.c index e44dc57..638189e 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr61839_2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr61839_2.c @@ -9,8 +9,8 @@ int foo () int a = -1; volatile unsigned b = 1U; int c = 1; - c = (a + 972195718) / (b ? 1 : 0); - if (c == 972195717) + c = (a + 972195718) / (b ? 2 : 0); + if (c == 486097858) ; else __builtin_abort (); @@ -23,8 +23,8 @@ int bar () int a = -1; volatile unsigned b = 1U; int c = 1; - c = (a + 972195718) % (b ? 1 : 0); - if (c == 972195717) + c = (a + 972195718) % (b ? 2 : 0); + if (c == 1) ; else __builtin_abort (); @@ -38,7 +38,7 @@ int bar2 () volatile unsigned b = 1U; int c = 1; c = (a + 972195716) % (b ? 1 : 2); - if (c == 972195715) + if (c == 0) ; else __builtin_abort (); @@ -47,8 +47,8 @@ int bar2 () /* Dont optimize 972195717 / 0 in function foo. */ -/* { dg-final { scan-tree-dump-times "972195717 / _" 1 "evrp" } } */ +/* { dg-final { scan-tree-dump-times "972195717 / " 1 "evrp" } } */ /* Dont optimize 972195717 % 0 in function bar. */ -/* { dg-final { scan-tree-dump-times "972195717 % _" 1 "evrp" } } */ -/* Optimize in function bar2. */ -/* { dg-final { scan-tree-dump-times "972195715 % _" 0 "evrp" } } */ +/* { dg-final { scan-tree-dump-times "972195717 % " 1 "evrp" } } */ +/* May optimize in function bar2, but EVRP doesn't perform this yet. */ +/* { dg-final { scan-tree-dump-times "972195715 % " 0 "evrp" { xfail *-*-* } } } */ 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 > stack; bitmap need_eh_cleanup; - vec stmts_to_fixup; + auto_vec stmts_to_fixup; + auto_vec 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 (); -- 2.7.4