diff options
author | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-02-17 04:15:32 +0000 |
---|---|---|
committer | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-02-17 04:15:32 +0000 |
commit | 8dbf774a27ebfe14b083c5b244cab23756eb2662 (patch) | |
tree | baa21343ce68c59242247d5fe6009ab29fba14f3 /gcc/tree-vrp.c | |
parent | e345fa3ab01357607f378005c69af2d0ff0d0183 (diff) | |
download | gcc-8dbf774a27ebfe14b083c5b244cab23756eb2662.tar.gz |
* tree-vrp.c (set_value_range_to_nonnegative): New function.
(vrp_expr_computes_nonnegative, ssa_name_nonnegative_p): Likewise.
(ssa_name_nonzero_p): Likewise.
(get_value_range): Return NULL if VRP is not running.
(extract_range_from_expr): Fallback to tree_expr_XXX_p if
VRP routines do not discover a range.
(vrp_finalize): Clear VR_VALUE to indicate VRP is not running.
* tree.h (ssa_name_nonzero_p, ssa_name_nonnegative_p): Prototype.
* fold-const.c (tree_expr_nonzero_p): For SSA_NAMEs, query VRP.
(tree_expr_nonnegative_p): Similarly.
* tree-ssa-dom.c (nonzero_vars, nonzero_vars_stack): Remove.
(restore_nonzero_vars_to_original_value): Remove.
(unsafe_associative_fp_binop): Remove.
(tree_ssa_dominator_optimize): Remove initialization and
finalization of nonzero_vars and nonzero_vars_stack.
(dom_opt_initialize_block): No longer push marker on
nonzero_vars_stack.
(dom_opt_finalize_block): No longer call
restore_nonzero_vars_to_original_value.
(record_equivalences_from_phis): No longer look for
nonzero PHI arguments.
(cprop_into_successor_phis): No longer propagate nonzero
property into PHI arguments. Lose unused argument. Caller
updated.
(record_equivalences_from_stmt): No longer record nonzero
values for SSA_NAMEs.
(lookup_avail_expr): No longer use nonzero_vars.
* gcc.dg/tree-ssa/vrp24.c: Update expected output.
* gcc.dg/tree-ssa/vrp26.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@111175 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r-- | gcc/tree-vrp.c | 89 |
1 files changed, 85 insertions, 4 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index a0950feeab2..b6b6d409d0b 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -191,6 +191,14 @@ copy_value_range (value_range_t *to, value_range_t *from) set_value_range (to, from->type, from->min, from->max, from->equiv); } +/* Set value range VR to a non-negative range of type TYPE. */ + +static inline void +set_value_range_to_nonnegative (value_range_t *vr, tree type) +{ + tree zero = build_int_cst (type, 0); + set_value_range (vr, VR_RANGE, zero, TYPE_MAX_VALUE (type), vr->equiv); +} /* Set value range VR to a non-NULL range of type TYPE. */ @@ -236,8 +244,10 @@ set_value_range_to_undefined (value_range_t *vr) } -/* Return value range information for VAR. Create an empty range - if none existed. */ +/* Return value range information for VAR. + + If we have no values ranges recorded (ie, VRP is not running), then + return NULL. Otherwise create an empty range if none existed for VAR. */ static value_range_t * get_value_range (tree var) @@ -246,6 +256,10 @@ get_value_range (tree var) tree sym; unsigned ver = SSA_NAME_VERSION (var); + /* If we have no recorded ranges, then return NULL. */ + if (! vr_value) + return NULL; + vr = vr_value[ver]; if (vr) return vr; @@ -358,6 +372,14 @@ symbolic_range_p (value_range_t *vr) || !is_gimple_min_invariant (vr->max)); } +/* Like tree_expr_nonnegative_p, but this function uses value ranges + obtained so far. */ + +static bool +vrp_expr_computes_nonnegative (tree expr) +{ + return tree_expr_nonnegative_p (expr); +} /* Like tree_expr_nonzero_p, but this function uses value ranges obtained so far. */ @@ -629,6 +651,50 @@ range_includes_zero_p (value_range_t *vr) return (value_inside_range (zero, vr) == 1); } +/* Return true if T, an SSA_NAME, is known to be nonnegative. Return + false otherwise or if no value range information is available. */ + +bool +ssa_name_nonnegative_p (tree t) +{ + value_range_t *vr = get_value_range (t); + + if (!vr) + return false; + + /* Testing for VR_ANTI_RANGE is not useful here as any anti-range + which would return a useful value should be encoded as a VR_RANGE. */ + if (vr->type == VR_RANGE) + { + int result = compare_values (vr->min, integer_zero_node); + + return (result == 0 || result == 1); + } + return false; +} + +/* Return true if T, an SSA_NAME, is known to be nonzero. Return + false otherwise or if no value range information is available. */ + +bool +ssa_name_nonzero_p (tree t) +{ + value_range_t *vr = get_value_range (t); + + if (!vr) + return false; + + /* A VR_RANGE which does not include zero is a nonzero value. */ + if (vr->type == VR_RANGE && !symbolic_range_p (vr)) + return ! range_includes_zero_p (vr); + + /* A VR_ANTI_RANGE which does include zero is a nonzero value. */ + if (vr->type == VR_ANTI_RANGE && !symbolic_range_p (vr)) + return range_includes_zero_p (vr); + + return false; +} + /* When extracting ranges from X_i = ASSERT_EXPR <Y_j, pred>, we will initially consider X_i and Y_j equivalent, so the equivalence set @@ -1868,10 +1934,21 @@ extract_range_from_expr (value_range_t *vr, tree expr) extract_range_from_comparison (vr, expr); else if (is_gimple_min_invariant (expr)) set_value_range (vr, VR_RANGE, expr, expr, NULL); - else if (vrp_expr_computes_nonzero (expr)) - set_value_range_to_nonnull (vr, TREE_TYPE (expr)); else set_value_range_to_varying (vr); + + /* If we got a varying range from the tests above, try a final + time to derive a nonnegative or nonzero range. This time + relying primarily on generic routines in fold in conjunction + with range data. */ + if (vr->type == VR_VARYING) + { + if (INTEGRAL_TYPE_P (TREE_TYPE (expr)) + && vrp_expr_computes_nonnegative (expr)) + set_value_range_to_nonnegative (vr, TREE_TYPE (expr)); + else if (vrp_expr_computes_nonzero (expr)) + set_value_range_to_nonnull (vr, TREE_TYPE (expr)); + } } /* Given a range VR, a LOOP and a variable VAR, determine whether it @@ -4428,6 +4505,10 @@ vrp_finalize (void) free (single_val_range); free (vr_value); + + /* So that we can distinguish between VRP data being available + and not available. */ + vr_value = NULL; } |