This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Clean up SSA propagator <-> VRP interface
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 22 Sep 2009 10:27:14 +0200 (CEST)
- Subject: [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 ----