diff mbox

Make EVRP propagate into PHIs and remove dead stmts

Message ID alpine.LSU.2.11.1610181432210.2258@t29.fhfr.qr
State New
Headers show

Commit Message

Richard Biener Oct. 18, 2016, 12:34 p.m. UTC
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.

Comments

Trevor Saunders Oct. 18, 2016, 1:35 p.m. UTC | #1
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.

Thanks!

Trev
diff mbox

Patch

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 ();