tree-vrp.c (set_value_range_to_nonnegative): New function.
* 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. From-SVN: r111175
This commit is contained in:
parent
7f18f91710
commit
b16caf72c7
@ -1,5 +1,33 @@
|
||||
2006-02-16 Jeff Law <law@redhat.com>
|
||||
|
||||
* 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.
|
||||
|
||||
* stor-layout.c (set_sizetype): Set TYPE_MAX_VALUE properly
|
||||
for sizetype when sizetype is unsigned.
|
||||
|
||||
|
@ -11054,6 +11054,11 @@ tree_expr_nonnegative_p (tree t)
|
||||
|
||||
switch (TREE_CODE (t))
|
||||
{
|
||||
case SSA_NAME:
|
||||
/* Query VRP to see if it has recorded any information about
|
||||
the range of this object. */
|
||||
return ssa_name_nonnegative_p (t);
|
||||
|
||||
case ABS_EXPR:
|
||||
/* We can't return 1 if flag_wrapv is set because
|
||||
ABS_EXPR<INT_MIN> = INT_MIN. */
|
||||
@ -11317,6 +11322,11 @@ tree_expr_nonzero_p (tree t)
|
||||
|
||||
switch (TREE_CODE (t))
|
||||
{
|
||||
case SSA_NAME:
|
||||
/* Query VRP to see if it has recorded any information about
|
||||
the range of this object. */
|
||||
return ssa_name_nonzero_p (t);
|
||||
|
||||
case ABS_EXPR:
|
||||
return tree_expr_nonzero_p (TREE_OPERAND (t, 0));
|
||||
|
||||
|
@ -1,3 +1,8 @@
|
||||
2006-02-16 Jeff Law <law@redhat.com>
|
||||
|
||||
* gcc.dg/tree-ssa/vrp24.c: Update expected output.
|
||||
* gcc.dg/tree-ssa/vrp26.c: New test.
|
||||
|
||||
2006-02-16 Joseph S. Myers <joseph@codesourcery.com>
|
||||
|
||||
PR target/20353
|
||||
|
@ -79,11 +79,13 @@ L7:
|
||||
|
||||
}
|
||||
|
||||
/* The first n_sets > 0 test can be simplfiied into n_sets == 1 since
|
||||
n_sets can only have the values [0, 1] as it's the result of a
|
||||
boolean operation.
|
||||
|
||||
|
||||
/* The n_sets > 0 test can be simplified into n_sets == 1 since the
|
||||
only way to reach the test is when n_sets <= 1, and the only value
|
||||
which satisfies both conditions is n_sets == 1. */
|
||||
/* { dg-final { scan-tree-dump-times "Simplified relational" 1 "vrp1" } } */
|
||||
The second n_sets > 0 test can also be simplified into n_sets == 1
|
||||
as the only way to reach the tests is when n_sets <= 1 and the only
|
||||
value which satisfies both conditions is n_sets == 1. */
|
||||
/* { dg-final { scan-tree-dump-times "Simplified relational" 2 "vrp1" } } */
|
||||
/* { dg-final { cleanup-tree-dump "vrp1" } } */
|
||||
|
||||
|
17
gcc/testsuite/gcc.dg/tree-ssa/vrp26.c
Normal file
17
gcc/testsuite/gcc.dg/tree-ssa/vrp26.c
Normal file
@ -0,0 +1,17 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-vrp1" } */
|
||||
|
||||
int
|
||||
foo(int a)
|
||||
{
|
||||
int z = a | 1;
|
||||
return z != 0;
|
||||
}
|
||||
|
||||
/* VRP should optimize this to a trivial "return 1". */
|
||||
/* { dg-final { scan-tree-dump-times "return 1" 1 "vrp1" } } * /
|
||||
/* { dg-final { cleanup-tree-dump "vrp1" } } */
|
||||
|
||||
|
||||
|
||||
|
@ -135,17 +135,6 @@ struct expr_hash_elt
|
||||
restored during finalization of this block. */
|
||||
static VEC(tree,heap) *const_and_copies_stack;
|
||||
|
||||
/* Bitmap of SSA_NAMEs known to have a nonzero value, even if we do not
|
||||
know their exact value. */
|
||||
static bitmap nonzero_vars;
|
||||
|
||||
/* Stack of SSA_NAMEs which need their NONZERO_VARS property cleared
|
||||
when the current block is finalized.
|
||||
|
||||
A NULL entry is used to mark the end of names needing their
|
||||
entry in NONZERO_VARS cleared during finalization of this block. */
|
||||
static VEC(tree,heap) *nonzero_vars_stack;
|
||||
|
||||
/* Track whether or not we have changed the control flow graph. */
|
||||
static bool cfg_altered;
|
||||
|
||||
@ -194,8 +183,6 @@ static void propagate_to_outgoing_edges (struct dom_walk_data *, basic_block);
|
||||
static void remove_local_expressions_from_table (void);
|
||||
static void restore_vars_to_original_value (void);
|
||||
static edge single_incoming_edge_ignoring_loop_edges (basic_block);
|
||||
static void restore_nonzero_vars_to_original_value (void);
|
||||
static inline bool unsafe_associative_fp_binop (tree);
|
||||
|
||||
|
||||
/* Allocate an EDGE_INFO for edge E and attach it to E.
|
||||
@ -261,9 +248,7 @@ tree_ssa_dominator_optimize (void)
|
||||
avail_exprs = htab_create (1024, real_avail_expr_hash, avail_expr_eq, free);
|
||||
avail_exprs_stack = VEC_alloc (tree, heap, 20);
|
||||
const_and_copies_stack = VEC_alloc (tree, heap, 20);
|
||||
nonzero_vars_stack = VEC_alloc (tree, heap, 20);
|
||||
stmts_to_rescan = VEC_alloc (tree, heap, 20);
|
||||
nonzero_vars = BITMAP_ALLOC (NULL);
|
||||
need_eh_cleanup = BITMAP_ALLOC (NULL);
|
||||
|
||||
/* Setup callbacks for the generic dominator tree walker. */
|
||||
@ -367,13 +352,11 @@ tree_ssa_dominator_optimize (void)
|
||||
/* And finalize the dominator walker. */
|
||||
fini_walk_dominator_tree (&walk_data);
|
||||
|
||||
/* Free nonzero_vars. */
|
||||
BITMAP_FREE (nonzero_vars);
|
||||
/* Free asserted bitmaps and stacks. */
|
||||
BITMAP_FREE (need_eh_cleanup);
|
||||
|
||||
VEC_free (tree, heap, avail_exprs_stack);
|
||||
VEC_free (tree, heap, const_and_copies_stack);
|
||||
VEC_free (tree, heap, nonzero_vars_stack);
|
||||
VEC_free (tree, heap, stmts_to_rescan);
|
||||
}
|
||||
|
||||
@ -466,7 +449,6 @@ dom_opt_initialize_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
far to unwind when we finalize this block. */
|
||||
VEC_safe_push (tree, heap, avail_exprs_stack, NULL_TREE);
|
||||
VEC_safe_push (tree, heap, const_and_copies_stack, NULL_TREE);
|
||||
VEC_safe_push (tree, heap, nonzero_vars_stack, NULL_TREE);
|
||||
|
||||
record_equivalences_from_incoming_edge (bb);
|
||||
|
||||
@ -540,23 +522,6 @@ remove_local_expressions_from_table (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Use the SSA_NAMES in LOCALS to restore TABLE to its original
|
||||
state, stopping when there are LIMIT entries left in LOCALs. */
|
||||
|
||||
static void
|
||||
restore_nonzero_vars_to_original_value (void)
|
||||
{
|
||||
while (VEC_length (tree, nonzero_vars_stack) > 0)
|
||||
{
|
||||
tree name = VEC_pop (tree, nonzero_vars_stack);
|
||||
|
||||
if (name == NULL)
|
||||
break;
|
||||
|
||||
bitmap_clear_bit (nonzero_vars, SSA_NAME_VERSION (name));
|
||||
}
|
||||
}
|
||||
|
||||
/* Use the source/dest pairs in CONST_AND_COPIES_STACK to restore
|
||||
CONST_AND_COPIES to its original state, stopping when we hit a
|
||||
NULL marker. */
|
||||
@ -728,7 +693,6 @@ dom_opt_finalize_block (struct dom_walk_data *walk_data, basic_block bb)
|
||||
}
|
||||
|
||||
remove_local_expressions_from_table ();
|
||||
restore_nonzero_vars_to_original_value ();
|
||||
restore_vars_to_original_value ();
|
||||
|
||||
/* If we queued any statements to rescan in this block, then
|
||||
@ -750,11 +714,7 @@ dom_opt_finalize_block (struct dom_walk_data *walk_data, basic_block bb)
|
||||
|
||||
Ignoring any alternatives which are the same as the result, if
|
||||
all the alternatives are equal, then the PHI node creates an
|
||||
equivalence.
|
||||
|
||||
Additionally, if all the PHI alternatives are known to have a nonzero
|
||||
value, then the result of this PHI is known to have a nonzero value,
|
||||
even if we do not know its exact value. */
|
||||
equivalence. */
|
||||
|
||||
static void
|
||||
record_equivalences_from_phis (basic_block bb)
|
||||
@ -802,17 +762,6 @@ record_equivalences_from_phis (basic_block bb)
|
||||
if (i == PHI_NUM_ARGS (phi)
|
||||
&& may_propagate_copy (lhs, rhs))
|
||||
SSA_NAME_VALUE (lhs) = rhs;
|
||||
|
||||
/* Now see if we know anything about the nonzero property for the
|
||||
result of this PHI. */
|
||||
for (i = 0; i < PHI_NUM_ARGS (phi); i++)
|
||||
{
|
||||
if (!PHI_ARG_NONZERO (phi, i))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == PHI_NUM_ARGS (phi))
|
||||
bitmap_set_bit (nonzero_vars, SSA_NAME_VERSION (PHI_RESULT (phi)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -944,26 +893,6 @@ htab_statistics (FILE *file, htab_t htab)
|
||||
htab_collisions (htab));
|
||||
}
|
||||
|
||||
/* Record the fact that VAR has a nonzero value, though we may not know
|
||||
its exact value. Note that if VAR is already known to have a nonzero
|
||||
value, then we do nothing. */
|
||||
|
||||
static void
|
||||
record_var_is_nonzero (tree var)
|
||||
{
|
||||
int indx = SSA_NAME_VERSION (var);
|
||||
|
||||
if (bitmap_bit_p (nonzero_vars, indx))
|
||||
return;
|
||||
|
||||
/* Mark it in the global table. */
|
||||
bitmap_set_bit (nonzero_vars, indx);
|
||||
|
||||
/* Record this SSA_NAME so that we can reset the global table
|
||||
when we leave this block. */
|
||||
VEC_safe_push (tree, heap, nonzero_vars_stack, var);
|
||||
}
|
||||
|
||||
/* Enter a statement into the true/false expression hash table indicating
|
||||
that the condition COND has the value VALUE. */
|
||||
|
||||
@ -1213,19 +1142,6 @@ record_equality (tree x, tree y)
|
||||
record_const_or_copy_1 (x, y, prev_x);
|
||||
}
|
||||
|
||||
/* Return true, if it is ok to do folding of an associative expression.
|
||||
EXP is the tree for the associative expression. */
|
||||
|
||||
static inline bool
|
||||
unsafe_associative_fp_binop (tree exp)
|
||||
{
|
||||
enum tree_code code = TREE_CODE (exp);
|
||||
return !(!flag_unsafe_math_optimizations
|
||||
&& (code == MULT_EXPR || code == PLUS_EXPR
|
||||
|| code == MINUS_EXPR)
|
||||
&& FLOAT_TYPE_P (TREE_TYPE (exp)));
|
||||
}
|
||||
|
||||
/* Returns true when STMT is a simple iv increment. It detects the
|
||||
following situation:
|
||||
|
||||
@ -1269,14 +1185,11 @@ simple_iv_increment_p (tree stmt)
|
||||
/* CONST_AND_COPIES is a table which maps an SSA_NAME to the current
|
||||
known value for that SSA_NAME (or NULL if no value is known).
|
||||
|
||||
NONZERO_VARS is the set SSA_NAMES known to have a nonzero value,
|
||||
even if we don't know their precise value.
|
||||
|
||||
Propagate values from CONST_AND_COPIES and NONZERO_VARS into the PHI
|
||||
nodes of the successors of BB. */
|
||||
Propagate values from CONST_AND_COPIES into the PHI nodes of the
|
||||
successors of BB. */
|
||||
|
||||
static void
|
||||
cprop_into_successor_phis (basic_block bb, bitmap nonzero_vars)
|
||||
cprop_into_successor_phis (basic_block bb)
|
||||
{
|
||||
edge e;
|
||||
edge_iterator ei;
|
||||
@ -1309,11 +1222,6 @@ cprop_into_successor_phis (basic_block bb, bitmap nonzero_vars)
|
||||
if (TREE_CODE (orig) != SSA_NAME)
|
||||
continue;
|
||||
|
||||
/* If the alternative is known to have a nonzero value, record
|
||||
that fact in the PHI node itself for future use. */
|
||||
if (bitmap_bit_p (nonzero_vars, SSA_NAME_VERSION (orig)))
|
||||
PHI_ARG_NONZERO (phi, indx) = true;
|
||||
|
||||
/* If we have *ORIG_P in our constant/copy table, then replace
|
||||
ORIG_P with its value in our constant/copy table. */
|
||||
new = SSA_NAME_VALUE (orig);
|
||||
@ -1518,7 +1426,7 @@ propagate_to_outgoing_edges (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
|
||||
basic_block bb)
|
||||
{
|
||||
record_edge_info (bb);
|
||||
cprop_into_successor_phis (bb, nonzero_vars);
|
||||
cprop_into_successor_phis (bb);
|
||||
}
|
||||
|
||||
/* Search for redundant computations in STMT. If any are found, then
|
||||
@ -1626,7 +1534,6 @@ record_equivalences_from_stmt (tree stmt,
|
||||
{
|
||||
tree lhs = TREE_OPERAND (stmt, 0);
|
||||
enum tree_code lhs_code = TREE_CODE (lhs);
|
||||
int i;
|
||||
|
||||
if (lhs_code == SSA_NAME)
|
||||
{
|
||||
@ -1645,48 +1552,8 @@ record_equivalences_from_stmt (tree stmt,
|
||||
&& (TREE_CODE (rhs) == SSA_NAME
|
||||
|| is_gimple_min_invariant (rhs)))
|
||||
SSA_NAME_VALUE (lhs) = rhs;
|
||||
|
||||
if (tree_expr_nonzero_p (rhs))
|
||||
record_var_is_nonzero (lhs);
|
||||
}
|
||||
|
||||
/* Look at both sides for pointer dereferences. If we find one, then
|
||||
the pointer must be nonnull and we can enter that equivalence into
|
||||
the hash tables. */
|
||||
if (flag_delete_null_pointer_checks)
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
tree t = TREE_OPERAND (stmt, i);
|
||||
|
||||
/* Strip away any COMPONENT_REFs. */
|
||||
while (TREE_CODE (t) == COMPONENT_REF)
|
||||
t = TREE_OPERAND (t, 0);
|
||||
|
||||
/* Now see if this is a pointer dereference. */
|
||||
if (INDIRECT_REF_P (t))
|
||||
{
|
||||
tree op = TREE_OPERAND (t, 0);
|
||||
|
||||
/* If the pointer is a SSA variable, then enter new
|
||||
equivalences into the hash table. */
|
||||
while (TREE_CODE (op) == SSA_NAME)
|
||||
{
|
||||
tree def = SSA_NAME_DEF_STMT (op);
|
||||
|
||||
record_var_is_nonzero (op);
|
||||
|
||||
/* And walk up the USE-DEF chains noting other SSA_NAMEs
|
||||
which are known to have a nonzero value. */
|
||||
if (def
|
||||
&& TREE_CODE (def) == MODIFY_EXPR
|
||||
&& TREE_CODE (TREE_OPERAND (def, 1)) == NOP_EXPR)
|
||||
op = TREE_OPERAND (TREE_OPERAND (def, 1), 0);
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* A memory store, even an aliased store, creates a useful
|
||||
equivalence. By exchanging the LHS and RHS, creating suitable
|
||||
vops and recording the result in the available expression table,
|
||||
@ -2047,24 +1914,6 @@ lookup_avail_expr (tree stmt, bool insert)
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* If this is an equality test against zero, see if we have recorded a
|
||||
nonzero value for the variable in question. */
|
||||
if ((TREE_CODE (element->rhs) == EQ_EXPR
|
||||
|| TREE_CODE (element->rhs) == NE_EXPR)
|
||||
&& TREE_CODE (TREE_OPERAND (element->rhs, 0)) == SSA_NAME
|
||||
&& integer_zerop (TREE_OPERAND (element->rhs, 1)))
|
||||
{
|
||||
int indx = SSA_NAME_VERSION (TREE_OPERAND (element->rhs, 0));
|
||||
|
||||
if (bitmap_bit_p (nonzero_vars, indx))
|
||||
{
|
||||
tree t = element->rhs;
|
||||
free (element);
|
||||
return constant_boolean_node (TREE_CODE (t) != EQ_EXPR,
|
||||
TREE_TYPE (t));
|
||||
}
|
||||
}
|
||||
|
||||
/* Finally try to find the expression in the main expression hash table. */
|
||||
slot = htab_find_slot_with_hash (avail_exprs, element, element->hash,
|
||||
(insert ? INSERT : NO_INSERT));
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -4520,6 +4520,10 @@ extern int tree_map_eq (const void *, const void *);
|
||||
extern tree tree_mem_ref_addr (tree, tree);
|
||||
extern void copy_mem_ref_info (tree, tree);
|
||||
|
||||
/* In tree-vrp.c */
|
||||
extern bool ssa_name_nonzero_p (tree);
|
||||
extern bool ssa_name_nonnegative_p (tree);
|
||||
|
||||
/* In tree-object-size.c. */
|
||||
extern void init_object_sizes (void);
|
||||
extern void fini_object_sizes (void);
|
||||
|
Loading…
Reference in New Issue
Block a user