diff options
author | dnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-06-02 02:57:15 +0000 |
---|---|---|
committer | dnovillo <dnovillo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-06-02 02:57:15 +0000 |
commit | eea12c729f81ba778b6b37e0ddc3311b80e867af (patch) | |
tree | ae1c65c21b373e1f2c501ae1c46755f0fb072bda /gcc/tree-ssa-propagate.c | |
parent | 5d7bbf40fca8537c4d4fd1c9a1db5b0db017277e (diff) | |
download | gcc-eea12c729f81ba778b6b37e0ddc3311b80e867af.tar.gz |
2005-06-01 Diego Novillo <dnovillo@redhat.com>
PR 14341, PR 21332, PR 20701, PR 21029, PR 21086, PR 21090
PR 21289, PR 21348, PR 21367, PR 21368, PR 21458.
* fold-const.c (invert_tree_comparison): Make extern.
* tree-flow.h (enum value_range_type): Move to tree-ssa-propagate.
(struct value_range_def): Limewise.
(get_value_range): Remove.
(dump_value_range): Remove.
(dump_all_value_ranges): Remove.
(debug_all_value_ranges): Remove.
(vrp_evaluate_conditional): Declare.
* tree-ssa-propagate.c (struct prop_stats_d): Add field
num_pred_folded.
(substitute_and_fold): Add argument use_ranges_p.
Update all callers.
If use_ranges_p is true, call fold_predicate_in to fold
predicates using range information.
Ignore ASSERT_EXPRs.
Change debugging output to only show statements that have been
folded.
(replace_phi_args_in): Move debugging output code from
substitute and fold.
(fold_predicate_in): New local function.
* tree-ssa-propagate.h (enum value_range_type): Move from
tree-flow.h.
(struct value_range_d): Likewise.
Add field 'equiv'.
(value_range_t): Rename from value_range.
* tree-vrp.c (found_in_subgraph): Rename from found.
(get_opposite_operand): Remove.
(struct assert_locus_d): Declare.
(assert_locus_t): Declare.
(need_assert_for): Declare.
(asserts_for): Declare.
(blocks_visited): Declare.
(vr_value): Declare.
(set_value_range): Add argument 'equiv'.
Don't drop to VARYING ranges that cover all values in the
type.
Make deep copy of equivalence set 'equiv'.
(copy_value_range): New local function.
(set_value_range_to_undefined): New local function.
(compare_values): Return -2 if either value has overflowed.
(range_includes_zero_p): New local function.
(extract_range_from_assert): Flip the predicate code if the
name being asserted is on the RHS of the predicate.
Avoid creating unnecessary symbolic ranges if the comparison
includes another name with a known numeric range.
Update the equivalnce set of the new range when asserting
EQ_EXPR predicates.
(extract_range_from_ssa_name): Update the equivalence set of
the new range with VAR.
(extract_range_from_binary_expr): Also handle TRUTH_*_EXPR.
If -fwrapv is used, set the resulting range to VARYING if the
operation overflows. Otherwise, use TYPE_MIN_VALUE and
TYPE_MAX_VALUE to represent -INF and +INF.
Fix handling of *_DIV_EXPR.
(extract_range_from_unary_expr): Handle MINUS_EXPR and
ABS_EXPR properly by switching the range around if necessary.
(extract_range_from_comparison): New local function.
(extract_range_from_expr): Call it.
(adjust_range_with_scev): Do not adjust the range if using
wrapping arithmetic (-fwrapv).
(dump_value_range): Also show equivalence set.
Show -INF and +INF for TYPE_MIN_VALUE and TYPE_MAX_VALUE.
(build_assert_expr_for): Also build ASSERT_EXPR for EQ_EXPR.
(infer_value_range): Change return value to bool.
Add arguments 'comp_code_p' and 'val_p'.
Do not attempt to infer ranges from statements that may throw.
Store the comparison code in comp_code_p.
Store the other operand to be used in the predicate in val_p.
(dump_asserts_for): New.
(debug_asserts_for): New.
(dump_all_asserts): New.
(debug_all_asserts): New.
(register_new_assert_for): New.
(register_edge_assert_for): New.
(find_conditional_asserts): New.
(find_assert_locations): New.
(process_assert_insertions_for): New.
(process_assert_insertions): New.
(insert_range_assertions): Initialize found_in_subgraph,
blocks_visited, need_assert_for and asserts_for.
Call find_assert_locations and process_assert_insertions.
(remove_range_assertions): Add more documentation.
(vrp_initialize): Change return type to void.
Do not try to guess if running VRP is worth it.
(compare_name_with_value): New.
(compare_names): New.
(vrp_evaluate_conditional): Add argument 'use_equiv_p'. If
use_equiv_p is true, call compare_names and
compare_name_with_value to compare all the ranges for every
name in the equivalence set of the predicate operands.
Update all callers.
(vrp_meet): Try harder not to derive a VARYING range.
If two values meet, the resulting equivalence set is the
intersection of the two equivalence sets.
(vrp_visit_phi_node): Call copy_value_range to get the current
range information of the LHS.
(vrp_finalize): Create a value vector representing all the
names that ended up with exactly one value in their range.
Call substitute_and_fold.
(execute_vrp): Document equivalence sets in ranges.
* tree.h (SSA_NAME_VALUE_RANGE): Remove.
(struct tree_ssa_name): Remove field value_range.
(invert_tree_comparison): Declare.
testsuite/ChangeLog
2005-06-01 Diego Novillo <dnovillo@redhat.com>
PR 14341, PR 21332, PR 20701, PR 21086, PR 21090
PR 21289, PR 21348, PR 21367, PR 21368, PR 21458.
* gcc.dg/tree-ssa/pr14341.c: New test.
* gcc.dg/tree-ssa/pr14841.c: New test.
* gcc.dg/tree-ssa/pr20701.c: New test.
* gcc.dg/tree-ssa/pr21086.c: New test.
* gcc.dg/tree-ssa/pr21090.c: New test.
* gcc.dg/tree-ssa/pr21332.c: New test.
* gcc.dg/tree-ssa/pr21458.c: New test.
* gcc.dg/tree-ssa/pr21658.c: New test.
* gcc.dg/tree-ssa/vrp01.c: New test.
* gcc.dg/tree-ssa/vrp02.c: New test.
* gcc.dg/tree-ssa/vrp03.c: New test.
* gcc.dg/tree-ssa/vrp04.c: New test.
* gcc.dg/tree-ssa/vrp05.c: New test.
* gcc.dg/tree-ssa/vrp06.c: New test.
* gcc.dg/tree-ssa/vrp07.c: New test.
* gcc.dg/tree-ssa/vrp08.c: New test.
* gcc.dg/tree-ssa/vrp09.c: New test.
* gcc.dg/tree-ssa/vrp10.c: New test.
* gcc.dg/tree-ssa/vrp11.c: New test.
* gcc.dg/tree-ssa/vrp12.c: New test.
* gcc.dg/tree-ssa/vrp13.c: New test.
2005-06-01 Alexandre Oliva <aoliva@redhat.com>
PR 21029
* gcc.dg/tree-ssa/pr21029.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@100478 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-propagate.c')
-rw-r--r-- | gcc/tree-ssa-propagate.c | 146 |
1 files changed, 114 insertions, 32 deletions
diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c index f272aa54b4b..37c644b50c4 100644 --- a/gcc/tree-ssa-propagate.c +++ b/gcc/tree-ssa-propagate.c @@ -773,6 +773,7 @@ struct prop_stats_d { long num_const_prop; long num_copy_prop; + long num_pred_folded; }; static struct prop_stats_d prop_stats; @@ -964,6 +965,11 @@ static void replace_phi_args_in (tree phi, prop_value_t *prop_value) { int i; + bool replaced = false; + tree prev_phi = NULL; + + if (dump_file && (dump_flags & TDF_DETAILS)) + prev_phi = unshare_expr (phi); for (i = 0; i < PHI_NUM_ARGS (phi); i++) { @@ -981,6 +987,7 @@ replace_phi_args_in (tree phi, prop_value_t *prop_value) prop_stats.num_copy_prop++; propagate_value (PHI_ARG_DEF_PTR (phi, i), val); + replaced = true; /* If we propagated a copy and this argument flows through an abnormal edge, update the replacement @@ -991,19 +998,79 @@ replace_phi_args_in (tree phi, prop_value_t *prop_value) } } } + + if (replaced && dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Folded PHI node: "); + print_generic_stmt (dump_file, prev_phi, TDF_SLIM); + fprintf (dump_file, " into: "); + print_generic_stmt (dump_file, phi, TDF_SLIM); + fprintf (dump_file, "\n"); + } +} + + +/* If STMT 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 (tree stmt) +{ + tree *pred_p = NULL; + tree val; + + if (TREE_CODE (stmt) == MODIFY_EXPR + && COMPARISON_CLASS_P (TREE_OPERAND (stmt, 1))) + pred_p = &TREE_OPERAND (stmt, 1); + else if (TREE_CODE (stmt) == COND_EXPR) + pred_p = &COND_EXPR_COND (stmt); + else + return false; + + val = vrp_evaluate_conditional (*pred_p, true); + if (val) + { + if (dump_file) + { + fprintf (dump_file, "Folding predicate "); + print_generic_expr (dump_file, *pred_p, 0); + fprintf (dump_file, " to "); + print_generic_expr (dump_file, val, 0); + fprintf (dump_file, "\n"); + } + + prop_stats.num_pred_folded++; + *pred_p = val; + 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 + 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). */ void -substitute_and_fold (prop_value_t *prop_value) +substitute_and_fold (prop_value_t *prop_value, bool use_ranges_p) { basic_block bb; + if (prop_value == NULL && !use_ranges_p) + return; + if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, - "\nSubstituing values and folding statements\n\n"); + fprintf (dump_file, "\nSubstituing values and folding statements\n\n"); memset (&prop_stats, 0, sizeof (prop_stats)); @@ -1013,41 +1080,51 @@ substitute_and_fold (prop_value_t *prop_value) block_stmt_iterator i; tree phi; - /* Propagate our known values into PHI nodes. */ - for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi)) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, "Replaced "); - print_generic_stmt (dump_file, phi, TDF_SLIM); - } - + /* Propagate known values into PHI nodes. */ + if (prop_value) + for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi)) replace_phi_args_in (phi, prop_value); - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, " with "); - print_generic_stmt (dump_file, phi, TDF_SLIM); - fprintf (dump_file, "\n"); - } - } - for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i)) { bool replaced_address, did_replace; + tree prev_stmt = NULL; tree stmt = bsi_stmt (i); + /* Ignore ASSERT_EXPRs. They are used by VRP to generate + range information for names and they are discarded + afterwards. */ + if (TREE_CODE (stmt) == MODIFY_EXPR + && TREE_CODE (TREE_OPERAND (stmt, 1)) == ASSERT_EXPR) + continue; + /* Replace the statement with its folded version and mark it folded. */ + did_replace = false; + replaced_address = false; if (dump_file && (dump_flags & TDF_DETAILS)) + prev_stmt = unshare_expr (stmt); + + /* If we have range information, see if we can fold + predicate expressions. */ + if (use_ranges_p) + did_replace = fold_predicate_in (stmt); + + if (prop_value) { - fprintf (dump_file, "Replaced "); - print_generic_stmt (dump_file, stmt, TDF_SLIM); + /* Only replace real uses if we couldn't fold the + statement using value range information (value range + information is not collected on virtuals, so we only + need to check this for real uses). */ + if (!did_replace) + did_replace |= replace_uses_in (stmt, &replaced_address, + prop_value); + + did_replace |= replace_vuses_in (stmt, &replaced_address, + prop_value); } - replaced_address = false; - did_replace = replace_uses_in (stmt, &replaced_address, prop_value); - did_replace |= replace_vuses_in (stmt, &replaced_address, prop_value); + /* If we made a replacement, fold and cleanup the statement. */ if (did_replace) { tree old_stmt = stmt; @@ -1068,13 +1145,15 @@ substitute_and_fold (prop_value_t *prop_value) rhs = get_rhs (stmt); if (TREE_CODE (rhs) == ADDR_EXPR) recompute_tree_invarant_for_addr_expr (rhs); - } - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, " with "); - print_generic_stmt (dump_file, stmt, TDF_SLIM); - fprintf (dump_file, "\n"); + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Folded statement: "); + print_generic_stmt (dump_file, prev_stmt, TDF_SLIM); + fprintf (dump_file, " into: "); + print_generic_stmt (dump_file, stmt, TDF_SLIM); + fprintf (dump_file, "\n"); + } } } } @@ -1085,6 +1164,9 @@ substitute_and_fold (prop_value_t *prop_value) prop_stats.num_const_prop); fprintf (dump_file, "Copies propagated: %6ld\n", prop_stats.num_copy_prop); + fprintf (dump_file, "Predicates folded: %6ld\n", + prop_stats.num_pred_folded); } } + #include "gt-tree-ssa-propagate.h" |