Split up value_range::intersect into base (value_range_base) and
derived versions (value_range). From-SVN: r272058
This commit is contained in:
parent
f32ee8a25e
commit
1ef8f50e4f
|
@ -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.
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ");
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue