Commit ff7ffb8f by Richard Guenther Committed by Richard Biener

tree-ssa-propagate.h (ssa_prop_fold_stmt_fn): Declare.

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.

From-SVN: r151968
parent 8b659ecb
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.
2009-09-22 Jakub Jelinek <jakub@redhat.com> 2009-09-22 Jakub Jelinek <jakub@redhat.com>
* dwarf2out.c (address_of_int_loc_descriptor): Avoid signed/unsigned * dwarf2out.c (address_of_int_loc_descriptor): Avoid signed/unsigned
......
...@@ -680,10 +680,6 @@ tree fold_const_aggregate_ref (tree); ...@@ -680,10 +680,6 @@ tree fold_const_aggregate_ref (tree);
bool may_propagate_address_into_dereference (tree, tree); 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 */ /* In tree-ssa-dom.c */
extern void dump_dominator_optimization_stats (FILE *); extern void dump_dominator_optimization_stats (FILE *);
extern void debug_dominator_optimization_stats (void); extern void debug_dominator_optimization_stats (void);
......
...@@ -724,7 +724,7 @@ ccp_finalize (void) ...@@ -724,7 +724,7 @@ ccp_finalize (void)
do_dbg_cnt (); do_dbg_cnt ();
/* Perform substitutions based on the known constant values. */ /* Perform substitutions based on the known constant values. */
something_changed = substitute_and_fold (const_val, false); something_changed = substitute_and_fold (const_val, NULL);
free (const_val); free (const_val);
const_val = NULL; const_val = NULL;
......
...@@ -847,7 +847,7 @@ fini_copy_prop (void) ...@@ -847,7 +847,7 @@ fini_copy_prop (void)
duplicate_ssa_name_ptr_info (tmp[i].value, SSA_NAME_PTR_INFO (var)); duplicate_ssa_name_ptr_info (tmp[i].value, SSA_NAME_PTR_INFO (var));
} }
substitute_and_fold (tmp, false); substitute_and_fold (tmp, NULL);
free (cached_last_copy_of); free (cached_last_copy_of);
free (copy_of); free (copy_of);
......
...@@ -856,7 +856,7 @@ struct prop_stats_d ...@@ -856,7 +856,7 @@ struct prop_stats_d
{ {
long num_const_prop; long num_const_prop;
long num_copy_prop; long num_copy_prop;
long num_pred_folded; long num_stmts_folded;
long num_dce; long num_dce;
}; };
...@@ -958,92 +958,24 @@ replace_phi_args_in (gimple phi, prop_value_t *prop_value) ...@@ -958,92 +958,24 @@ replace_phi_args_in (gimple phi, prop_value_t *prop_value)
} }
/* 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. /* Perform final substitution and folding of propagated values.
PROP_VALUE[I] contains the single value that should be substituted 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 at every use of SSA name N_I. If PROP_VALUE is NULL, no values are
substituted. substituted.
If USE_RANGES_P is true, statements that contain predicate If FOLD_FN is non-NULL the function will be invoked on all statements
expressions are evaluated with a call to vrp_evaluate_conditional. before propagating values for pass specific simplification.
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. */ Return TRUE when something changed. */
bool bool
substitute_and_fold (prop_value_t *prop_value, bool use_ranges_p) substitute_and_fold (prop_value_t *prop_value, ssa_prop_fold_stmt_fn fold_fn)
{ {
basic_block bb; basic_block bb;
bool something_changed = false; bool something_changed = false;
if (prop_value == NULL && !use_ranges_p) if (prop_value == NULL && !fold_fn)
return false; return false;
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
...@@ -1114,13 +1046,16 @@ substitute_and_fold (prop_value_t *prop_value, bool use_ranges_p) ...@@ -1114,13 +1046,16 @@ substitute_and_fold (prop_value_t *prop_value, bool use_ranges_p)
print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
} }
/* If we have range information, see if we can fold old_stmt = stmt;
predicate expressions. */
if (use_ranges_p) /* 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 = fold_predicate_in (&i); did_replace = true;
/* fold_predicate_in should not have reallocated STMT. */ prop_stats.num_stmts_folded++;
gcc_assert (gsi_stmt (i) == stmt);
} }
/* Only replace real uses if we couldn't fold the /* Only replace real uses if we couldn't fold the
...@@ -1130,20 +1065,9 @@ substitute_and_fold (prop_value_t *prop_value, bool use_ranges_p) ...@@ -1130,20 +1065,9 @@ substitute_and_fold (prop_value_t *prop_value, bool use_ranges_p)
did_replace |= replace_uses_in (stmt, prop_value); did_replace |= replace_uses_in (stmt, prop_value);
/* If we made a replacement, fold the statement. */ /* If we made a replacement, fold the statement. */
old_stmt = stmt;
if (did_replace) if (did_replace)
fold_stmt (&i); 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. */ /* Now cleanup. */
if (did_replace) if (did_replace)
{ {
...@@ -1190,8 +1114,8 @@ substitute_and_fold (prop_value_t *prop_value, bool use_ranges_p) ...@@ -1190,8 +1114,8 @@ substitute_and_fold (prop_value_t *prop_value, bool use_ranges_p)
prop_stats.num_const_prop); prop_stats.num_const_prop);
statistics_counter_event (cfun, "Copies propagated", statistics_counter_event (cfun, "Copies propagated",
prop_stats.num_copy_prop); prop_stats.num_copy_prop);
statistics_counter_event (cfun, "Predicates folded", statistics_counter_event (cfun, "Statements folded",
prop_stats.num_pred_folded); prop_stats.num_stmts_folded);
statistics_counter_event (cfun, "Statements deleted", statistics_counter_event (cfun, "Statements deleted",
prop_stats.num_dce); prop_stats.num_dce);
return something_changed; return something_changed;
......
...@@ -110,6 +110,7 @@ typedef struct value_range_d value_range_t; ...@@ -110,6 +110,7 @@ typedef struct value_range_d value_range_t;
/* Call-back functions used by the value propagation engine. */ /* 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_stmt_fn) (gimple, edge *, tree *);
typedef enum ssa_prop_result (*ssa_prop_visit_phi_fn) (gimple); 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 */ /* In tree-ssa-propagate.c */
...@@ -119,6 +120,6 @@ bool valid_gimple_call_p (tree); ...@@ -119,6 +120,6 @@ bool valid_gimple_call_p (tree);
void move_ssa_defining_stmt_for_defs (gimple, gimple); void move_ssa_defining_stmt_for_defs (gimple, gimple);
bool update_call_from_tree (gimple_stmt_iterator *, tree); bool update_call_from_tree (gimple_stmt_iterator *, tree);
bool stmt_makes_single_store (gimple); bool stmt_makes_single_store (gimple);
bool substitute_and_fold (prop_value_t *, bool); bool substitute_and_fold (prop_value_t *, ssa_prop_fold_stmt_fn);
#endif /* _TREE_SSA_PROPAGATE_H */ #endif /* _TREE_SSA_PROPAGATE_H */
...@@ -5678,7 +5678,7 @@ vrp_evaluate_conditional_warnv_with_ops (enum tree_code code, tree op0, ...@@ -5678,7 +5678,7 @@ vrp_evaluate_conditional_warnv_with_ops (enum tree_code code, tree op0,
based on undefined signed overflow, issue a warning if based on undefined signed overflow, issue a warning if
appropriate. */ appropriate. */
tree static tree
vrp_evaluate_conditional (enum tree_code code, tree op0, tree op1, gimple stmt) vrp_evaluate_conditional (enum tree_code code, tree op0, tree op1, gimple stmt)
{ {
bool sop; bool sop;
...@@ -6945,7 +6945,7 @@ simplify_switch_using_ranges (gimple stmt) ...@@ -6945,7 +6945,7 @@ simplify_switch_using_ranges (gimple stmt)
/* Simplify STMT using ranges if possible. */ /* Simplify STMT using ranges if possible. */
bool static bool
simplify_stmt_using_ranges (gimple_stmt_iterator *gsi) simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
{ {
gimple stmt = gsi_stmt (*gsi); gimple stmt = gsi_stmt (*gsi);
...@@ -6998,6 +6998,78 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi) ...@@ -6998,6 +6998,78 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
return false; 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 /* 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. each attempt to thread a block's incoming edge to an outgoing edge.
...@@ -7187,7 +7259,7 @@ vrp_finalize (void) ...@@ -7187,7 +7259,7 @@ vrp_finalize (void)
single_val_range = NULL; single_val_range = NULL;
} }
substitute_and_fold (single_val_range, true); substitute_and_fold (single_val_range, vrp_fold_stmt);
if (warn_array_bounds) if (warn_array_bounds)
check_all_array_refs (); check_all_array_refs ();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment