diff options
-rw-r--r-- | gcc/ChangeLog | 19 | ||||
-rw-r--r-- | gcc/tree-flow.h | 4 | ||||
-rw-r--r-- | gcc/tree-ssa-ccp.c | 2 | ||||
-rw-r--r-- | gcc/tree-ssa-copy.c | 2 | ||||
-rw-r--r-- | gcc/tree-ssa-propagate.c | 108 | ||||
-rw-r--r-- | gcc/tree-ssa-propagate.h | 3 | ||||
-rw-r--r-- | gcc/tree-vrp.c | 78 |
7 files changed, 114 insertions, 102 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fe3b12cd254..97dd74b3d1f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index b93e2f4a373..77cd80bdfe9 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -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); diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 61827a74ab4..5e305880bb7 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -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; diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c index 6bc3c13d4bb..986ad454e74 100644 --- a/gcc/tree-ssa-copy.c +++ b/gcc/tree-ssa-copy.c @@ -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); diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c index 42d89e91920..ec0ecf3d3bb 100644 --- a/gcc/tree-ssa-propagate.c +++ b/gcc/tree-ssa-propagate.c @@ -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; diff --git a/gcc/tree-ssa-propagate.h b/gcc/tree-ssa-propagate.h index 3c267247717..e8f4f03dfb3 100644 --- a/gcc/tree-ssa-propagate.h +++ b/gcc/tree-ssa-propagate.h @@ -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 */ 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 (); |