diff options
author | Richard Guenther <rguenther@suse.de> | 2009-09-22 08:30:34 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2009-09-22 08:30:34 +0000 |
commit | ff7ffb8f2a4670297b53f38c0a751defc59bb47f (patch) | |
tree | 051a9f785512d04b8b2f8278b342dada185c9d91 /gcc/tree-vrp.c | |
parent | 8b659ecb8ea30d4f15c973d114c28f0c46ad96d6 (diff) | |
download | gcc-ff7ffb8f2a4670297b53f38c0a751defc59bb47f.tar.gz |
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
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r-- | gcc/tree-vrp.c | 78 |
1 files changed, 75 insertions, 3 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 514a3ec661e..57800075e94 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -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 (); |