[PATCH][1/2] Enable SSA propagator "DCE" for VRP

Richard Biener rguenther@suse.de
Fri Oct 7 09:01:00 GMT 2016


This is the first patch in a series of enabling "DCE" mode in
substitute_and_fold for VRP.  It exchanges lattice substitution
and folding (by substitute_and_fold) with the pass specific
folding routine.  This is because if we do not substitute before
that the pass specific folding might see SSA names that will end
up being released (because they are fully propagated out).  VRP
in particular happily inserts new stmts before the current stmt
referencing such SSA names which later causes problems.

[In the end I would like all those pass specific foldings to go away
in favor of match.pd rules]

Re-bootstrap & regtest running on x86_64-unknown-linux-gnu.

Richard.

2016-10-07  Richard Biener  <rguenther@suse.de>

	* tree-ssa-propagate.c (replace_phi_args_in): Remove no longer
	required hack.
	(substitute_and_fold_dom_walker::before_dom_children):
	Substitute and fold before pass specific folding to avoid
	feeding that with SSA names that will be later released.
	* tree-ssa-ccp.c (get_value_for_expr): Guard for new SSA names
	introduced by folding and visited by evaluate_stmt called during
	ccp_fold_stmt.
	(likely_value): Likewise.
	(evaluate_stmt): Likewise.
	* tree-vrp.c (simplify_truth_ops_using_ranges): Fold modified stmt.
	(simplify_div_or_mod_using_ranges): Likewise.
	(simplify_min_or_max_using_ranges): Likewise.
	(simplify_abs_using_ranges): Likewise.
	(simplify_conversion_using_ranges): Likewise.
	(simplify_float_conversion_using_ranges): Likewise.
	(simplify_stmt_using_ranges): Likewise.

	* gcc.dg/tree-ssa/vrp01.c: Adjust.
	* gcc.dg/tree-ssa/vrp34.c: Likewise.

Index: gcc/testsuite/gcc.dg/tree-ssa/vrp01.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/vrp01.c	(revision 240855)
+++ gcc/testsuite/gcc.dg/tree-ssa/vrp01.c	(working copy)
@@ -25,4 +25,4 @@ foo (int *p, int i)
   return i;
 }
 
-/* { dg-final { scan-tree-dump-times "Folding predicate p_.*to 1" 1 "vrp1" } } */
+/* { dg-final { scan-tree-dump-times "if \\\(" 2 "vrp1" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/vrp34.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/vrp34.c	(revision 240855)
+++ gcc/testsuite/gcc.dg/tree-ssa/vrp34.c	(working copy)
@@ -15,5 +15,5 @@ foo (int a)
     }
 }
 
-/* { dg-final { scan-tree-dump "Folding predicate a_. > 2 to 1" "vrp1" } } */
-/* { dg-final { scan-tree-dump "Folding predicate a_. <= 5 to 1" "vrp1" } } */
+/* Both ifs should be optimized.  */
+/* { dg-final { scan-tree-dump-times "if \\\(" 0 "vrp1" } } */
Index: gcc/tree-ssa-ccp.c
===================================================================
--- gcc/tree-ssa-ccp.c	(revision 240855)
+++ gcc/tree-ssa-ccp.c	(working copy)
@@ -591,7 +591,15 @@ get_value_for_expr (tree expr, bool for_
 
   if (TREE_CODE (expr) == SSA_NAME)
     {
-      val = *get_value (expr);
+      ccp_prop_value_t *val_ = get_value (expr);
+      if (val_)
+	val = *val_;
+      else
+	{
+	  val.lattice_val = VARYING;
+	  val.value = NULL_TREE;
+	  val.mask = -1;
+	}
       if (for_bits_p
 	  && val.lattice_val == CONSTANT
 	  && TREE_CODE (val.value) == ADDR_EXPR)
@@ -673,12 +681,12 @@ likely_value (gimple *stmt)
     {
       ccp_prop_value_t *val = get_value (use);
 
-      if (val->lattice_val == UNDEFINED)
+      if (val && val->lattice_val == UNDEFINED)
 	has_undefined_operand = true;
       else
 	all_undefined_operands = false;
 
-      if (val->lattice_val == CONSTANT)
+      if (val && val->lattice_val == CONSTANT)
 	has_constant_operand = true;
 
       if (SSA_NAME_IS_DEFAULT_DEF (use)
@@ -1739,11 +1747,11 @@ evaluate_stmt (gimple *stmt)
       simplified = ccp_fold (stmt);
       if (simplified && TREE_CODE (simplified) == SSA_NAME)
 	{
-	  val = *get_value (simplified);
-	  if (val.lattice_val != VARYING)
+	  ccp_prop_value_t *val = get_value (simplified);
+	  if (val && val->lattice_val != VARYING)
 	    {
 	      fold_undefer_overflow_warnings (true, stmt, 0);
-	      return val;
+	      return *val;
 	    }
 	}
       is_constant = simplified && is_gimple_min_invariant (simplified);
Index: gcc/tree-ssa-propagate.c
===================================================================
--- gcc/tree-ssa-propagate.c	(revision 240855)
+++ gcc/tree-ssa-propagate.c	(working copy)
@@ -914,7 +914,6 @@ replace_phi_args_in (gphi *phi, ssa_prop
       print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
     }
 
-  basic_block bb = gimple_bb (phi);
   for (i = 0; i < gimple_phi_num_args (phi); i++)
     {
       tree arg = gimple_phi_arg_def (phi, i);
@@ -927,19 +926,6 @@ replace_phi_args_in (gphi *phi, ssa_prop
 	    {
 	      edge e = gimple_phi_arg_edge (phi, i);
 
-	      /* Avoid propagating constants into loop latch edge
-	         PHI arguments as this makes coalescing the copy
-		 across this edge impossible.  If the argument is
-		 defined by an assert - otherwise the stmt will
-		 get removed without replacing its uses.  */
-	      if (TREE_CODE (val) != SSA_NAME
-		  && bb->loop_father->header == bb
-		  && dominated_by_p (CDI_DOMINATORS, e->src, bb)
-		  && is_gimple_assign (SSA_NAME_DEF_STMT (arg))
-		  && (gimple_assign_rhs_code (SSA_NAME_DEF_STMT (arg))
-		      == ASSERT_EXPR))
-		continue;
-
 	      if (TREE_CODE (val) != SSA_NAME)
 		prop_stats.num_const_prop++;
 	      else
@@ -1090,18 +1076,6 @@ substitute_and_fold_dom_walker::before_d
       bool was_noreturn = (is_gimple_call (stmt)
 			   && gimple_call_noreturn_p (stmt));
 
-      /* Some statements may be simplified using propagator
-	 specific information.  Do this before propagating
-	 into the stmt to not disturb pass specific information.  */
-      if (fold_fn
-	  && (*fold_fn)(&i))
-	{
-	  did_replace = true;
-	  prop_stats.num_stmts_folded++;
-	  stmt = gsi_stmt (i);
-	  update_stmt (stmt);
-	}
-
       /* Replace real uses in the statement.  */
       did_replace |= replace_uses_in (stmt, get_value_fn);
 
@@ -1110,6 +1084,22 @@ substitute_and_fold_dom_walker::before_d
 	{
 	  fold_stmt (&i, follow_single_use_edges);
 	  stmt = gsi_stmt (i);
+	  gimple_set_modified (stmt, true);
+	}
+
+      /* Some statements may be simplified using propagator
+	 specific information.  Do this before propagating
+	 into the stmt to not disturb pass specific information.  */
+      if (fold_fn)
+	{
+	  update_stmt_if_modified (stmt);
+	  if ((*fold_fn)(&i))
+	    {
+	      did_replace = true;
+	      prop_stats.num_stmts_folded++;
+	      stmt = gsi_stmt (i);
+	      gimple_set_modified (stmt, true);
+	    }
 	}
 
       /* If this is a control statement the propagator left edges
@@ -1127,6 +1117,7 @@ substitute_and_fold_dom_walker::before_d
 		gimple_cond_make_true (as_a <gcond *> (stmt));
 	      else
 		gimple_cond_make_false (as_a <gcond *> (stmt));
+	      gimple_set_modified (stmt, true);
 	      did_replace = true;
 	    }
 	}
@@ -1155,7 +1146,7 @@ substitute_and_fold_dom_walker::before_d
 	    }
 
 	  /* Determine what needs to be done to update the SSA form.  */
-	  update_stmt (stmt);
+	  update_stmt_if_modified (stmt);
 	  if (!is_gimple_debug (stmt))
 	    something_changed = true;
 	}
Index: gcc/tree-vrp.c
===================================================================
--- gcc/tree-vrp.c	(revision 240855)
+++ gcc/tree-vrp.c	(working copy)
@@ -9055,6 +9055,7 @@ simplify_truth_ops_using_ranges (gimple_
   else
     gimple_assign_set_rhs_with_ops (gsi, BIT_XOR_EXPR, op0, op1);
   update_stmt (gsi_stmt (*gsi));
+  fold_stmt (gsi, follow_single_use_edges);
 
   return true;
 }
@@ -9156,6 +9157,7 @@ simplify_div_or_mod_using_ranges (gimple
 	}
 
       update_stmt (stmt);
+      fold_stmt (gsi, follow_single_use_edges);
       return true;
     }
 
@@ -9204,6 +9206,7 @@ simplify_min_or_max_using_ranges (gimple
       gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
       gimple_assign_set_rhs_from_tree (&gsi, res);
       update_stmt (stmt);
+      fold_stmt (&gsi, follow_single_use_edges);
       return true;
     }
 
@@ -9256,6 +9259,8 @@ simplify_abs_using_ranges (gimple *stmt)
 	  else
 	    gimple_assign_set_rhs_code (stmt, NEGATE_EXPR);
 	  update_stmt (stmt);
+	  gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
+	  fold_stmt (&gsi, follow_single_use_edges);
 	  return true;
 	}
     }
@@ -9906,7 +9911,8 @@ simplify_conversion_using_ranges (gimple
     return false;
 
   gimple_assign_set_rhs1 (stmt, innerop);
-  update_stmt (stmt);
+  gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
+  fold_stmt (&gsi, follow_single_use_edges);
   return true;
 }
 
@@ -9971,7 +9977,7 @@ simplify_float_conversion_using_ranges (
   conv = gimple_build_assign (tem, NOP_EXPR, rhs1);
   gsi_insert_before (gsi, conv, GSI_SAME_STMT);
   gimple_assign_set_rhs1 (stmt, tem);
-  update_stmt (stmt);
+  fold_stmt (gsi, follow_single_use_edges);
 
   return true;
 }
@@ -10176,6 +10182,7 @@ simplify_stmt_using_ranges (gimple_stmt_
 					      new_rhs1,
 					      new_rhs2);
 	      update_stmt (gsi_stmt (*gsi));
+	      fold_stmt (gsi, follow_single_use_edges);
 	      return true;
 	    }
 	}



More information about the Gcc-patches mailing list