[PATCH] Make EVRP propagate into PHIs and remove dead stmts

Richard Biener rguenther@suse.de
Tue Oct 18 12:35:00 GMT 2016


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;
 };
 
 
@@ -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))
+	{
+	  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))
+		{
+		  stmts_to_remove.safe_push (stmt);
+		  continue;
+		}
 	    }
 	  else
 	    set_defs_to_varying (stmt);
@@ -10860,6 +10882,24 @@ 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;
+	  if (tree val = op_with_constant_singleton_value_range (arg))
+	    propagate_value (use_p, val);
+	}
+    }
+ 
   bb->flags |= BB_VISITED;
 
   return taken_edge;
@@ -10941,6 +10981,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 +11022,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