diff options
author | Aldy Hernandez <aldyh@redhat.com> | 2020-06-18 19:09:37 +0200 |
---|---|---|
committer | Aldy Hernandez <aldyh@redhat.com> | 2020-06-19 15:14:08 +0200 |
commit | 7cefb069fa9d631566a201ad71fa1a370ab04d17 (patch) | |
tree | b95a5a288bc963e728a8c3d266866a2f952566a4 /gcc | |
parent | 6472945db3885a749fb17073a3dee25c9839b21a (diff) | |
download | gcc-7cefb069fa9d631566a201ad71fa1a370ab04d17.zip gcc-7cefb069fa9d631566a201ad71fa1a370ab04d17.tar.gz gcc-7cefb069fa9d631566a201ad71fa1a370ab04d17.tar.bz2 |
Remove vrange as well as irange virtuals.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/value-range-equiv.cc | 39 | ||||
-rw-r--r-- | gcc/value-range-equiv.h | 20 | ||||
-rw-r--r-- | gcc/value-range.cc | 162 | ||||
-rw-r--r-- | gcc/value-range.h | 130 |
4 files changed, 164 insertions, 187 deletions
diff --git a/gcc/value-range-equiv.cc b/gcc/value-range-equiv.cc index ab90166..6d8e974 100644 --- a/gcc/value-range-equiv.cc +++ b/gcc/value-range-equiv.cc @@ -30,14 +30,14 @@ along with GCC; see the file COPYING3. If not see value_range_equiv::value_range_equiv (tree min, tree max, bitmap equiv, value_range_kind kind) { - m_discriminator = VRANGE_KIND_INT_WITH_EQUIVS; + m_discriminator = IRANGE_KIND_INT; m_equiv = NULL; set (min, max, equiv, kind); } value_range_equiv::value_range_equiv (const value_range &other) { - m_discriminator = VRANGE_KIND_INT_WITH_EQUIVS; + m_discriminator = IRANGE_KIND_INT; m_equiv = NULL; set (other.min(), other.max (), NULL, other.kind ()); } @@ -190,16 +190,8 @@ value_range_equiv::equiv_add (const_tree var, } void -value_range_equiv::intersect (const vrange &vother) +value_range_equiv::intersect (const value_range_equiv *other) { - if (!is_a <const value_range_equiv *> (&vother)) - { - irange::intersect (vother); - return; - } - const value_range_equiv *other = as_a <const value_range_equiv *> (&vother); - gcc_checking_assert (other != NULL); - if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Intersecting\n "); @@ -247,22 +239,8 @@ value_range_equiv::intersect (const vrange &vother) } void -value_range_equiv::intersect (const value_range_equiv *other) -{ - intersect (*other); -} - -void -value_range_equiv::union_ (const vrange &vother) +value_range_equiv::union_ (const value_range_equiv *other) { - if (!is_a <const value_range_equiv *> (&vother)) - { - irange::union_ (vother); - return; - } - const value_range_equiv *other = as_a <const value_range_equiv *> (&vother); - gcc_checking_assert (other != NULL); - if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Meeting\n "); @@ -278,8 +256,7 @@ value_range_equiv::union_ (const vrange &vother) this->deep_copy (other); else { - gcc_checking_assert (other->simple_ranges_p ()); - value_range tem = union_helper (this, (const value_range *) other); + value_range tem = union_helper (this, other); this->update (tem.min (), tem.max (), tem.kind ()); /* The resulting set of equivalences is always the intersection of @@ -299,12 +276,6 @@ value_range_equiv::union_ (const vrange &vother) } void -value_range_equiv::union_ (const value_range_equiv *other) -{ - union_ (*other); -} - -void value_range_equiv::dump (FILE *file) const { value_range::dump (file); diff --git a/gcc/value-range-equiv.h b/gcc/value-range-equiv.h index 7cf4bcb..1cb06d9 100644 --- a/gcc/value-range-equiv.h +++ b/gcc/value-range-equiv.h @@ -29,7 +29,7 @@ class GTY((user)) value_range_equiv : public value_range public: value_range_equiv () : value_range () { - m_discriminator = VRANGE_KIND_INT_WITH_EQUIVS; + m_discriminator = IRANGE_KIND_INT; m_equiv = NULL; } value_range_equiv (const value_range &); @@ -54,8 +54,6 @@ class GTY((user)) value_range_equiv : public value_range bool operator!= (const value_range_equiv &) const /* = delete */; void intersect (const value_range_equiv *); void union_ (const value_range_equiv *); - virtual void intersect (const vrange &); - virtual void union_ (const vrange &); bool equal_p (const value_range_equiv &, bool ignore_equivs) const; /* Types of value ranges. */ @@ -85,20 +83,4 @@ class GTY((user)) value_range_equiv : public value_range extern void dump_value_range (FILE *, const value_range_equiv *); -template <> -template <> -inline bool -is_a_helper <const value_range_equiv *>::test (const vrange *p) -{ - return p && p->m_discriminator == VRANGE_KIND_INT_WITH_EQUIVS; -} - -template <> -template <> -inline bool -is_a_helper <value_range_equiv *>::test (vrange *p) -{ - return p && p->m_discriminator == VRANGE_KIND_INT_WITH_EQUIVS; -} - #endif // GCC_VALUE_RANGE_EQUIV_H diff --git a/gcc/value-range.cc b/gcc/value-range.cc index ffe1835..b369d2b 100644 --- a/gcc/value-range.cc +++ b/gcc/value-range.cc @@ -27,36 +27,38 @@ along with GCC; see the file COPYING3. If not see #include "tree-pretty-print.h" #include "fold-const.h" -// Abstract vrange implementation. +// Here we copy between any two irange's. The ranges can be simple or +// multi-ranges, and copying between any combination works correctly. -unsigned -vrange::num_pairs () const -{ - return m_num_ranges; -} - -vrange& -vrange::operator= (const vrange &src) +irange& +irange::operator= (const irange &src) { if (compatible_copy_p (src)) copy_compatible_range (src); else if (simple_ranges_p () != src.simple_ranges_p ()) copy_simple_range (src); else - copy_incompatible_range (src); + { + set_undefined (); + union_ (src); + } return *this; } +// Return TRUE if copying SRC to THIS can be done trivially. Trivial +// copies are those that can be done by just straight up copying the +// fields, without having to squish or expand ranges (as is the case +// when copying between a simple and a multi-range). + bool -vrange::compatible_copy_p (const vrange &src) const +irange::compatible_copy_p (const irange &src) const { if (src.undefined_p () || src.varying_p ()) return true; // Symbolics may be copied straight because there's only one // representation for them. - const irange *int_range = as_a <const irange *> (&src); - if (int_range && !range_has_numeric_bounds_p (int_range)) + if (!range_has_numeric_bounds_p (&src)) return true; if (simple_ranges_p () != src.simple_ranges_p ()) @@ -65,8 +67,10 @@ vrange::compatible_copy_p (const vrange &src) const return m_max_ranges >= src.m_num_ranges; } +// Trivial copy from SRC to THIS by copying the component fields. + void -vrange::copy_compatible_range (const vrange &src) +irange::copy_compatible_range (const irange &src) { if (src.undefined_p ()) set_undefined (); @@ -84,12 +88,8 @@ vrange::copy_compatible_range (const vrange &src) } } -void -vrange::copy_incompatible_range (const vrange &src) -{ - set_undefined (); - union_ (src); -} +// Return TRUE if SRC is a multi-range that can be represented as a +// VR_ANTI_RANGE. bool irange::maybe_anti_range (const irange &src) const @@ -107,10 +107,12 @@ irange::maybe_anti_range (const irange &src) const && ub == type_max); } +// Copy between a simple and a multi-range or vice-versa. + void -irange::copy_simple_range (const vrange &vsrc) +irange::copy_simple_range (const irange &vsrc) { - const irange *src = as_a <const irange *> (&vsrc); + const irange *src = &vsrc; gcc_checking_assert (src->simple_ranges_p () != simple_ranges_p ()); if (src->undefined_p ()) @@ -144,7 +146,7 @@ irange::copy_simple_range (const vrange &vsrc) irange::irange (tree *base, unsigned nranges) { m_kind = VR_UNDEFINED; - m_discriminator = VRANGE_KIND_INT; + m_discriminator = IRANGE_KIND_INT; m_base = base; m_num_ranges = 0; m_max_ranges = nranges; @@ -152,10 +154,9 @@ irange::irange (tree *base, unsigned nranges) irange::irange (tree *base, unsigned nranges, const irange &other) { - m_discriminator = VRANGE_KIND_INT; + m_discriminator = IRANGE_KIND_INT; m_base = base; m_max_ranges = nranges; - // Uses the generic vrange copy constructor to copy without sharing. *this = other; } @@ -201,12 +202,37 @@ template<unsigned N> int_range<N>& int_range<N>::operator= (const int_range &src) { - vrange::operator= (src); + irange::operator= (src); return *this; } - + // widest_irange implementation +template <> +template <> +inline bool +is_a_helper <const irange *>::test (const irange *p) +{ + return p && (p->m_discriminator == IRANGE_KIND_INT + || p->m_discriminator == IRANGE_KIND_WIDEST_INT); +} + +template <> +template <> +inline bool +is_a_helper <const widest_irange *>::test (const irange *p) +{ + return p && p->m_discriminator == IRANGE_KIND_WIDEST_INT; +} + +template <> +template <> +inline bool +is_a_helper <widest_irange *>::test (irange *p) +{ + return p && p->m_discriminator == IRANGE_KIND_WIDEST_INT; +} + widest_irange::widest_irange () : irange (m_ranges, m_sub_ranges_in_local_storage) { @@ -218,7 +244,7 @@ widest_irange::widest_irange (const widest_irange &other) { init_widest_irange (); resize_if_needed (other.num_pairs ()); - vrange::operator= (other); + irange::operator= (other); } widest_irange::widest_irange (tree min, tree max, value_range_kind kind) @@ -251,7 +277,7 @@ widest_irange::widest_irange (const irange &other) { init_widest_irange (); resize_if_needed (other.num_pairs ()); - vrange::operator= (other); + irange::operator= (other); } widest_irange::~widest_irange () @@ -265,7 +291,7 @@ widest_irange::~widest_irange () widest_irange & widest_irange::operator= (const widest_irange &src) { - vrange::operator= (src); + irange::operator= (src); return *this; } @@ -273,6 +299,7 @@ void widest_irange::init_widest_irange () { m_blob = NULL; + m_discriminator = IRANGE_KIND_WIDEST_INT; } void @@ -281,7 +308,9 @@ widest_irange::resize_if_needed (unsigned nranges) if (m_max_ranges >= nranges) return; - // We're about to double the size. Bail if it won't fit. + // If the reallocation below will exceed the maximum number of + // ranges that fit in the m_max_ranges field, just leave things as + // they are. This is the theoreticaly max we can handle. if (nranges * 2 > sizeof (m_max_ranges) * 255) return; @@ -300,22 +329,6 @@ widest_irange::resize_if_needed (unsigned nranges) } } -void -widest_irange::union_ (const vrange &other) -{ - unsigned size = num_pairs () + other.num_pairs (); - resize_if_needed (size); - irange::union_ (other); -} - -void -widest_irange::invert () -{ - unsigned size = num_pairs () + 1; - resize_if_needed (size); - irange::invert (); -} - int widest_irange::stats_used_buckets[11]; void @@ -350,16 +363,17 @@ dump_value_range_stats (FILE *file) } void -vrange::set_undefined () +irange::set_undefined () { if (simple_ranges_p ()) m_kind = VR_UNDEFINED; - else m_kind = VR_RANGE; + else + m_kind = VR_RANGE; m_num_ranges = 0; } void -vrange::set_varying (tree type) +irange::set_varying (tree type) { if (simple_ranges_p ()) m_kind = VR_VARYING; @@ -548,6 +562,8 @@ irange::set (tree min, tree max, value_range_kind kind) check (); } +// Set range for a multi-range irange from an anti-range ~[MIN,MAX]. + void irange::multi_range_set_anti_range (tree min, tree max) { @@ -1693,6 +1709,11 @@ union_helper (const value_range *vr0, const value_range *vr1) void irange::union_ (const irange *other) { + if (widest_irange *widest = dyn_cast <widest_irange *> (this)) + { + unsigned size = num_pairs () + other->num_pairs (); + widest->resize_if_needed (size); + } if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Meeting\n "); @@ -1750,11 +1771,10 @@ private: /* Range union, but for references. */ void -irange::union_ (const vrange &vr) +irange::union_ (const irange &r) { disable_dump_details details; - const irange *other = as_a <const irange *> (&vr); - union_ (other); + union_ (&r); } void @@ -1805,13 +1825,14 @@ irange::intersect (const irange *other) /* Range intersect, but for references. */ void -irange::intersect (const vrange &vr) +irange::intersect (const irange &r) { disable_dump_details details; - const irange *other = as_a <const irange *> (&vr); - intersect (other); + intersect (&r); } +// union_ for multi-ranges. + void irange::multi_range_union (const irange &r) { @@ -1954,6 +1975,8 @@ irange::intersect_from_wide_ints (const wide_int &x, const wide_int &y) check (); } +// intersect for multi-ranges. + void irange::multi_range_intersect (const irange &r) { @@ -2006,6 +2029,14 @@ subtract_one (const wide_int &x, tree type, wi::overflow_type &overflow) void irange::invert () { + // Resize a widest_irange if needed. + if (widest_irange *widest = dyn_cast <widest_irange *> (this)) + { + unsigned size = num_pairs () + 1; + widest->resize_if_needed (size); + } + + // Handle simple ranges. if (simple_ranges_p ()) { /* We can't just invert VR_RANGE and VR_ANTI_RANGE because we may @@ -2114,6 +2145,8 @@ irange::invert () check (); } +// Dump a simple range. + void irange::simple_dump (FILE *file) const { @@ -2172,13 +2205,14 @@ dump_bound_with_infinite_markers (FILE *file, tree bound) print_generic_expr (file, bound); } +// Dump any range. + void -vrange::dump (FILE *file) const +irange::dump (FILE *file) const { - const irange *ir = as_a <const irange *> (this); - if (ir && simple_ranges_p ()) + if (simple_ranges_p ()) { - ir->simple_dump (file); + simple_dump (file); return; } if (undefined_p ()) @@ -2206,7 +2240,7 @@ vrange::dump (FILE *file) const else if (m_kind == VR_ANTI_RANGE) { gcc_checking_assert (m_num_ranges == 1); - gcc_checking_assert (!range_has_numeric_bounds_p (ir)); + gcc_checking_assert (!range_has_numeric_bounds_p (this)); tree lb = m_base[0]; tree ub = m_base[1]; fprintf (file, "~["); @@ -2220,20 +2254,20 @@ vrange::dump (FILE *file) const } void -dump_value_range (FILE *file, const vrange *vr) +dump_value_range (FILE *file, const irange *vr) { vr->dump (file); } DEBUG_FUNCTION void -debug (const vrange *vr) +debug (const irange *vr) { dump_value_range (stderr, vr); fprintf (stderr, "\n"); } DEBUG_FUNCTION void -debug (const vrange &vr) +debug (const irange &vr) { debug (&vr); } diff --git a/gcc/value-range.h b/gcc/value-range.h index 6588086..2c20445 100644 --- a/gcc/value-range.h +++ b/gcc/value-range.h @@ -35,48 +35,20 @@ enum value_range_kind VR_LAST }; -enum vrange_discriminator -{ - VRANGE_KIND_UNKNOWN, - VRANGE_KIND_INT, - VRANGE_KIND_INT_WITH_EQUIVS -}; +// Helper for is_a<> to distinguish between irange and widest_irange. -class vrange +enum irange_discriminator { -public: - unsigned num_pairs () const; - bool undefined_p () const; - bool varying_p () const; - void set_undefined (); - void set_varying (tree type); - tree type () const; - void dump (FILE * = stderr) const; - vrange& operator= (const vrange &); - virtual void union_ (const vrange &) = 0; - virtual void intersect (const vrange &) = 0; - virtual void invert () = 0; -protected: - bool simple_ranges_p () const { return m_max_ranges == 1; } -private: - bool compatible_copy_p (const vrange &) const; - void copy_compatible_range (const vrange &); - void copy_incompatible_range (const vrange &); - virtual void copy_simple_range (const vrange &) = 0; - -public: - // For is_a_helper. - enum vrange_discriminator m_discriminator; -protected: - unsigned char m_num_ranges; - unsigned char m_max_ranges; - value_range_kind m_kind; - tree *m_base; + IRANGE_KIND_UNKNOWN, + IRANGE_KIND_INT, + IRANGE_KIND_WIDEST_INT }; // Range of values that can be associated with an SSA_NAME. +// +// This is the base class without any storage. -class irange : public vrange +class irange { public: void set (tree, tree, value_range_kind = VR_RANGE); @@ -91,21 +63,28 @@ public: /* Types of value ranges. */ bool symbolic_p () const; bool constant_p () const; + bool undefined_p () const; + bool varying_p () const; + void set_varying (tree type); + void set_undefined (); void union_ (const irange *); void intersect (const irange *); - virtual void union_ (const vrange &); - virtual void intersect (const vrange &); + void union_ (const irange &); + void intersect (const irange &); + irange& operator= (const irange &); bool operator== (const irange &) const; bool operator!= (const irange &r) const { return !(*this == r); } bool equal_p (const irange &) const; /* Misc methods. */ + tree type () const; bool may_contain_p (tree) const; bool zero_p () const; bool nonzero_p () const; bool singleton_p (tree *result = NULL) const; + void dump (FILE * = stderr) const; void simple_dump (FILE *) const; static bool supports_type_p (tree); @@ -117,17 +96,18 @@ public: wide_int lower_bound (unsigned = 0) const; wide_int upper_bound (unsigned) const; wide_int upper_bound () const; - virtual void invert (); + void invert (); protected: void check (); + // Returns true for an old-school value_range with anti ranges. + bool simple_ranges_p () const { return m_max_ranges == 1; } irange (tree *, unsigned); irange (tree *, unsigned, const irange &); private: int value_inside_range (tree) const; - virtual void copy_simple_range (const vrange &); void intersect_from_wide_ints (const wide_int &, const wide_int &); bool maybe_anti_range (const irange &) const; void multi_range_set_anti_range (tree, tree); @@ -135,8 +115,23 @@ private: void multi_range_intersect (const irange &); tree tree_lower_bound (unsigned = 0) const; tree tree_upper_bound (unsigned) const; + + bool compatible_copy_p (const irange &) const; + void copy_compatible_range (const irange &); + void copy_simple_range (const irange &); + +public: + ENUM_BITFIELD(irange_discriminator) m_discriminator : 8; +protected: + unsigned char m_num_ranges; + unsigned char m_max_ranges; + ENUM_BITFIELD(value_range_kind) m_kind : 8; + + tree *m_base; }; +// int_range<N> describes an irange with N pairs of ranges. + template<unsigned N> class GTY((user)) int_range : public irange { @@ -165,6 +160,25 @@ private: tree m_ranges[N*2]; }; +// This is a special int_range<> with only one pair, plus +// VR_ANTI_RANGE magic to describe slightly more than can be described +// in one pair. It is described in the code as a "simple range" (as +// opposed to multi-ranges which have multiple sub-ranges). It is +// provided for backward compatibility with the more limited, +// traditional value_range's. +// +// simple_ranges_p() returns true for value_range's. +// +// There are copy methods to seamlessly copy to/fro multi-ranges. + +typedef int_range<1> value_range; + +// An irange with "unlimited" sub-ranges. In reality we are limited +// by the number of values that fit in an `m_num_ranges'. +// +// A widest_irange starts with a handful of sub-ranges in local +// storage and will grow into the heap as necessary. + class widest_irange : public irange { public: @@ -177,16 +191,14 @@ public: widest_irange (const irange &); ~widest_irange (); widest_irange& operator= (const widest_irange &); - - virtual void union_ (const vrange &); - virtual void invert (); + void resize_if_needed (unsigned); #if CHECKING_P static void stats_dump (FILE *); #endif + private: static const unsigned m_sub_ranges_in_local_storage = 5; void init_widest_irange (); - void resize_if_needed (unsigned); // Memory usage stats. void stats_register_use (void); @@ -196,14 +208,12 @@ private: tree m_ranges[m_sub_ranges_in_local_storage*2]; }; -typedef int_range<1> value_range; - value_range union_helper (const value_range *, const value_range *); value_range intersect_helper (const value_range *, const value_range *); extern bool range_has_numeric_bounds_p (const irange *); extern bool ranges_from_anti_range (const value_range *, value_range *, value_range *); -extern void dump_value_range (FILE *, const vrange *); +extern void dump_value_range (FILE *, const irange *); extern void dump_value_range_stats (FILE *); extern bool vrp_val_is_min (const_tree); extern bool vrp_val_is_max (const_tree); @@ -244,7 +254,7 @@ irange::kind () const } inline tree -vrange::type () const +irange::type () const { gcc_checking_assert (!undefined_p ()); return TREE_TYPE (m_base[0]); @@ -277,7 +287,7 @@ irange::max () const } inline bool -vrange::varying_p () const +irange::varying_p () const { if (simple_ranges_p ()) return m_kind == VR_VARYING; @@ -288,7 +298,7 @@ vrange::varying_p () const } inline bool -vrange::undefined_p () const +irange::undefined_p () const { if (simple_ranges_p ()) { @@ -341,26 +351,6 @@ range_includes_zero_p (const irange *vr) return vr->may_contain_p (build_zero_cst (vr->type ())); } -template <> -template <> -inline bool -is_a_helper <const irange *>::test (const vrange *p) -{ - return p - && (p->m_discriminator == VRANGE_KIND_INT - || p->m_discriminator == VRANGE_KIND_INT_WITH_EQUIVS); -} - -template <> -template <> -inline bool -is_a_helper <irange *>::test (vrange *p) -{ - return p - && (p->m_discriminator == VRANGE_KIND_INT - || p->m_discriminator == VRANGE_KIND_INT_WITH_EQUIVS); -} - template<unsigned N> static inline void gt_ggc_mx (int_range<N> *x) |