tree-vrp.c (evrp_dom_walker::evrp_dom_walker): Initialize stmts_to_remove.
authorRichard Biener <rguenther@suse.de>
Wed, 19 Oct 2016 07:42:19 +0000 (07:42 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 19 Oct 2016 07:42:19 +0000 (07:42 +0000)
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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr61839_2.c
gcc/tree-vrp.c

index 2431b30627e3f4351894dd6a80553322602fa4f0..ba1d46060e0fa1e5619809d0ba198c2dfb8f2a10 100644 (file)
@@ -1,3 +1,15 @@
+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.
+
 2016-10-18  Aldy Hernandez  <aldyh@redhat.com>
 
        * Makefile.in (OBJS): Add gimple-ssa-warn-alloca.o.
index f80bc500a745b055425b888e73d6660f48b6291a..df7302249832a33a1d338ab5c53118a1afc32b03 100644 (file)
@@ -1,3 +1,7 @@
+2016-10-19  Richard Biener  <rguenther@suse.de>
+
+       * gcc.dg/tree-ssa/pr61839_2.c: Fix testcase.
+
 2016-10-18  Kelvin Nilsen  <kelvin@gcc.gnu.org>
 
        * gcc.target/powerpc/vsu/vec-all-ne-0.c: New test.
index e44dc576c5143507d0ce134e1b44b275965844e1..638189e66e569c6d2786ed8b3e1c859d9b185c72 100644 (file)
@@ -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 *-*-* } } } */
index 6a7adaeff83edf32b310124feaea767cab486111..c1750d03840f1eb3e357a18b42c1619fc8f8304d 100644 (file)
@@ -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 ();