1 /* Support routines for value ranges.
2    Copyright (C) 2019-2020 Free Software Foundation, Inc.
3 
4 This file is part of GCC.
5 
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
10 
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along 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.  */
24 enum 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 
class(for_user)40 class GTY((for_user)) value_range
41 {
42 public:
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 
96 protected:
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 
115 private:
116   int value_inside_range (tree) const;
117 };
118 
119 extern bool range_has_numeric_bounds_p (const value_range *);
120 extern bool ranges_from_anti_range (const value_range *,
121 				    value_range *, value_range *);
122 extern void dump_value_range (FILE *, const value_range *);
123 extern bool vrp_val_is_min (const_tree);
124 extern bool vrp_val_is_max (const_tree);
125 extern tree vrp_val_min (const_tree);
126 extern tree vrp_val_max (const_tree);
127 extern bool vrp_operand_equal_p (const_tree, const_tree);
128 
129 inline
value_range()130 value_range::value_range ()
131 {
132   m_kind = VR_UNDEFINED;
133   m_min = m_max = NULL;
134 }
135 
136 inline value_range_kind
kind()137 value_range::kind () const
138 {
139   return m_kind;
140 }
141 
142 inline tree
type()143 value_range::type () const
144 {
145   return TREE_TYPE (min ());
146 }
147 
148 inline tree
min()149 value_range::min () const
150 {
151   return m_min;
152 }
153 
154 inline tree
max()155 value_range::max () const
156 {
157   return m_max;
158 }
159 
160 inline bool
varying_p()161 value_range::varying_p () const
162 {
163   return m_kind == VR_VARYING;
164 }
165 
166 inline bool
undefined_p()167 value_range::undefined_p () const
168 {
169   return m_kind == VR_UNDEFINED;
170 }
171 
172 inline bool
zero_p()173 value_range::zero_p () const
174 {
175   return (m_kind == VR_RANGE
176 	  && integer_zerop (m_min)
177 	  && integer_zerop (m_max));
178 }
179 
180 inline bool
nonzero_p()181 value_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 
195 inline bool
supports_type_p(tree type)196 value_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 
203 inline bool
range_includes_zero_p(const value_range * vr)204 range_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