This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Clean up SSA propagator <-> VRP interface


VRP does need to do some extra folding during SSA propagation.  ATM
this is done by directly calling routines in VRP.  I am about to
add a similar function to CCP, so this cleans up this interface to
instead use a callback.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2009-09-22  Richard Guenther  <rguenther@suse.de>

	* tree-ssa-propagate.h (ssa_prop_fold_stmt_fn): Declare.
	(substitute_and_fold): Adjust prototype.
	* tree-vrp.c (vrp_evaluate_conditional): Make static.
	(simplify_stmt_using_ranges): Likewise.
	(fold_predicate_in): Move here from tree-ssa-propagate.c.
	(vrp_fold_stmt): New function.
	(vrp_finalize): Pass it to substitute_and_fold.
	* tree-flow.h (vrp_evaluate_conditional): Remove.
	(simplify_stmt_using_ranges): Likewise.
	* tree-ssa-ccp.c (ccp_finalize): Adjust call to substitute_and_fold.
	* tree-ssa-copy.c (fini_copy_prop): Likewise.
	* tree-ssa-propagate.c (struct prop_stats_d): Rename num_pred_folded
	member.
	(fold_predicate_in): Move to tree-vrp.c.
	(substitute_and_fold): Use the callback instead of calling into
	tree-vrp.c functions directly.

Index: gcc/tree-vrp.c
===================================================================
*** gcc/tree-vrp.c.orig	2009-09-21 16:34:50.000000000 +0200
--- gcc/tree-vrp.c	2009-09-21 17:06:21.000000000 +0200
*************** vrp_evaluate_conditional_warnv_with_ops
*** 5678,5684 ****
     based on undefined signed overflow, issue a warning if
     appropriate.  */
  
! tree
  vrp_evaluate_conditional (enum tree_code code, tree op0, tree op1, gimple stmt)
  {
    bool sop;
--- 5678,5684 ----
     based on undefined signed overflow, issue a warning if
     appropriate.  */
  
! static tree
  vrp_evaluate_conditional (enum tree_code code, tree op0, tree op1, gimple stmt)
  {
    bool sop;
*************** simplify_switch_using_ranges (gimple stm
*** 6945,6951 ****
  
  /* Simplify STMT using ranges if possible.  */
  
! bool
  simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
  {
    gimple stmt = gsi_stmt (*gsi);
--- 6945,6951 ----
  
  /* Simplify STMT using ranges if possible.  */
  
! static bool
  simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
  {
    gimple stmt = gsi_stmt (*gsi);
*************** simplify_stmt_using_ranges (gimple_stmt_
*** 6998,7003 ****
--- 6998,7075 ----
    return false;
  }
  
+ /* If the statement pointed by SI has a predicate whose value can be
+    computed using the value range information computed by VRP, compute
+    its value and return true.  Otherwise, return false.  */
+ 
+ static bool
+ fold_predicate_in (gimple_stmt_iterator *si)
+ {
+   bool assignment_p = false;
+   tree val;
+   gimple stmt = gsi_stmt (*si);
+ 
+   if (is_gimple_assign (stmt)
+       && TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_comparison)
+     {
+       assignment_p = true;
+       val = vrp_evaluate_conditional (gimple_assign_rhs_code (stmt),
+ 				      gimple_assign_rhs1 (stmt),
+ 				      gimple_assign_rhs2 (stmt),
+ 				      stmt);
+     }
+   else if (gimple_code (stmt) == GIMPLE_COND)
+     val = vrp_evaluate_conditional (gimple_cond_code (stmt),
+ 				    gimple_cond_lhs (stmt),
+ 				    gimple_cond_rhs (stmt),
+ 				    stmt);
+   else
+     return false;
+ 
+   if (val)
+     {
+       if (assignment_p)
+         val = fold_convert (gimple_expr_type (stmt), val);
+       
+       if (dump_file)
+ 	{
+ 	  fprintf (dump_file, "Folding predicate ");
+ 	  print_gimple_expr (dump_file, stmt, 0, 0);
+ 	  fprintf (dump_file, " to ");
+ 	  print_generic_expr (dump_file, val, 0);
+ 	  fprintf (dump_file, "\n");
+ 	}
+ 
+       if (is_gimple_assign (stmt))
+ 	gimple_assign_set_rhs_from_tree (si, val);
+       else
+ 	{
+ 	  gcc_assert (gimple_code (stmt) == GIMPLE_COND);
+ 	  if (integer_zerop (val))
+ 	    gimple_cond_make_false (stmt);
+ 	  else if (integer_onep (val))
+ 	    gimple_cond_make_true (stmt);
+ 	  else
+ 	    gcc_unreachable ();
+ 	}
+ 
+       return true;
+     }
+ 
+   return false;
+ }
+ 
+ /* Callback for substitute_and_fold folding the stmt at *SI.  */
+ 
+ static bool
+ vrp_fold_stmt (gimple_stmt_iterator *si)
+ {
+   if (fold_predicate_in (si))
+     return true;
+ 
+   return simplify_stmt_using_ranges (si);
+ }
+ 
  /* Stack of dest,src equivalency pairs that need to be restored after
     each attempt to thread a block's incoming edge to an outgoing edge. 
  
*************** vrp_finalize (void)
*** 7187,7193 ****
        single_val_range = NULL;
      }
  
!   substitute_and_fold (single_val_range, true);
  
    if (warn_array_bounds)
        check_all_array_refs ();
--- 7259,7265 ----
        single_val_range = NULL;
      }
  
!   substitute_and_fold (single_val_range, vrp_fold_stmt);
  
    if (warn_array_bounds)
        check_all_array_refs ();
Index: gcc/tree-ssa-ccp.c
===================================================================
*** gcc/tree-ssa-ccp.c.orig	2009-09-21 16:34:50.000000000 +0200
--- gcc/tree-ssa-ccp.c	2009-09-21 16:35:00.000000000 +0200
*************** ccp_finalize (void)
*** 724,730 ****
  
    do_dbg_cnt ();
    /* Perform substitutions based on the known constant values.  */
!   something_changed = substitute_and_fold (const_val, false);
  
    free (const_val);
    const_val = NULL;
--- 724,730 ----
  
    do_dbg_cnt ();
    /* Perform substitutions based on the known constant values.  */
!   something_changed = substitute_and_fold (const_val, NULL);
  
    free (const_val);
    const_val = NULL;
Index: gcc/tree-ssa-propagate.c
===================================================================
*** gcc/tree-ssa-propagate.c.orig	2009-09-21 16:34:50.000000000 +0200
--- gcc/tree-ssa-propagate.c	2009-09-21 17:05:48.000000000 +0200
*************** struct prop_stats_d
*** 856,862 ****
  {
    long num_const_prop;
    long num_copy_prop;
!   long num_pred_folded;
    long num_dce;
  };
  
--- 856,862 ----
  {
    long num_const_prop;
    long num_copy_prop;
!   long num_stmts_folded;
    long num_dce;
  };
  
*************** replace_phi_args_in (gimple phi, prop_va
*** 958,1049 ****
  }
  
  
- /* If the statement pointed by SI has a predicate whose value can be
-    computed using the value range information computed by VRP, compute
-    its value and return true.  Otherwise, return false.  */
- 
- static bool
- fold_predicate_in (gimple_stmt_iterator *si)
- {
-   bool assignment_p = false;
-   tree val;
-   gimple stmt = gsi_stmt (*si);
- 
-   if (is_gimple_assign (stmt)
-       && TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_comparison)
-     {
-       assignment_p = true;
-       val = vrp_evaluate_conditional (gimple_assign_rhs_code (stmt),
- 				      gimple_assign_rhs1 (stmt),
- 				      gimple_assign_rhs2 (stmt),
- 				      stmt);
-     }
-   else if (gimple_code (stmt) == GIMPLE_COND)
-     val = vrp_evaluate_conditional (gimple_cond_code (stmt),
- 				    gimple_cond_lhs (stmt),
- 				    gimple_cond_rhs (stmt),
- 				    stmt);
-   else
-     return false;
- 
- 
-   if (val)
-     {
-       if (assignment_p)
-         val = fold_convert (gimple_expr_type (stmt), val);
-       
-       if (dump_file)
- 	{
- 	  fprintf (dump_file, "Folding predicate ");
- 	  print_gimple_expr (dump_file, stmt, 0, 0);
- 	  fprintf (dump_file, " to ");
- 	  print_generic_expr (dump_file, val, 0);
- 	  fprintf (dump_file, "\n");
- 	}
- 
-       prop_stats.num_pred_folded++;
- 
-       if (is_gimple_assign (stmt))
- 	gimple_assign_set_rhs_from_tree (si, val);
-       else
- 	{
- 	  gcc_assert (gimple_code (stmt) == GIMPLE_COND);
- 	  if (integer_zerop (val))
- 	    gimple_cond_make_false (stmt);
- 	  else if (integer_onep (val))
- 	    gimple_cond_make_true (stmt);
- 	  else
- 	    gcc_unreachable ();
- 	}
- 
-       return true;
-     }
- 
-   return false;
- }
- 
- 
  /* Perform final substitution and folding of propagated values.
  
     PROP_VALUE[I] contains the single value that should be substituted
     at every use of SSA name N_I.  If PROP_VALUE is NULL, no values are
     substituted.
  
!    If USE_RANGES_P is true, statements that contain predicate
!    expressions are evaluated with a call to vrp_evaluate_conditional.
!    This will only give meaningful results when called from tree-vrp.c
!    (the information used by vrp_evaluate_conditional is built by the
!    VRP pass).  
  
     Return TRUE when something changed.  */
  
  bool
! substitute_and_fold (prop_value_t *prop_value, bool use_ranges_p)
  {
    basic_block bb;
    bool something_changed = false;
  
!   if (prop_value == NULL && !use_ranges_p)
      return false;
  
    if (dump_file && (dump_flags & TDF_DETAILS))
--- 958,981 ----
  }
  
  
  /* Perform final substitution and folding of propagated values.
  
     PROP_VALUE[I] contains the single value that should be substituted
     at every use of SSA name N_I.  If PROP_VALUE is NULL, no values are
     substituted.
  
!    If FOLD_FN is non-NULL the function will be invoked on all statements
!    before propagating values for pass specific simplification.
  
     Return TRUE when something changed.  */
  
  bool
! substitute_and_fold (prop_value_t *prop_value, ssa_prop_fold_stmt_fn fold_fn)
  {
    basic_block bb;
    bool something_changed = false;
  
!   if (prop_value == NULL && !fold_fn)
      return false;
  
    if (dump_file && (dump_flags & TDF_DETAILS))
*************** substitute_and_fold (prop_value_t *prop_
*** 1114,1126 ****
  	      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
  	    }
  
! 	  /* If we have range information, see if we can fold
! 	     predicate expressions.  */
! 	  if (use_ranges_p)
  	    {
! 	      did_replace = fold_predicate_in (&i);
! 	      /* fold_predicate_in should not have reallocated STMT.  */
! 	      gcc_assert (gsi_stmt (i) == stmt);
  	    }
  
  	  /* Only replace real uses if we couldn't fold the
--- 1046,1061 ----
  	      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
  	    }
  
! 	  old_stmt = 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++;
  	    }
  
  	  /* Only replace real uses if we couldn't fold the
*************** substitute_and_fold (prop_value_t *prop_
*** 1130,1149 ****
  	    did_replace |= replace_uses_in (stmt, prop_value);
  
  	  /* If we made a replacement, fold the statement.  */
- 
- 	  old_stmt = stmt;
  	  if (did_replace)
  	    fold_stmt (&i);
  
- 	  /* Some statements may be simplified using ranges.  For
- 	     example, division may be replaced by shifts, modulo
- 	     replaced with bitwise and, etc.   Do this after 
- 	     substituting constants, folding, etc so that we're
- 	     presented with a fully propagated, canonicalized
- 	     statement.  */
- 	  if (use_ranges_p)
- 	    did_replace |= simplify_stmt_using_ranges (&i);
- 
  	  /* Now cleanup.  */
  	  if (did_replace)
  	    {
--- 1065,1073 ----
*************** substitute_and_fold (prop_value_t *prop_
*** 1190,1197 ****
  			    prop_stats.num_const_prop);
    statistics_counter_event (cfun, "Copies propagated",
  			    prop_stats.num_copy_prop);
!   statistics_counter_event (cfun, "Predicates folded",
! 			    prop_stats.num_pred_folded);
    statistics_counter_event (cfun, "Statements deleted",
  			    prop_stats.num_dce);
    return something_changed;
--- 1114,1121 ----
  			    prop_stats.num_const_prop);
    statistics_counter_event (cfun, "Copies propagated",
  			    prop_stats.num_copy_prop);
!   statistics_counter_event (cfun, "Statements folded",
! 			    prop_stats.num_stmts_folded);
    statistics_counter_event (cfun, "Statements deleted",
  			    prop_stats.num_dce);
    return something_changed;
Index: gcc/tree-ssa-propagate.h
===================================================================
*** gcc/tree-ssa-propagate.h.orig	2009-09-21 16:34:50.000000000 +0200
--- gcc/tree-ssa-propagate.h	2009-09-21 16:35:00.000000000 +0200
*************** typedef struct value_range_d value_range
*** 110,115 ****
--- 110,116 ----
  /* Call-back functions used by the value propagation engine.  */
  typedef enum ssa_prop_result (*ssa_prop_visit_stmt_fn) (gimple, edge *, tree *);
  typedef enum ssa_prop_result (*ssa_prop_visit_phi_fn) (gimple);
+ typedef bool (*ssa_prop_fold_stmt_fn) (gimple_stmt_iterator *gsi);
  
  
  /* In tree-ssa-propagate.c  */
*************** bool valid_gimple_call_p (tree);
*** 119,124 ****
  void move_ssa_defining_stmt_for_defs (gimple, gimple);
  bool update_call_from_tree (gimple_stmt_iterator *, tree);
  bool stmt_makes_single_store (gimple);
! bool substitute_and_fold (prop_value_t *, bool);
  
  #endif /* _TREE_SSA_PROPAGATE_H  */
--- 120,125 ----
  void move_ssa_defining_stmt_for_defs (gimple, gimple);
  bool update_call_from_tree (gimple_stmt_iterator *, tree);
  bool stmt_makes_single_store (gimple);
! bool substitute_and_fold (prop_value_t *, ssa_prop_fold_stmt_fn);
  
  #endif /* _TREE_SSA_PROPAGATE_H  */
Index: gcc/tree-ssa-copy.c
===================================================================
*** gcc/tree-ssa-copy.c.orig	2009-09-21 16:34:50.000000000 +0200
--- gcc/tree-ssa-copy.c	2009-09-21 16:35:00.000000000 +0200
*************** fini_copy_prop (void)
*** 847,853 ****
  	duplicate_ssa_name_ptr_info (tmp[i].value, SSA_NAME_PTR_INFO (var));
      }
  
!   substitute_and_fold (tmp, false);
  
    free (cached_last_copy_of);
    free (copy_of);
--- 847,853 ----
  	duplicate_ssa_name_ptr_info (tmp[i].value, SSA_NAME_PTR_INFO (var));
      }
  
!   substitute_and_fold (tmp, NULL);
  
    free (cached_last_copy_of);
    free (copy_of);
Index: gcc/tree-flow.h
===================================================================
*** gcc/tree-flow.h.orig	2009-09-15 15:35:16.000000000 +0200
--- gcc/tree-flow.h	2009-09-21 17:04:56.000000000 +0200
*************** tree fold_const_aggregate_ref (tree);
*** 680,689 ****
  bool may_propagate_address_into_dereference (tree, tree);
  
  
- /* In tree-vrp.c  */
- tree vrp_evaluate_conditional (enum tree_code, tree, tree, gimple);
- bool simplify_stmt_using_ranges (gimple_stmt_iterator *);
- 
  /* In tree-ssa-dom.c  */
  extern void dump_dominator_optimization_stats (FILE *);
  extern void debug_dominator_optimization_stats (void);
--- 680,685 ----


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]