diff options
author | Aldy Hernandez <aldyh@redhat.com> | 2019-11-13 19:13:40 +0000 |
---|---|---|
committer | Aldy Hernandez <aldyh@gcc.gnu.org> | 2019-11-13 19:13:40 +0000 |
commit | cca78449beb70da5d1e65e206044b3ef22a48b55 (patch) | |
tree | 7166217f4585418b79d0ba6b4ebe36ed9580288a /gcc/value-range.h | |
parent | 425ea30f79e236c187430749be994309968e1dbd (diff) | |
download | gcc-cca78449beb70da5d1e65e206044b3ef22a48b55.zip gcc-cca78449beb70da5d1e65e206044b3ef22a48b55.tar.gz gcc-cca78449beb70da5d1e65e206044b3ef22a48b55.tar.bz2 |
Move plain value_range things to value-range.[hc]*.
From-SVN: r278153
Diffstat (limited to 'gcc/value-range.h')
-rw-r--r-- | gcc/value-range.h | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/gcc/value-range.h b/gcc/value-range.h new file mode 100644 index 0000000..8a88e9a --- /dev/null +++ b/gcc/value-range.h @@ -0,0 +1,216 @@ +/* Support routines for value ranges. + Copyright (C) 2019 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#ifndef GCC_VALUE_RANGE_H +#define GCC_VALUE_RANGE_H + +/* Types of value ranges. */ +enum value_range_kind +{ + /* Empty range. */ + VR_UNDEFINED, + /* Range spans the entire domain. */ + VR_VARYING, + /* Range is [MIN, MAX]. */ + VR_RANGE, + /* Range is ~[MIN, MAX]. */ + VR_ANTI_RANGE, + /* Range is a nice guy. */ + VR_LAST +}; + +// Range of values that can be associated with an SSA_NAME. + +class GTY((for_user)) value_range +{ + friend void range_tests (); +public: + value_range (); + value_range (tree, tree, value_range_kind = VR_RANGE); + value_range (tree type, const wide_int &, const wide_int &, + value_range_kind = VR_RANGE); + value_range (tree type); + + void set (tree, tree, value_range_kind = VR_RANGE); + void set (tree); + void set_nonzero (tree); + void set_zero (tree); + + enum value_range_kind kind () const; + tree min () const; + tree max () const; + + /* 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 value_range *); + void intersect (const value_range *); + void union_ (const value_range &); + void intersect (const value_range &); + + bool operator== (const value_range &) const; + bool operator!= (const value_range &) const /* = delete */; + bool equal_p (const value_range &) 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 *) const; + void dump () const; + + static bool supports_type_p (tree); + value_range normalize_symbolics () const; + value_range normalize_addresses () const; + + static const unsigned int m_max_pairs = 2; + bool contains_p (tree) const; + unsigned num_pairs () const; + wide_int lower_bound (unsigned = 0) const; + wide_int upper_bound (unsigned) const; + wide_int upper_bound () const; + void invert (); + +protected: + void check (); + static value_range union_helper (const value_range *, const value_range *); + static value_range intersect_helper (const value_range *, + const value_range *); + + friend void gt_ggc_mx_value_range (void *); + friend void gt_pch_p_11value_range (void *, void *, + gt_pointer_operator, void *); + friend void gt_pch_nx_value_range (void *); + friend void gt_ggc_mx (value_range &); + friend void gt_ggc_mx (value_range *&); + friend void gt_pch_nx (value_range &); + friend void gt_pch_nx (value_range *, gt_pointer_operator, void *); + + enum value_range_kind m_kind; + tree m_min; + tree m_max; + +private: + int value_inside_range (tree) const; +}; + +extern bool range_has_numeric_bounds_p (const value_range *); +extern bool ranges_from_anti_range (const value_range *, + value_range *, value_range *); +extern void dump_value_range (FILE *, const value_range *); +extern bool vrp_val_is_min (const_tree); +extern bool vrp_val_is_max (const_tree); +extern tree vrp_val_min (const_tree); +extern tree vrp_val_max (const_tree); +extern bool vrp_operand_equal_p (const_tree, const_tree); + +inline +value_range::value_range () +{ + m_kind = VR_UNDEFINED; + m_min = m_max = NULL; +} + +inline value_range_kind +value_range::kind () const +{ + return m_kind; +} + +inline tree +value_range::type () const +{ + return TREE_TYPE (min ()); +} + +inline tree +value_range::min () const +{ + return m_min; +} + +inline tree +value_range::max () const +{ + return m_max; +} + +inline bool +value_range::varying_p () const +{ + return m_kind == VR_VARYING; +} + +inline bool +value_range::undefined_p () const +{ + return m_kind == VR_UNDEFINED; +} + +inline bool +value_range::zero_p () const +{ + return (m_kind == VR_RANGE + && integer_zerop (m_min) + && integer_zerop (m_max)); +} + +inline bool +value_range::nonzero_p () const +{ + if (m_kind == VR_ANTI_RANGE + && !TYPE_UNSIGNED (type ()) + && integer_zerop (m_min) + && integer_zerop (m_max)) + return true; + + return (m_kind == VR_RANGE + && TYPE_UNSIGNED (type ()) + && integer_onep (m_min) + && vrp_val_is_max (m_max)); +} + +inline bool +value_range::supports_type_p (tree type) +{ + if (type && (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))) + return type; + return false; +} + +inline bool +range_includes_zero_p (const value_range *vr) +{ + if (vr->undefined_p ()) + return false; + + if (vr->varying_p ()) + return true; + + return vr->may_contain_p (build_zero_cst (vr->type ())); +} + +#endif // GCC_VALUE_RANGE_H |