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:
parent
8b659ecb8e
commit
ff7ffb8f2a
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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 ();
|
||||
|
Loading…
Reference in New Issue
Block a user