+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.
/* 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 ();
}
-/* 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 ();
/* 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");
}
}
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 ");
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 */;
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;
/* 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. */