diff options
author | Aldy Hernandez <aldyh@redhat.com> | 2024-04-22 13:34:48 +0200 |
---|---|---|
committer | Aldy Hernandez <aldyh@redhat.com> | 2024-04-28 21:03:00 +0200 |
commit | ba1a8e8eed963c0253c6e5550c8bccc264c5d469 (patch) | |
tree | 81025048edd9a42891256be60f5b6be7967699c1 /gcc | |
parent | a46564e4876c9a863d9897d72963cc4f03689adc (diff) | |
download | gcc-ba1a8e8eed963c0253c6e5550c8bccc264c5d469.zip gcc-ba1a8e8eed963c0253c6e5550c8bccc264c5d469.tar.gz gcc-ba1a8e8eed963c0253c6e5550c8bccc264c5d469.tar.bz2 |
Add tree versions of lower and upper bounds to vrange.
This patch adds vrange::lbound() and vrange::ubound() that return
trees. These can be used in generic code that is type agnostic, and
avoids special casing for pointers and integers in places where we
handle both. It also cleans up a wart in the Value_Range class.
gcc/ChangeLog:
* tree-ssa-loop-niter.cc (refine_value_range_using_guard): Convert
bound to wide_int.
* value-range.cc (Value_Range::lower_bound): Remove.
(Value_Range::upper_bound): Remove.
(unsupported_range::lbound): New.
(unsupported_range::ubound): New.
(frange::lbound): New.
(frange::ubound): New.
(irange::lbound): New.
(irange::ubound): New.
* value-range.h (class vrange): Add lbound() and ubound().
(class irange): Same.
(class frange): Same.
(class unsupported_range): Same.
(class Value_Range): Rename lower_bound and upper_bound to lbound
and ubound respectively.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/tree-ssa-loop-niter.cc | 4 | ||||
-rw-r--r-- | gcc/value-range.cc | 56 | ||||
-rw-r--r-- | gcc/value-range.h | 13 |
3 files changed, 48 insertions, 25 deletions
diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc index cbc9dbc..adbc193 100644 --- a/gcc/tree-ssa-loop-niter.cc +++ b/gcc/tree-ssa-loop-niter.cc @@ -4067,7 +4067,7 @@ record_nonwrapping_iv (class loop *loop, tree base, tree step, gimple *stmt, Value_Range base_range (TREE_TYPE (orig_base)); if (get_range_query (cfun)->range_of_expr (base_range, orig_base) && !base_range.undefined_p ()) - max = base_range.upper_bound (); + max = wi::to_wide (base_range.ubound ()); extreme = fold_convert (unsigned_type, low); if (TREE_CODE (orig_base) == SSA_NAME && TREE_CODE (high) == INTEGER_CST @@ -4090,7 +4090,7 @@ record_nonwrapping_iv (class loop *loop, tree base, tree step, gimple *stmt, Value_Range base_range (TREE_TYPE (orig_base)); if (get_range_query (cfun)->range_of_expr (base_range, orig_base) && !base_range.undefined_p ()) - min = base_range.lower_bound (); + min = wi::to_wide (base_range.lbound ()); extreme = fold_convert (unsigned_type, high); if (TREE_CODE (orig_base) == SSA_NAME && TREE_CODE (low) == INTEGER_CST diff --git a/gcc/value-range.cc b/gcc/value-range.cc index 632d773..ccac517 100644 --- a/gcc/value-range.cc +++ b/gcc/value-range.cc @@ -37,26 +37,6 @@ irange::accept (const vrange_visitor &v) const v.visit (*this); } -// Convenience function only available for integers and pointers. - -wide_int -Value_Range::lower_bound () const -{ - if (is_a <irange> (*m_vrange)) - return as_a <irange> (*m_vrange).lower_bound (); - gcc_unreachable (); -} - -// Convenience function only available for integers and pointers. - -wide_int -Value_Range::upper_bound () const -{ - if (is_a <irange> (*m_vrange)) - return as_a <irange> (*m_vrange).upper_bound (); - gcc_unreachable (); -} - void Value_Range::dump (FILE *out) const { @@ -211,6 +191,18 @@ unsupported_range::operator= (const vrange &r) return *this; } +tree +unsupported_range::lbound () const +{ + return NULL; +} + +tree +unsupported_range::ubound () const +{ + return NULL; +} + // Assignment operator for generic ranges. Copying incompatible types // is not allowed. @@ -957,6 +949,18 @@ frange::set_nonnegative (tree type) set (type, dconst0, frange_val_max (type)); } +tree +frange::lbound () const +{ + return build_real (type (), lower_bound ()); +} + +tree +frange::ubound () const +{ + return build_real (type (), upper_bound ()); +} + // Here we copy between any two irange's. irange & @@ -2086,6 +2090,18 @@ irange::union_bitmask (const irange &r) return true; } +tree +irange::lbound () const +{ + return wide_int_to_tree (type (), lower_bound ()); +} + +tree +irange::ubound () const +{ + return wide_int_to_tree (type (), upper_bound ()); +} + void irange_bitmask::verify_mask () const { diff --git a/gcc/value-range.h b/gcc/value-range.h index b7c8398..f216f1b 100644 --- a/gcc/value-range.h +++ b/gcc/value-range.h @@ -96,6 +96,8 @@ public: virtual void set_nonnegative (tree type) = 0; virtual bool fits_p (const vrange &r) const = 0; virtual ~vrange () { } + virtual tree lbound () const = 0; + virtual tree ubound () const = 0; bool varying_p () const; bool undefined_p () const; @@ -298,6 +300,8 @@ public: wide_int lower_bound (unsigned = 0) const; wide_int upper_bound (unsigned) const; wide_int upper_bound () const; + virtual tree lbound () const override; + virtual tree ubound () const override; // Predicates. virtual bool zero_p () const override; @@ -419,6 +423,8 @@ public: void set_nonnegative (tree type) final override; bool fits_p (const vrange &) const final override; unsupported_range& operator= (const vrange &r); + tree lbound () const final override; + tree ubound () const final override; }; // The NAN state as an opaque object. @@ -526,6 +532,8 @@ public: bool operator!= (const frange &r) const { return !(*this == r); } const REAL_VALUE_TYPE &lower_bound () const; const REAL_VALUE_TYPE &upper_bound () const; + virtual tree lbound () const override; + virtual tree ubound () const override; nan_state get_nan_state () const; void update_nan (); void update_nan (bool sign); @@ -710,7 +718,6 @@ public: void dump (FILE *) const; static bool supports_type_p (const_tree type); - // Convenience methods for vrange compatibility. tree type () { return m_vrange->type (); } bool varying_p () const { return m_vrange->varying_p (); } bool undefined_p () const { return m_vrange->undefined_p (); } @@ -726,8 +733,8 @@ public: { init (type); return m_vrange->set_nonzero (type); } bool nonzero_p () const { return m_vrange->nonzero_p (); } bool zero_p () const { return m_vrange->zero_p (); } - wide_int lower_bound () const; // For irange/prange comparability. - wide_int upper_bound () const; // For irange/prange comparability. + tree lbound () const { return m_vrange->lbound (); } + tree ubound () const { return m_vrange->ubound (); } void accept (const vrange_visitor &v) const { m_vrange->accept (v); } private: void init (tree type); |