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
This commit is contained in:
Richard Guenther 2009-09-22 08:30:34 +00:00 committed by Richard Biener
parent 8b659ecb8e
commit ff7ffb8f2a
7 changed files with 114 additions and 102 deletions

View File

@ -1,3 +1,22 @@
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>
* dwarf2out.c (address_of_int_loc_descriptor): Avoid signed/unsigned

View File

@ -680,10 +680,6 @@ tree fold_const_aggregate_ref (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 */
extern void dump_dominator_optimization_stats (FILE *);
extern void debug_dominator_optimization_stats (void);

View File

@ -724,7 +724,7 @@ ccp_finalize (void)
do_dbg_cnt ();
/* 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);
const_val = NULL;

View File

@ -847,7 +847,7 @@ fini_copy_prop (void)
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 (copy_of);

View File

@ -856,7 +856,7 @@ struct prop_stats_d
{
long num_const_prop;
long num_copy_prop;
long num_pred_folded;
long num_stmts_folded;
long num_dce;
};
@ -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.
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).
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, bool use_ranges_p)
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 && !use_ranges_p)
if (prop_value == NULL && !fold_fn)
return false;
if (dump_file && (dump_flags & TDF_DETAILS))
@ -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);
}
/* If we have range information, see if we can fold
predicate expressions. */
if (use_ranges_p)
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 = fold_predicate_in (&i);
/* fold_predicate_in should not have reallocated STMT. */
gcc_assert (gsi_stmt (i) == stmt);
did_replace = true;
prop_stats.num_stmts_folded++;
}
/* 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)
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)
{
@ -1190,8 +1114,8 @@ substitute_and_fold (prop_value_t *prop_value, bool use_ranges_p)
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 folded",
prop_stats.num_stmts_folded);
statistics_counter_event (cfun, "Statements deleted",
prop_stats.num_dce);
return something_changed;

View File

@ -110,6 +110,7 @@ typedef struct value_range_d value_range_t;
/* 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 */
@ -119,6 +120,6 @@ bool valid_gimple_call_p (tree);
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);
bool substitute_and_fold (prop_value_t *, ssa_prop_fold_stmt_fn);
#endif /* _TREE_SSA_PROPAGATE_H */

View File

@ -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
appropriate. */
tree
static tree
vrp_evaluate_conditional (enum tree_code code, tree op0, tree op1, gimple stmt)
{
bool sop;
@ -6945,7 +6945,7 @@ simplify_switch_using_ranges (gimple stmt)
/* Simplify STMT using ranges if possible. */
bool
static bool
simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
{
gimple stmt = gsi_stmt (*gsi);
@ -6998,6 +6998,78 @@ simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
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.
@ -7187,7 +7259,7 @@ vrp_finalize (void)
single_val_range = NULL;
}
substitute_and_fold (single_val_range, true);
substitute_and_fold (single_val_range, vrp_fold_stmt);
if (warn_array_bounds)
check_all_array_refs ();