Split up value_range::intersect into base (value_range_base) and

derived versions (value_range).

From-SVN: r272058
This commit is contained in:
Aldy Hernandez 2019-06-07 22:18:24 +00:00 committed by Aldy Hernandez
parent f32ee8a25e
commit 1ef8f50e4f
6 changed files with 89 additions and 39 deletions

View File

@ -1,3 +1,19 @@
2019-06-07 Aldy Hernandez <aldyh@redhat.com>
* tree-vrp.h (value_range_base::intersect): New.
(value_range::intersect_helper): Move from here...
(value_range_base::intersect_helper): ...to here.
* tree-vrp.c (value_range::intersect_helper): Rename to...
(value_range_base::intersect_helper): ...this, and rewrite to
return a value instead of modifying THIS in place.
Also, move equivalence handling...
(value_range::intersect): ...here, while calling intersect_helper.
* gimple-fold.c (size_must_be_zero_p): Use value_range_base when
calling intersect.
* gimple-ssa-evrp-analyze.c (ecord_ranges_from_incoming_edge):
Same.
* vr-values.c (vrp_evaluate_conditional_warnv_with_ops): Same.
2019-06-07 Jakub Jelinek <jakub@redhat.com>
* Makefile.in (genprogerr): Add condmd.

View File

@ -684,10 +684,10 @@ size_must_be_zero_p (tree size)
/* Compute the value of SSIZE_MAX, the largest positive value that
can be stored in ssize_t, the signed counterpart of size_t. */
wide_int ssize_max = wi::lshift (wi::one (prec), prec - 1) - 1;
value_range valid_range (VR_RANGE,
build_int_cst (type, 0),
wide_int_to_tree (type, ssize_max));
value_range vr;
value_range_base valid_range (VR_RANGE,
build_int_cst (type, 0),
wide_int_to_tree (type, ssize_max));
value_range_base vr;
get_range_info (size, vr);
vr.intersect (&valid_range);
return vr.zero_p ();

View File

@ -210,9 +210,10 @@ evrp_range_analyzer::record_ranges_from_incoming_edge (basic_block bb)
getting first [64, +INF] and then ~[0, 0] from
conditions like (s & 0x3cc0) == 0). */
value_range *old_vr = get_value_range (vrs[i].first);
value_range tem (old_vr->kind (), old_vr->min (), old_vr->max ());
value_range_base tem (old_vr->kind (), old_vr->min (),
old_vr->max ());
tem.intersect (vrs[i].second);
if (tem.equal_p (*old_vr, /*ignore_equivs=*/true))
if (tem.equal_p (*old_vr))
continue;
push_value_range (vrs[i].first, vrs[i].second);
if (is_fallthru

View File

@ -6020,30 +6020,26 @@ intersect_ranges (enum value_range_kind *vr0type,
}
/* Intersect the two value-ranges *VR0 and *VR1 and store the result
in *VR0. This may not be the smallest possible such range. */
/* Helper for the intersection operation for value ranges. Given two
value ranges VR0 and VR1, return the intersection of the two
ranges. This may not be the smallest possible such range. */
void
value_range::intersect_helper (value_range *vr0, const value_range *vr1)
value_range_base
value_range_base::intersect_helper (const value_range_base *vr0,
const value_range_base *vr1)
{
/* If either range is VR_VARYING the other one wins. */
if (vr1->varying_p ())
return;
return *vr0;
if (vr0->varying_p ())
{
vr0->deep_copy (vr1);
return;
}
return *vr1;
/* When either range is VR_UNDEFINED the resulting range is
VR_UNDEFINED, too. */
if (vr0->undefined_p ())
return;
return *vr0;
if (vr1->undefined_p ())
{
vr0->set_undefined ();
return;
}
return *vr1;
value_range_kind vr0type = vr0->kind ();
tree vr0min = vr0->min ();
@ -6053,28 +6049,34 @@ value_range::intersect_helper (value_range *vr0, const value_range *vr1)
/* Make sure to canonicalize the result though as the inversion of a
VR_RANGE can still be a VR_RANGE. Work on a temporary so we can
fall back to vr0 when this turns things to varying. */
value_range tem;
value_range_base tem;
tem.set_and_canonicalize (vr0type, vr0min, vr0max);
/* If that failed, use the saved original VR0. */
if (tem.varying_p ())
return;
vr0->update (tem.kind (), tem.min (), tem.max ());
return *vr0;
/* If the result is VR_UNDEFINED there is no need to mess with
the equivalencies. */
if (vr0->undefined_p ())
return;
return tem;
}
/* The resulting set of equivalences for range intersection is the union of
the two sets. */
if (vr0->m_equiv && vr1->m_equiv && vr0->m_equiv != vr1->m_equiv)
bitmap_ior_into (vr0->m_equiv, vr1->m_equiv);
else if (vr1->m_equiv && !vr0->m_equiv)
void
value_range_base::intersect (const value_range_base *other)
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
/* All equivalence bitmaps are allocated from the same obstack. So
we can use the obstack associated with VR to allocate vr0->equiv. */
vr0->m_equiv = BITMAP_ALLOC (vr1->m_equiv->obstack);
bitmap_copy (m_equiv, vr1->m_equiv);
fprintf (dump_file, "Intersecting\n ");
dump_value_range (dump_file, this);
fprintf (dump_file, "\nand\n ");
dump_value_range (dump_file, other);
fprintf (dump_file, "\n");
}
*this = intersect_helper (this, other);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "to\n ");
dump_value_range (dump_file, this);
fprintf (dump_file, "\n");
}
}
@ -6089,7 +6091,36 @@ value_range::intersect (const value_range *other)
dump_value_range (dump_file, other);
fprintf (dump_file, "\n");
}
intersect_helper (this, other);
/* If THIS is varying we want to pick up equivalences from OTHER.
Just special-case this here rather than trying to fixup after the
fact. */
if (this->varying_p ())
this->deep_copy (other);
else
{
value_range_base tem = intersect_helper (this, other);
this->update (tem.kind (), tem.min (), tem.max ());
/* If the result is VR_UNDEFINED there is no need to mess with
equivalencies. */
if (!undefined_p ())
{
/* The resulting set of equivalences for range intersection
is the union of the two sets. */
if (m_equiv && other->m_equiv && m_equiv != other->m_equiv)
bitmap_ior_into (m_equiv, other->m_equiv);
else if (other->m_equiv && !m_equiv)
{
/* All equivalence bitmaps are allocated from the same
obstack. So we can use the obstack associated with
VR to allocate this->m_equiv. */
m_equiv = BITMAP_ALLOC (other->m_equiv->obstack);
bitmap_copy (m_equiv, other->m_equiv);
}
}
}
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "to\n ");

View File

@ -62,6 +62,7 @@ public:
void set_undefined ();
void union_ (const value_range_base *);
void intersect (const value_range_base *);
bool operator== (const value_range_base &) const /* = delete */;
bool operator!= (const value_range_base &) const /* = delete */;
@ -80,6 +81,8 @@ protected:
void check ();
static value_range_base union_helper (const value_range_base *,
const value_range_base *);
static value_range_base intersect_helper (const value_range_base *,
const value_range_base *);
enum value_range_kind m_kind;
@ -144,7 +147,6 @@ class GTY((user)) value_range : public value_range_base
/* Deep-copies bitmap argument. */
void set_equiv (bitmap);
void check ();
void intersect_helper (value_range *, const value_range *);
/* Set of SSA names whose value ranges are equivalent to this one.
This set is only valid when TYPE is VR_RANGE or VR_ANTI_RANGE. */

View File

@ -2357,7 +2357,7 @@ vr_values::vrp_evaluate_conditional_warnv_with_ops (enum tree_code code,
}
else
{
value_range vro, vri;
value_range_base vro, vri;
if (code == GT_EXPR || code == GE_EXPR)
{
vro.set (VR_ANTI_RANGE, TYPE_MIN_VALUE (TREE_TYPE (op0)), x);