tree-vrp.c (set_value_range_to_nonnull): Declare inline.

* tree-vrp.c (set_value_range_to_nonnull): Declare inline.
	(set_value_range_to_null): Likewise.
	(set_value_range_to_varying): New function.  Use it in all
	call sites that used to call set_value_range (vr, VR_VARYING, ...).
	(extract_range_from_assert): If the integral type has a
	super-type, and LIMIT is not within MIN and MAX values of that
	type, set the resulting range to VR_VARYING.

From-SVN: r99125
This commit is contained in:
Diego Novillo 2005-05-02 22:54:37 +00:00 committed by Diego Novillo
parent eeac8f6b3a
commit b565d77783
2 changed files with 109 additions and 30 deletions

View File

@ -1,3 +1,13 @@
2005-05-02 Diego Novillo <dnovillo@redhat.com>
* tree-vrp.c (set_value_range_to_nonnull): Declare inline.
(set_value_range_to_null): Likewise.
(set_value_range_to_varying): New function. Use it in all
call sites that used to call set_value_range (vr, VR_VARYING, ...).
(extract_range_from_assert): If the integral type has a
super-type, and LIMIT is not within MIN and MAX values of that
type, set the resulting range to VR_VARYING.
2005-05-02 Hans-Peter Nilsson <hp@bitrange.com>
* config/mmix/mmix.opt: New file.

View File

@ -251,7 +251,7 @@ range_is_null (value_range *vr)
/* Set value range VR to a non-NULL range of type TYPE. */
static void
static inline void
set_value_range_to_nonnull (value_range *vr, tree type)
{
tree zero = build_int_cst (type, 0);
@ -261,7 +261,7 @@ set_value_range_to_nonnull (value_range *vr, tree type)
/* Set value range VR to a NULL range of type TYPE. */
static void
static inline void
set_value_range_to_null (value_range *vr, tree type)
{
tree zero = build_int_cst (type, 0);
@ -269,6 +269,15 @@ set_value_range_to_null (value_range *vr, tree type)
}
/* Set value range VR to VR_VARYING. */
static inline void
set_value_range_to_varying (value_range *vr)
{
set_value_range (vr, VR_VARYING, NULL_TREE, NULL_TREE);
}
/* Compare two values VAL1 and VAL2. Return
-2 if VAL1 and VAL2 cannot be compared at compile-time,
@ -477,9 +486,11 @@ extract_range_from_assert (value_range *vr_p, tree expr)
{
tree var, cond, limit, type;
value_range *var_vr;
enum tree_code cond_code;
var = ASSERT_EXPR_VAR (expr);
cond = ASSERT_EXPR_COND (expr);
cond_code = TREE_CODE (cond);
gcc_assert (COMPARISON_CLASS_P (cond));
@ -493,12 +504,70 @@ extract_range_from_assert (value_range *vr_p, tree expr)
(NE_EXPR). Notice that we don't need to handle EQ_EXPR in these
cases because assertions with equalities are never generated.
The assert pass generates straight assignments in those cases. */
if (POINTER_TYPE_P (type) && TREE_CODE (cond) != NE_EXPR)
if (POINTER_TYPE_P (type) && cond_code != NE_EXPR)
{
set_value_range (vr_p, VR_VARYING, NULL_TREE, NULL_TREE);
set_value_range_to_varying (vr_p);
return;
}
/* Special handling for integral types with super-types. Some FEs
construct integral types derived from other types and restrict
the range of values these new types may take.
It may happen that LIMIT is actually smaller than TYPE's minimum
value. For instance, the Ada FE is generating code like this
during bootstrap:
D.1480_32 = nam_30 - 300000361;
if (D.1480_32 <= 1) goto <L112>; else goto <L52>;
<L112>:;
D.1480_94 = ASSERT_EXPR <D.1480_32, D.1480_32 <= 1>;
All the names are of type types__name_id___XDLU_300000000__399999999
which has min == 300000000 and max == 399999999. This means that
the ASSERT_EXPR would try to create the range [3000000, 1] which
is invalid.
The fact that the type specifies MIN and MAX values does not
automatically mean that every variable of that type will always
be within that range, so the predicate may well be true at run
time. If we had symbolic -INF and +INF values, we could
represent this range, but we currently represent -INF and +INF
using the type's min and max values.
So, the only sensible thing we can do for now is set the
resulting range to VR_VARYING. TODO, would having symbolic -INF
and +INF values be worth the trouble? */
if (TREE_TYPE (type))
{
if (cond_code == LE_EXPR || cond_code == LT_EXPR)
{
tree type_min = TYPE_MIN_VALUE (type);
int cmp = compare_values (limit, type_min);
/* For < or <= comparisons, if LIMIT is smaller than
TYPE_MIN, set the range to VR_VARYING. */
if (cmp == -1 || cmp == 0)
{
set_value_range_to_varying (vr_p);
return;
}
}
else if (cond_code == GE_EXPR || cond_code == GT_EXPR)
{
tree type_max = TYPE_MIN_VALUE (type);
int cmp = compare_values (limit, type_max);
/* For > or >= comparisons, if LIMIT is bigger than
TYPE_MAX, set the range to VR_VARYING. */
if (cmp == 1 || cmp == 0)
{
set_value_range_to_varying (vr_p);
return;
}
}
}
if (TREE_CODE (cond) == NE_EXPR)
set_value_range (vr_p, VR_ANTI_RANGE, limit, limit);
else if (TREE_CODE (cond) == LE_EXPR)
@ -599,7 +668,7 @@ extract_range_from_binary_expr (value_range *vr, tree expr)
&& code != MIN_EXPR
&& code != MAX_EXPR)
{
set_value_range (vr, VR_VARYING, NULL_TREE, NULL_TREE);
set_value_range_to_varying (vr);
return;
}
@ -613,7 +682,7 @@ extract_range_from_binary_expr (value_range *vr, tree expr)
if (is_gimple_min_invariant (op0))
set_value_range (&vr0, VR_RANGE, op0, op0);
else
set_value_range (&vr0, VR_VARYING, NULL_TREE, NULL_TREE);
set_value_range_to_varying (&vr0);
}
op1 = TREE_OPERAND (expr, 1);
@ -624,7 +693,7 @@ extract_range_from_binary_expr (value_range *vr, tree expr)
if (is_gimple_min_invariant (op1))
set_value_range (&vr1, VR_RANGE, op1, op1);
else
set_value_range (&vr1, VR_VARYING, 0, 0);
set_value_range_to_varying (&vr1);
}
/* If either range is UNDEFINED, so is the result. */
@ -637,21 +706,21 @@ extract_range_from_binary_expr (value_range *vr, tree expr)
/* If either range is VARYING, so is the result. */
if (vr0.type == VR_VARYING || vr1.type == VR_VARYING)
{
set_value_range (vr, VR_VARYING, NULL_TREE, NULL_TREE);
set_value_range_to_varying (vr);
return;
}
/* If the ranges are of different types, the result is VARYING. */
if (vr0.type != vr1.type)
{
set_value_range (vr, VR_VARYING, NULL_TREE, NULL_TREE);
set_value_range_to_varying (vr);
return;
}
/* TODO. Refuse to do any symbolic range operations for now. */
if (symbolic_range_p (&vr0) || symbolic_range_p (&vr1))
{
set_value_range (vr, VR_VARYING, NULL_TREE, NULL_TREE);
set_value_range_to_varying (vr);
return;
}
@ -676,7 +745,7 @@ extract_range_from_binary_expr (value_range *vr, tree expr)
{
/* Subtracting from a pointer, may yield 0, so just drop the
resulting range to varying. */
set_value_range (vr, VR_VARYING, NULL_TREE, NULL_TREE);
set_value_range_to_varying (vr);
}
return;
@ -710,7 +779,7 @@ extract_range_from_binary_expr (value_range *vr, tree expr)
/* If the new range has its limits swapped around (MIN > MAX),
then the operation caused one of them to wrap around, mark
the new range VARYING. */
set_value_range (vr, VR_VARYING, NULL_TREE, NULL_TREE);
set_value_range_to_varying (vr);
}
else
set_value_range (vr, vr0.type, min, max);
@ -767,7 +836,7 @@ extract_range_from_unary_expr (value_range *vr, tree expr)
if (is_gimple_min_invariant (op0))
set_value_range (&vr0, VR_RANGE, op0, op0);
else
set_value_range (&vr0, VR_VARYING, NULL_TREE, NULL_TREE);
set_value_range_to_varying (&vr0);
}
/* If VR0 is UNDEFINED, so is the result. */
@ -780,14 +849,14 @@ extract_range_from_unary_expr (value_range *vr, tree expr)
/* If VR0 is VARYING, so is the result. */
if (vr0.type == VR_VARYING)
{
set_value_range (vr, VR_VARYING, NULL_TREE, NULL_TREE);
set_value_range_to_varying (vr);
return;
}
/* TODO. Refuse to do any symbolic range operations for now. */
if (symbolic_range_p (&vr0))
{
set_value_range (vr, VR_VARYING, NULL_TREE, NULL_TREE);
set_value_range_to_varying (vr);
return;
}
@ -796,7 +865,7 @@ extract_range_from_unary_expr (value_range *vr, tree expr)
if (!INTEGRAL_TYPE_P (TREE_TYPE (op0))
&& !POINTER_TYPE_P (TREE_TYPE (op0)))
{
set_value_range (vr, VR_VARYING, NULL_TREE, NULL_TREE);
set_value_range_to_varying (vr);
return;
}
@ -809,7 +878,7 @@ extract_range_from_unary_expr (value_range *vr, tree expr)
else if (range_is_null (&vr0))
set_value_range_to_null (vr, TREE_TYPE (expr));
else
set_value_range (vr, VR_VARYING, NULL_TREE, NULL_TREE);
set_value_range_to_varying (vr);
return;
}
@ -824,7 +893,7 @@ extract_range_from_unary_expr (value_range *vr, tree expr)
int' and 'y_5 = (unsigned short) x_3', if x_3 is ~[0, 0], it
is impossible to know at compile time whether y_5 will be
~[0, 0]. */
set_value_range (vr, VR_VARYING, NULL_TREE, NULL_TREE);
set_value_range_to_varying (vr);
return;
}
@ -839,7 +908,7 @@ extract_range_from_unary_expr (value_range *vr, tree expr)
/* If the new range has its limits swapped around (MIN > MAX),
then the operation caused one of them to wrap around, mark
the new range VARYING. */
set_value_range (vr, VR_VARYING, NULL_TREE, NULL_TREE);
set_value_range_to_varying (vr);
}
else
set_value_range (vr, vr0.type, min, max);
@ -867,7 +936,7 @@ extract_range_from_expr (value_range *vr, tree expr)
else if (TREE_CODE (expr) == INTEGER_CST)
set_value_range (vr, VR_RANGE, expr, expr);
else
set_value_range (vr, VR_VARYING, NULL_TREE, NULL_TREE);
set_value_range_to_varying (vr);
}
@ -1791,7 +1860,7 @@ vrp_initialize (void)
if (!stmt_interesting_for_vrp (phi))
{
tree lhs = PHI_RESULT (phi);
set_value_range (get_value_range (lhs), VR_VARYING, 0, 0);
set_value_range_to_varying (get_value_range (lhs));
DONT_SIMULATE_AGAIN (phi) = true;
}
else
@ -1807,7 +1876,7 @@ vrp_initialize (void)
ssa_op_iter i;
tree def;
FOR_EACH_SSA_TREE_OPERAND (def, stmt, i, SSA_OP_DEF)
set_value_range (get_value_range (def), VR_VARYING, 0, 0);
set_value_range_to_varying (get_value_range (def));
DONT_SIMULATE_AGAIN (stmt) = true;
}
else
@ -1878,7 +1947,7 @@ vrp_visit_assignment (tree stmt, tree *output_p)
/* Every other statements produces no useful ranges. */
FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
set_value_range (get_value_range (def), VR_VARYING, 0, 0);
set_value_range_to_varying (get_value_range (def));
return SSA_PROP_VARYING;
}
@ -2021,7 +2090,7 @@ vrp_visit_stmt (tree stmt, edge *taken_edge_p, tree *output_p)
/* All other statements produce nothing of interest for VRP, so mark
their outputs varying and prevent further simulation. */
FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
set_value_range (get_value_range (def), VR_VARYING, 0, 0);
set_value_range_to_varying (get_value_range (def));
return SSA_PROP_VARYING;
}
@ -2067,7 +2136,7 @@ vrp_meet (value_range *vr0, value_range *vr1)
/* If either is a symbolic range, drop to VARYING. */
if (symbolic_range_p (vr0) || symbolic_range_p (vr1))
{
set_value_range (vr0, VR_VARYING, NULL_TREE, NULL_TREE);
set_value_range_to_varying (vr0);
return;
}
@ -2097,7 +2166,7 @@ vrp_meet (value_range *vr0, value_range *vr1)
else
{
/* The two ranges don't intersect, set the result to VR_VARYING. */
set_value_range (vr0, VR_VARYING, NULL_TREE, NULL_TREE);
set_value_range_to_varying (vr0);
}
}
else if (vr0->type == VR_ANTI_RANGE && vr1->type == VR_ANTI_RANGE)
@ -2108,7 +2177,7 @@ vrp_meet (value_range *vr0, value_range *vr1)
&& compare_values (vr0->min, vr0->max) == 0)
/* Nothing to do. */ ;
else
set_value_range (vr0, VR_VARYING, NULL_TREE, NULL_TREE);
set_value_range_to_varying (vr0);
}
else if (vr0->type == VR_ANTI_RANGE || vr1->type == VR_ANTI_RANGE)
{
@ -2121,7 +2190,7 @@ vrp_meet (value_range *vr0, value_range *vr1)
*vr0 = *vr1;
}
else
set_value_range (vr0, VR_VARYING, NULL_TREE, NULL_TREE);
set_value_range_to_varying (vr0);
}
else
gcc_unreachable ();
@ -2190,7 +2259,7 @@ vrp_visit_phi_node (tree phi)
if (vr_result.type == VR_VARYING)
{
set_value_range (lhs_vr, VR_VARYING, 0, 0);
set_value_range_to_varying (lhs_vr);
return SSA_PROP_VARYING;
}
@ -2222,7 +2291,7 @@ vrp_visit_phi_node (tree phi)
if (vr_result.min == TYPE_MIN_VALUE (TREE_TYPE (vr_result.min))
&& vr_result.max == TYPE_MAX_VALUE (TREE_TYPE (vr_result.max)))
{
set_value_range (lhs_vr, VR_VARYING, 0, 0);
set_value_range_to_varying (lhs_vr);
return SSA_PROP_VARYING;
}
}