aboutsummaryrefslogtreecommitdiff
path: root/gcc/value-range.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/value-range.h')
-rw-r--r--gcc/value-range.h153
1 files changed, 82 insertions, 71 deletions
diff --git a/gcc/value-range.h b/gcc/value-range.h
index 8a4d8ec..a8adc50 100644
--- a/gcc/value-range.h
+++ b/gcc/value-range.h
@@ -41,7 +41,7 @@ enum value_range_kind
//
// This is the base class without any storage.
-class irange
+class GTY((user)) irange
{
friend class irange_allocator;
public:
@@ -111,14 +111,13 @@ protected:
void irange_set (tree, tree);
void irange_set_anti_range (tree, tree);
- void normalize_min_max ();
+ void normalize_kind ();
bool legacy_mode_p () const;
bool legacy_equal_p (const irange &) const;
void legacy_union (irange *, const irange *);
void legacy_intersect (irange *, const irange *);
void verify_range ();
- unsigned legacy_num_pairs () const;
wide_int legacy_lower_bound (unsigned = 0) const;
wide_int legacy_upper_bound (unsigned) const;
int value_inside_range (tree) const;
@@ -127,6 +126,13 @@ protected:
void copy_legacy_to_multi_range (const irange &);
private:
+ friend void gt_ggc_mx (irange *);
+ friend void gt_pch_nx (irange *);
+ friend void gt_pch_nx (irange *, gt_pointer_operator, void *);
+
+ void irange_set_1bit_anti_range (tree, tree);
+ bool varying_compatible_p () const;
+
unsigned char m_num_ranges;
unsigned char m_max_ranges;
ENUM_BITFIELD(value_range_kind) m_kind : 8;
@@ -153,11 +159,10 @@ private:
template <unsigned X> friend void gt_pch_nx (int_range<X> *);
template <unsigned X> friend void gt_pch_nx (int_range<X> *,
gt_pointer_operator, void *);
- // ?? hash-traits.h has its own extern for these, which is causing
- // them to never be picked up by the templates. For now, define
- // elsewhere.
- //template<unsigned X> friend void gt_ggc_mx (int_range<X> *&);
- //template<unsigned X> friend void gt_pch_nx (int_range<X> *&);
+
+ // ?? These stubs are for ipa-prop.c which use a value_range in a
+ // hash_traits. hash-traits.h defines an extern of gt_ggc_mx (T &)
+ // instead of picking up the gt_ggc_mx (T *) version.
friend void gt_ggc_mx (int_range<1> *&);
friend void gt_pch_nx (int_range<1> *&);
@@ -196,16 +201,7 @@ extern bool vrp_operand_equal_p (const_tree, const_tree);
inline value_range_kind
irange::kind () const
{
- if (legacy_mode_p ())
- return m_kind;
-
- if (undefined_p ())
- return VR_UNDEFINED;
-
- if (varying_p ())
- return VR_VARYING;
-
- return VR_RANGE;
+ return m_kind;
}
// Number of sub-ranges in a range.
@@ -213,16 +209,16 @@ irange::kind () const
inline unsigned
irange::num_pairs () const
{
- if (!legacy_mode_p ())
- return m_num_ranges;
+ if (m_kind == VR_ANTI_RANGE)
+ return constant_p () ? 2 : 1;
else
- return legacy_num_pairs ();
+ return m_num_ranges;
}
inline tree
irange::type () const
{
- gcc_checking_assert (!undefined_p ());
+ gcc_checking_assert (m_num_ranges > 0);
return TREE_TYPE (m_base[0]);
}
@@ -269,17 +265,18 @@ irange::max () const
}
inline bool
-irange::varying_p () const
+irange::varying_compatible_p () const
{
- if (legacy_mode_p ())
- return m_kind == VR_VARYING;
-
if (m_num_ranges != 1)
return false;
tree l = m_base[0];
tree u = m_base[1];
tree t = TREE_TYPE (l);
+
+ if (m_kind == VR_VARYING && t == error_mark_node)
+ return true;
+
unsigned prec = TYPE_PRECISION (t);
signop sign = TYPE_SIGN (t);
if (INTEGRAL_TYPE_P (t))
@@ -289,22 +286,17 @@ irange::varying_p () const
return (wi::to_wide (l) == 0
&& wi::to_wide (u) == wi::max_value (prec, sign));
return true;
+}
+inline bool
+irange::varying_p () const
+{
+ return m_kind == VR_VARYING;
}
inline bool
irange::undefined_p () const
{
- if (!legacy_mode_p ())
- return m_num_ranges == 0;
-
- if (CHECKING_P && legacy_mode_p ())
- {
- if (m_kind == VR_UNDEFINED)
- gcc_checking_assert (m_num_ranges == 0);
- else
- gcc_checking_assert (m_num_ranges != 0);
- }
return m_kind == VR_UNDEFINED;
}
@@ -346,39 +338,57 @@ range_includes_zero_p (const irange *vr)
return vr->may_contain_p (build_zero_cst (vr->type ()));
}
-template<unsigned N>
inline void
-gt_ggc_mx (int_range<N> *x)
+gt_ggc_mx (irange *x)
{
- for (unsigned i = 0; i < N; ++i)
+ for (unsigned i = 0; i < x->m_num_ranges; ++i)
{
- gt_ggc_mx (x->m_ranges[i * 2]);
- gt_ggc_mx (x->m_ranges[i * 2 + 1]);
+ gt_ggc_mx (x->m_base[i * 2]);
+ gt_ggc_mx (x->m_base[i * 2 + 1]);
}
}
-template<unsigned N>
inline void
-gt_pch_nx (int_range<N> *x)
+gt_pch_nx (irange *x)
{
- for (unsigned i = 0; i < N; ++i)
+ for (unsigned i = 0; i < x->m_num_ranges; ++i)
{
- gt_pch_nx (x->m_ranges[i * 2]);
- gt_pch_nx (x->m_ranges[i * 2 + 1]);
+ gt_pch_nx (x->m_base[i * 2]);
+ gt_pch_nx (x->m_base[i * 2 + 1]);
}
}
-template<unsigned N>
inline void
-gt_pch_nx (int_range<N> *x, gt_pointer_operator op, void *cookie)
+gt_pch_nx (irange *x, gt_pointer_operator op, void *cookie)
{
- for (unsigned i = 0; i < N; ++i)
+ for (unsigned i = 0; i < x->m_num_ranges; ++i)
{
- op (&x->m_ranges[i * 2], cookie);
- op (&x->m_ranges[i * 2 + 1], cookie);
+ op (&x->m_base[i * 2], cookie);
+ op (&x->m_base[i * 2 + 1], cookie);
}
}
+template<unsigned N>
+inline void
+gt_ggc_mx (int_range<N> *x)
+{
+ gt_ggc_mx ((irange *) x);
+}
+
+template<unsigned N>
+inline void
+gt_pch_nx (int_range<N> *x)
+{
+ gt_pch_nx ((irange *) x);
+}
+
+template<unsigned N>
+inline void
+gt_pch_nx (int_range<N> *x, gt_pointer_operator op, void *cookie)
+{
+ gt_pch_nx ((irange *) x, op, cookie);
+}
+
// Constructors for irange
inline
@@ -387,10 +397,7 @@ irange::irange (tree *base, unsigned nranges)
m_base = base;
m_num_ranges = 0;
m_max_ranges = nranges;
- if (legacy_mode_p ())
- m_kind = VR_UNDEFINED;
- else
- m_kind = VR_RANGE;
+ m_kind = VR_UNDEFINED;
}
// Constructors for int_range<>.
@@ -457,18 +464,16 @@ irange::set (tree val)
inline void
irange::set_undefined ()
{
+ m_kind = VR_UNDEFINED;
m_num_ranges = 0;
- if (legacy_mode_p ())
- m_kind = VR_UNDEFINED;
}
inline void
irange::set_varying (tree type)
{
- if (legacy_mode_p ())
- m_kind = VR_VARYING;
-
+ m_kind = VR_VARYING;
m_num_ranges = 1;
+
if (INTEGRAL_TYPE_P (type))
{
wide_int min = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
@@ -499,7 +504,7 @@ irange::lower_bound (unsigned pair) const
{
if (legacy_mode_p ())
return legacy_lower_bound (pair);
- gcc_checking_assert (!undefined_p ());
+ gcc_checking_assert (m_num_ranges > 0);
gcc_checking_assert (pair + 1 <= num_pairs ());
return wi::to_wide (tree_lower_bound (pair));
}
@@ -512,7 +517,7 @@ irange::upper_bound (unsigned pair) const
{
if (legacy_mode_p ())
return legacy_upper_bound (pair);
- gcc_checking_assert (!undefined_p ());
+ gcc_checking_assert (m_num_ranges > 0);
gcc_checking_assert (pair + 1 <= num_pairs ());
return wi::to_wide (tree_upper_bound (pair));
}
@@ -572,17 +577,14 @@ irange::set_zero (tree type)
// Normalize a range to VARYING or UNDEFINED if possible.
inline void
-irange::normalize_min_max ()
-{
- gcc_checking_assert (legacy_mode_p ());
- gcc_checking_assert (!undefined_p ());
- unsigned prec = TYPE_PRECISION (type ());
- signop sign = TYPE_SIGN (type ());
- if (wi::eq_p (wi::to_wide (min ()), wi::min_value (prec, sign))
- && wi::eq_p (wi::to_wide (max ()), wi::max_value (prec, sign)))
+irange::normalize_kind ()
+{
+ if (m_num_ranges == 0)
+ m_kind = VR_UNDEFINED;
+ else if (varying_compatible_p ())
{
if (m_kind == VR_RANGE)
- set_varying (type ());
+ m_kind = VR_VARYING;
else if (m_kind == VR_ANTI_RANGE)
set_undefined ();
else
@@ -637,6 +639,7 @@ public:
// Return a copy of SRC with the minimum amount of sub-ranges needed
// to represent it.
irange *allocate (const irange &src);
+ void *get_memory (unsigned num_bytes);
private:
DISABLE_COPY_AND_ASSIGN (irange_allocator);
struct obstack m_obstack;
@@ -654,6 +657,14 @@ irange_allocator::~irange_allocator ()
obstack_free (&m_obstack, NULL);
}
+// Provide a hunk of memory from the obstack.
+inline void *
+irange_allocator::get_memory (unsigned num_bytes)
+{
+ void *r = obstack_alloc (&m_obstack, num_bytes);
+ return r;
+}
+
// Return a new range with NUM_PAIRS.
inline irange *