1/* Support routines for value ranges. 2 Copyright (C) 2019-2020 Free Software Foundation, Inc. 3 4This file is part of GCC. 5 6GCC is free software; you can redistribute it and/or modify 7it under the terms of the GNU General Public License as published by 8the Free Software Foundation; either version 3, or (at your option) 9any later version. 10 11GCC is distributed in the hope that it will be useful, 12but WITHOUT ANY WARRANTY; without even the implied warranty of 13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14GNU General Public License for more details. 15 16You should have received a copy of the GNU General Public License 17along with GCC; see the file COPYING3. If not see 18<http://www.gnu.org/licenses/>. */ 19 20#ifndef GCC_VALUE_RANGE_H 21#define GCC_VALUE_RANGE_H 22 23/* Types of value ranges. */ 24enum value_range_kind 25{ 26 /* Empty range. */ 27 VR_UNDEFINED, 28 /* Range spans the entire domain. */ 29 VR_VARYING, 30 /* Range is [MIN, MAX]. */ 31 VR_RANGE, 32 /* Range is ~[MIN, MAX]. */ 33 VR_ANTI_RANGE, 34 /* Range is a nice guy. */ 35 VR_LAST 36}; 37 38// Range of values that can be associated with an SSA_NAME. 39 40class GTY((for_user)) value_range 41{ 42public: 43 value_range (); 44 value_range (tree, tree, value_range_kind = VR_RANGE); 45 value_range (tree type, const wide_int &, const wide_int &, 46 value_range_kind = VR_RANGE); 47 value_range (tree type); 48 49 void set (tree, tree, value_range_kind = VR_RANGE); 50 void set (tree); 51 void set_nonzero (tree); 52 void set_zero (tree); 53 54 enum value_range_kind kind () const; 55 tree min () const; 56 tree max () const; 57 58 /* Types of value ranges. */ 59 bool symbolic_p () const; 60 bool constant_p () const; 61 bool undefined_p () const; 62 bool varying_p () const; 63 void set_varying (tree type); 64 void set_undefined (); 65 66 void union_ (const value_range *); 67 void intersect (const value_range *); 68 void union_ (const value_range &); 69 void intersect (const value_range &); 70 71 bool operator== (const value_range &) const; 72 bool operator!= (const value_range &) const /* = delete */; 73 bool equal_p (const value_range &) const; 74 75 /* Misc methods. */ 76 tree type () const; 77 bool may_contain_p (tree) const; 78 bool zero_p () const; 79 bool nonzero_p () const; 80 bool singleton_p (tree *result = NULL) const; 81 void dump (FILE *) const; 82 void dump () const; 83 84 static bool supports_type_p (tree); 85 void normalize_symbolics (); 86 void normalize_addresses (); 87 88 static const unsigned int m_max_pairs = 2; 89 bool contains_p (tree) const; 90 unsigned num_pairs () const; 91 wide_int lower_bound (unsigned = 0) const; 92 wide_int upper_bound (unsigned) const; 93 wide_int upper_bound () const; 94 void invert (); 95 96protected: 97 void check (); 98 static value_range union_helper (const value_range *, const value_range *); 99 static value_range intersect_helper (const value_range *, 100 const value_range *); 101 102 friend void gt_ggc_mx_value_range (void *); 103 friend void gt_pch_p_11value_range (void *, void *, 104 gt_pointer_operator, void *); 105 friend void gt_pch_nx_value_range (void *); 106 friend void gt_ggc_mx (value_range &); 107 friend void gt_ggc_mx (value_range *&); 108 friend void gt_pch_nx (value_range &); 109 friend void gt_pch_nx (value_range *, gt_pointer_operator, void *); 110 111 enum value_range_kind m_kind; 112 tree m_min; 113 tree m_max; 114 115private: 116 int value_inside_range (tree) const; 117}; 118 119extern bool range_has_numeric_bounds_p (const value_range *); 120extern bool ranges_from_anti_range (const value_range *, 121 value_range *, value_range *); 122extern void dump_value_range (FILE *, const value_range *); 123extern bool vrp_val_is_min (const_tree); 124extern bool vrp_val_is_max (const_tree); 125extern tree vrp_val_min (const_tree); 126extern tree vrp_val_max (const_tree); 127extern bool vrp_operand_equal_p (const_tree, const_tree); 128 129inline 130value_range::value_range () 131{ 132 m_kind = VR_UNDEFINED; 133 m_min = m_max = NULL; 134} 135 136inline value_range_kind 137value_range::kind () const 138{ 139 return m_kind; 140} 141 142inline tree 143value_range::type () const 144{ 145 return TREE_TYPE (min ()); 146} 147 148inline tree 149value_range::min () const 150{ 151 return m_min; 152} 153 154inline tree 155value_range::max () const 156{ 157 return m_max; 158} 159 160inline bool 161value_range::varying_p () const 162{ 163 return m_kind == VR_VARYING; 164} 165 166inline bool 167value_range::undefined_p () const 168{ 169 return m_kind == VR_UNDEFINED; 170} 171 172inline bool 173value_range::zero_p () const 174{ 175 return (m_kind == VR_RANGE 176 && integer_zerop (m_min) 177 && integer_zerop (m_max)); 178} 179 180inline bool 181value_range::nonzero_p () const 182{ 183 if (m_kind == VR_ANTI_RANGE 184 && !TYPE_UNSIGNED (type ()) 185 && integer_zerop (m_min) 186 && integer_zerop (m_max)) 187 return true; 188 189 return (m_kind == VR_RANGE 190 && TYPE_UNSIGNED (type ()) 191 && integer_onep (m_min) 192 && vrp_val_is_max (m_max)); 193} 194 195inline bool 196value_range::supports_type_p (tree type) 197{ 198 if (type && (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))) 199 return type; 200 return false; 201} 202 203inline bool 204range_includes_zero_p (const value_range *vr) 205{ 206 if (vr->undefined_p ()) 207 return false; 208 209 if (vr->varying_p ()) 210 return true; 211 212 return vr->may_contain_p (build_zero_cst (vr->type ())); 213} 214 215#endif // GCC_VALUE_RANGE_H 216