diff options
-rw-r--r-- | gcc/value-range.cc | 175 | ||||
-rw-r--r-- | gcc/value-range.h | 44 |
2 files changed, 106 insertions, 113 deletions
diff --git a/gcc/value-range.cc b/gcc/value-range.cc index c4bcb97..815cb78 100644 --- a/gcc/value-range.cc +++ b/gcc/value-range.cc @@ -66,176 +66,183 @@ debug (const Value_Range &r) fprintf (stderr, "\n"); } -// Default implementation when none has been defined. +// Default vrange definitions. bool vrange::contains_p (tree) const { - return false; + return varying_p (); } -// Default implementation when none has been defined. - bool vrange::singleton_p (tree *) const { return false; } -// Assignment operator for generic ranges. Copying incompatible types -// is not allowed. - -vrange & -vrange::operator= (const vrange &src) +void +vrange::set (tree, tree, value_range_kind) { - if (is_a <irange> (src)) - { - as_a <irange> (*this) = as_a <irange> (src); - return *this; - } - else - gcc_unreachable (); } -// Equality operator for generic ranges. - -bool -vrange::operator== (const vrange &src) const +tree +vrange::type () const { - if (is_a <irange> (src)) - return as_a <irange> (*this) == as_a <irange> (src); - gcc_unreachable (); + return void_type_node; } bool -irange::supports_type_p (tree type) const +vrange::supports_type_p (tree) const { - return supports_p (type); + return false; } -// Return TRUE if R fits in THIS. - -bool -irange::fits_p (const vrange &r) const +void +vrange::set_undefined () { - return m_max_ranges >= as_a <irange> (r).num_pairs (); + m_kind = VR_UNDEFINED; } void -irange::set_nonnegative (tree type) +vrange::set_varying (tree) { - set (build_int_cst (type, 0), TYPE_MAX_VALUE (type)); + m_kind = VR_VARYING; } -unsupported_range::unsupported_range () +bool +vrange::union_ (const vrange &r) { - m_discriminator = VR_UNKNOWN; - set_undefined (); + if (r.undefined_p () || varying_p ()) + return false; + if (undefined_p () || r.varying_p ()) + { + operator= (r); + return true; + } + gcc_unreachable (); + return false; } -void -unsupported_range::set (tree, tree, value_range_kind) +bool +vrange::intersect (const vrange &r) { + if (undefined_p () || r.varying_p ()) + return false; + if (r.undefined_p ()) + { + set_undefined (); + return true; + } + if (varying_p ()) + { + operator= (r); + return true; + } gcc_unreachable (); + return false; } -tree -unsupported_range::type () const +bool +vrange::zero_p () const { - gcc_unreachable (); - return nullptr; + return false; } bool -unsupported_range::supports_type_p (tree) const +vrange::nonzero_p () const { return false; } void -unsupported_range::set_undefined () +vrange::set_nonzero (tree) { - m_kind = VR_UNDEFINED; } void -unsupported_range::set_varying (tree) +vrange::set_zero (tree) { - gcc_unreachable (); } void -unsupported_range::dump (FILE *file) const +vrange::set_nonnegative (tree) { - fprintf (file, "[unsupported_range] "); - if (undefined_p ()) - { - fprintf (file, "UNDEFINED"); - return; - } - if (varying_p ()) - { - fprintf (file, "VARYING"); - return; - } - gcc_unreachable (); } bool -unsupported_range::union_ (const vrange &) +vrange::fits_p (const vrange &) const { - gcc_unreachable (); - return false; + return true; } -bool -unsupported_range::intersect (const vrange &) +// Assignment operator for generic ranges. Copying incompatible types +// is not allowed. + +vrange & +vrange::operator= (const vrange &src) { - gcc_unreachable (); - return false; + if (is_a <irange> (src)) + { + as_a <irange> (*this) = as_a <irange> (src); + return *this; + } + else + gcc_unreachable (); } +// Equality operator for generic ranges. + bool -unsupported_range::zero_p () const +vrange::operator== (const vrange &src) const { + if (is_a <irange> (src)) + return as_a <irange> (*this) == as_a <irange> (src); gcc_unreachable (); - return false; } bool -unsupported_range::nonzero_p () const +irange::supports_type_p (tree type) const { - gcc_unreachable (); - return false; + return supports_p (type); } -void -unsupported_range::set_nonzero (tree) +// Return TRUE if R fits in THIS. + +bool +irange::fits_p (const vrange &r) const { - gcc_unreachable (); + return m_max_ranges >= as_a <irange> (r).num_pairs (); } void -unsupported_range::set_zero (tree) +irange::set_nonnegative (tree type) { - gcc_unreachable (); + set (build_int_cst (type, 0), TYPE_MAX_VALUE (type)); } -void -unsupported_range::set_nonnegative (tree) +unsupported_range::unsupported_range () { - gcc_unreachable (); + m_discriminator = VR_UNKNOWN; + set_undefined (); } -bool -unsupported_range::fits_p (const vrange &) const +void +unsupported_range::dump (FILE *file) const { + fprintf (file, "[unsupported_range] "); + if (undefined_p ()) + { + fprintf (file, "UNDEFINED"); + return; + } + if (varying_p ()) + { + fprintf (file, "VARYING"); + return; + } gcc_unreachable (); - return false; } -unsupported_range Value_Range::m_unsupported; - // Here we copy between any two irange's. The ranges can be legacy or // multi-ranges, and copying between any combination works correctly. diff --git a/gcc/value-range.h b/gcc/value-range.h index 69cf6c3..61e6a18 100644 --- a/gcc/value-range.h +++ b/gcc/value-range.h @@ -73,22 +73,22 @@ class vrange template <typename T> friend bool is_a (vrange &); friend class Value_Range; public: - virtual void set (tree, tree, value_range_kind = VR_RANGE) = 0; - virtual tree type () const = 0; - virtual bool supports_type_p (tree type) const = 0; - virtual void set_varying (tree type) = 0; - virtual void set_undefined () = 0; + virtual void set (tree, tree, value_range_kind = VR_RANGE); + virtual tree type () const; + virtual bool supports_type_p (tree type) const; + virtual void set_varying (tree type); + virtual void set_undefined (); virtual void dump (FILE * = stderr) const = 0; - virtual bool union_ (const vrange &) = 0; - virtual bool intersect (const vrange &) = 0; + virtual bool union_ (const vrange &); + virtual bool intersect (const vrange &); virtual bool singleton_p (tree *result = NULL) const; virtual bool contains_p (tree cst) const; - virtual bool zero_p () const = 0; - virtual bool nonzero_p () const = 0; - virtual void set_nonzero (tree type) = 0; - virtual void set_zero (tree type) = 0; - virtual void set_nonnegative (tree type) = 0; - virtual bool fits_p (const vrange &r) const = 0; + virtual bool zero_p () const; + virtual bool nonzero_p () const; + virtual void set_nonzero (tree type); + virtual void set_zero (tree type); + virtual void set_nonnegative (tree type); + virtual bool fits_p (const vrange &r) const; bool varying_p () const; bool undefined_p () const; @@ -236,27 +236,13 @@ private: }; // Unsupported temporaries may be created by ranger before it's known -// they're unsupported, or by vr_values::get_value_range. All -// operations except construction cause a trap. +// they're unsupported, or by vr_values::get_value_range. class unsupported_range : public vrange { public: unsupported_range (); - virtual void set (tree, tree, value_range_kind) override; - virtual tree type () const override; - virtual bool supports_type_p (tree type) const override; - virtual void set_varying (tree type) override; - virtual void set_undefined () override; virtual void dump (FILE *) const override; - virtual bool union_ (const vrange &) override; - virtual bool intersect (const vrange &) override; - virtual bool zero_p () const override; - virtual bool nonzero_p () const override; - virtual void set_nonzero (tree) override; - virtual void set_zero (tree) override; - virtual void set_nonnegative (tree) override; - virtual bool fits_p (const vrange &) const override; }; // Traits to implement vrange is_a<> and as_a<>. @@ -369,7 +355,7 @@ public: wide_int upper_bound () const; // For irange/prange compatability. private: void init (tree type); - static unsupported_range m_unsupported; + unsupported_range m_unsupported; vrange *m_vrange; int_range_max m_irange; DISABLE_COPY_AND_ASSIGN (Value_Range); |