summaryrefslogtreecommitdiff
path: root/gcc/tree-vrp.c
diff options
context:
space:
mode:
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>2006-02-17 04:15:32 +0000
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>2006-02-17 04:15:32 +0000
commit8dbf774a27ebfe14b083c5b244cab23756eb2662 (patch)
treebaa21343ce68c59242247d5fe6009ab29fba14f3 /gcc/tree-vrp.c
parente345fa3ab01357607f378005c69af2d0ff0d0183 (diff)
downloadgcc-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.c89
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;
}