Commit f5052e29 by Richard Guenther Committed by Richard Biener

tree-vrp.c (set_value_range): Do not allocate equiv bitmap if it is not about to be set.

2007-05-01  Richard Guenther  <rguenther@suse.de>

	* tree-vrp.c (set_value_range): Do not allocate equiv bitmap
	if it is not about to be set.
	(get_value_range): Do not pre-allocate equiv bitmap.
	(update_value_range): No need to clear equiv field.
	(add_equivalence): Change prototype to get bitmap pointer.
	Allocate bitmap here if it is not already.
	(extract_range_from_assert): Do not allocate bitmap here.
	Update callers to add_equivalence.
	(extract_range_from_ssa_name): Likewise.
	(get_vr_for_comparison): New static helper.
	(compare_name_with_value): Handle NULL equiv bitmap by
	peeling the first iteration of the comparison loop.
	Use get_vr_for_comparison.
	(compare_names): Handle NULL equiv bitmaps by using fake
	ones.  Use get_vr_for_comparison.

From-SVN: r124321
parent 42b5a16d
2007-05-01 Richard Guenther <rguenther@suse.de>
* tree-vrp.c (set_value_range): Do not allocate equiv bitmap
if it is not about to be set.
(get_value_range): Do not pre-allocate equiv bitmap.
(update_value_range): No need to clear equiv field.
(add_equivalence): Change prototype to get bitmap pointer.
Allocate bitmap here if it is not already.
(extract_range_from_assert): Do not allocate bitmap here.
Update callers to add_equivalence.
(extract_range_from_ssa_name): Likewise.
(get_vr_for_comparison): New static helper.
(compare_name_with_value): Handle NULL equiv bitmap by
peeling the first iteration of the comparison loop.
Use get_vr_for_comparison.
(compare_names): Handle NULL equiv bitmaps by using fake
ones. Use get_vr_for_comparison.
2007-04-30 Brooks Moses <brooks.moses@codesourcery.com> 2007-04-30 Brooks Moses <brooks.moses@codesourcery.com>
* double-int.c (mpz_set_double_int): Moved from * double-int.c (mpz_set_double_int): Moved from
......
...@@ -291,7 +291,8 @@ set_value_range (value_range_t *vr, enum value_range_type t, tree min, ...@@ -291,7 +291,8 @@ set_value_range (value_range_t *vr, enum value_range_type t, tree min,
/* Since updating the equivalence set involves deep copying the /* Since updating the equivalence set involves deep copying the
bitmaps, only do it if absolutely necessary. */ bitmaps, only do it if absolutely necessary. */
if (vr->equiv == NULL) if (vr->equiv == NULL
&& equiv != NULL)
vr->equiv = BITMAP_ALLOC (NULL); vr->equiv = BITMAP_ALLOC (NULL);
if (equiv != vr->equiv) if (equiv != vr->equiv)
...@@ -436,8 +437,8 @@ get_value_range (tree var) ...@@ -436,8 +437,8 @@ get_value_range (tree var)
/* Create a default value range. */ /* Create a default value range. */
vr_value[ver] = vr = XCNEW (value_range_t); vr_value[ver] = vr = XCNEW (value_range_t);
/* Allocate an equivalence set. */ /* Defer allocating the equivalence set. */
vr->equiv = BITMAP_ALLOC (NULL); vr->equiv = NULL;
/* If VAR is a default definition, the variable can take any value /* If VAR is a default definition, the variable can take any value
in VAR's type. */ in VAR's type. */
...@@ -510,23 +511,25 @@ update_value_range (tree var, value_range_t *new_vr) ...@@ -510,23 +511,25 @@ update_value_range (tree var, value_range_t *new_vr)
new_vr->equiv); new_vr->equiv);
BITMAP_FREE (new_vr->equiv); BITMAP_FREE (new_vr->equiv);
new_vr->equiv = NULL;
return is_new; return is_new;
} }
/* Add VAR and VAR's equivalence set to EQUIV. */ /* Add VAR and VAR's equivalence set to EQUIV. This is the central
point where equivalence processing can be turned on/off. */
static void static void
add_equivalence (bitmap equiv, tree var) add_equivalence (bitmap *equiv, tree var)
{ {
unsigned ver = SSA_NAME_VERSION (var); unsigned ver = SSA_NAME_VERSION (var);
value_range_t *vr = vr_value[ver]; value_range_t *vr = vr_value[ver];
bitmap_set_bit (equiv, ver); if (*equiv == NULL)
*equiv = BITMAP_ALLOC (NULL);
bitmap_set_bit (*equiv, ver);
if (vr && vr->equiv) if (vr && vr->equiv)
bitmap_ior_into (equiv, vr->equiv); bitmap_ior_into (*equiv, vr->equiv);
} }
...@@ -1095,8 +1098,7 @@ extract_range_from_assert (value_range_t *vr_p, tree expr) ...@@ -1095,8 +1098,7 @@ extract_range_from_assert (value_range_t *vr_p, tree expr)
predicates, we will need to trim the set of equivalences before predicates, we will need to trim the set of equivalences before
we are done. */ we are done. */
gcc_assert (vr_p->equiv == NULL); gcc_assert (vr_p->equiv == NULL);
vr_p->equiv = BITMAP_ALLOC (NULL); add_equivalence (&vr_p->equiv, var);
add_equivalence (vr_p->equiv, var);
/* Extract a new range based on the asserted comparison for VAR and /* Extract a new range based on the asserted comparison for VAR and
LIMIT's value range. Notice that if LIMIT has an anti-range, we LIMIT's value range. Notice that if LIMIT has an anti-range, we
...@@ -1130,7 +1132,7 @@ extract_range_from_assert (value_range_t *vr_p, tree expr) ...@@ -1130,7 +1132,7 @@ extract_range_from_assert (value_range_t *vr_p, tree expr)
SSA name, the new range will also inherit the equivalence set SSA name, the new range will also inherit the equivalence set
from LIMIT. */ from LIMIT. */
if (TREE_CODE (limit) == SSA_NAME) if (TREE_CODE (limit) == SSA_NAME)
add_equivalence (vr_p->equiv, limit); add_equivalence (&vr_p->equiv, limit);
} }
else if (cond_code == NE_EXPR) else if (cond_code == NE_EXPR)
{ {
...@@ -1478,7 +1480,7 @@ extract_range_from_ssa_name (value_range_t *vr, tree var) ...@@ -1478,7 +1480,7 @@ extract_range_from_ssa_name (value_range_t *vr, tree var)
else else
set_value_range (vr, VR_RANGE, var, var, NULL); set_value_range (vr, VR_RANGE, var, var, NULL);
add_equivalence (vr->equiv, var); add_equivalence (&vr->equiv, var);
} }
...@@ -4582,6 +4584,27 @@ vrp_visit_assignment (tree stmt, tree *output_p) ...@@ -4582,6 +4584,27 @@ vrp_visit_assignment (tree stmt, tree *output_p)
return SSA_PROP_VARYING; return SSA_PROP_VARYING;
} }
/* Helper that gets the value range of the SSA_NAME with version I
or a symbolic range contaning the SSA_NAME only if the value range
is varying or undefined. */
static inline value_range_t
get_vr_for_comparison (int i)
{
value_range_t vr = *(vr_value[i]);
/* If name N_i does not have a valid range, use N_i as its own
range. This allows us to compare against names that may
have N_i in their ranges. */
if (vr.type == VR_VARYING || vr.type == VR_UNDEFINED)
{
vr.type = VR_RANGE;
vr.min = ssa_name (i);
vr.max = ssa_name (i);
}
return vr;
}
/* Compare all the value ranges for names equivalent to VAR with VAL /* Compare all the value ranges for names equivalent to VAR with VAL
using comparison code COMP. Return the same value returned by using comparison code COMP. Return the same value returned by
...@@ -4597,37 +4620,35 @@ compare_name_with_value (enum tree_code comp, tree var, tree val, ...@@ -4597,37 +4620,35 @@ compare_name_with_value (enum tree_code comp, tree var, tree val,
bitmap e; bitmap e;
tree retval, t; tree retval, t;
int used_strict_overflow; int used_strict_overflow;
bool sop;
t = retval = NULL_TREE; value_range_t equiv_vr;
/* Get the set of equivalences for VAR. */ /* Get the set of equivalences for VAR. */
e = get_value_range (var)->equiv; e = get_value_range (var)->equiv;
/* Add VAR to its own set of equivalences so that VAR's value range
is processed by this loop (otherwise, we would have to replicate
the body of the loop just to check VAR's value range). */
bitmap_set_bit (e, SSA_NAME_VERSION (var));
/* Start at -1. Set it to 0 if we do a comparison without relying /* Start at -1. Set it to 0 if we do a comparison without relying
on overflow, or 1 if all comparisons rely on overflow. */ on overflow, or 1 if all comparisons rely on overflow. */
used_strict_overflow = -1; used_strict_overflow = -1;
EXECUTE_IF_SET_IN_BITMAP (e, 0, i, bi) /* Compare vars' value range with val. */
{ equiv_vr = get_vr_for_comparison (SSA_NAME_VERSION (var));
bool sop; sop = false;
retval = compare_range_with_value (comp, &equiv_vr, val, &sop);
value_range_t equiv_vr = *(vr_value[i]); if (sop)
used_strict_overflow = 1;
/* If name N_i does not have a valid range, use N_i as its own /* If the equiv set is empty we have done all work we need to do. */
range. This allows us to compare against names that may if (e == NULL)
have N_i in their ranges. */
if (equiv_vr.type == VR_VARYING || equiv_vr.type == VR_UNDEFINED)
{ {
equiv_vr.type = VR_RANGE; if (retval
equiv_vr.min = ssa_name (i); && used_strict_overflow > 0)
equiv_vr.max = ssa_name (i); *strict_overflow_p = true;
return retval;
} }
EXECUTE_IF_SET_IN_BITMAP (e, 0, i, bi)
{
equiv_vr = get_vr_for_comparison (i);
sop = false; sop = false;
t = compare_range_with_value (comp, &equiv_vr, val, &sop); t = compare_range_with_value (comp, &equiv_vr, val, &sop);
if (t) if (t)
...@@ -4651,18 +4672,11 @@ compare_name_with_value (enum tree_code comp, tree var, tree val, ...@@ -4651,18 +4672,11 @@ compare_name_with_value (enum tree_code comp, tree var, tree val,
} }
} }
/* Remove VAR from its own equivalence set. */ if (retval
bitmap_clear_bit (e, SSA_NAME_VERSION (var)); && used_strict_overflow > 0)
if (retval)
{
if (used_strict_overflow > 0)
*strict_overflow_p = true; *strict_overflow_p = true;
return retval;
}
/* We couldn't find a non-NULL value for the predicate. */ return retval;
return NULL_TREE;
} }
...@@ -4682,12 +4696,27 @@ compare_names (enum tree_code comp, tree n1, tree n2, ...@@ -4682,12 +4696,27 @@ compare_names (enum tree_code comp, tree n1, tree n2,
bitmap_iterator bi1, bi2; bitmap_iterator bi1, bi2;
unsigned i1, i2; unsigned i1, i2;
int used_strict_overflow; int used_strict_overflow;
static bitmap_obstack *s_obstack = NULL;
static bitmap s_e1 = NULL, s_e2 = NULL;
/* Compare the ranges of every name equivalent to N1 against the /* Compare the ranges of every name equivalent to N1 against the
ranges of every name equivalent to N2. */ ranges of every name equivalent to N2. */
e1 = get_value_range (n1)->equiv; e1 = get_value_range (n1)->equiv;
e2 = get_value_range (n2)->equiv; e2 = get_value_range (n2)->equiv;
/* Use the fake bitmaps if e1 or e2 are not available. */
if (s_obstack == NULL)
{
s_obstack = XNEW (bitmap_obstack);
bitmap_obstack_initialize (s_obstack);
s_e1 = BITMAP_ALLOC (s_obstack);
s_e2 = BITMAP_ALLOC (s_obstack);
}
if (e1 == NULL)
e1 = s_e1;
if (e2 == NULL)
e2 = s_e2;
/* Add N1 and N2 to their own set of equivalences to avoid /* Add N1 and N2 to their own set of equivalences to avoid
duplicating the body of the loop just to check N1 and N2 duplicating the body of the loop just to check N1 and N2
ranges. */ ranges. */
...@@ -4715,29 +4744,14 @@ compare_names (enum tree_code comp, tree n1, tree n2, ...@@ -4715,29 +4744,14 @@ compare_names (enum tree_code comp, tree n1, tree n2,
of the loop just to check N1 and N2 ranges. */ of the loop just to check N1 and N2 ranges. */
EXECUTE_IF_SET_IN_BITMAP (e1, 0, i1, bi1) EXECUTE_IF_SET_IN_BITMAP (e1, 0, i1, bi1)
{ {
value_range_t vr1 = *(vr_value[i1]); value_range_t vr1 = get_vr_for_comparison (i1);
/* If the range is VARYING or UNDEFINED, use the name itself. */
if (vr1.type == VR_VARYING || vr1.type == VR_UNDEFINED)
{
vr1.type = VR_RANGE;
vr1.min = ssa_name (i1);
vr1.max = ssa_name (i1);
}
t = retval = NULL_TREE; t = retval = NULL_TREE;
EXECUTE_IF_SET_IN_BITMAP (e2, 0, i2, bi2) EXECUTE_IF_SET_IN_BITMAP (e2, 0, i2, bi2)
{ {
bool sop; bool sop;
value_range_t vr2 = *(vr_value[i2]); value_range_t vr2 = get_vr_for_comparison (i2);
if (vr2.type == VR_VARYING || vr2.type == VR_UNDEFINED)
{
vr2.type = VR_RANGE;
vr2.min = ssa_name (i2);
vr2.max = ssa_name (i2);
}
t = compare_ranges (comp, &vr1, &vr2, &sop); t = compare_ranges (comp, &vr1, &vr2, &sop);
if (t) if (t)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment