145
|
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
|
|
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
|
|
130 value_range::value_range ()
|
|
131 {
|
|
132 m_kind = VR_UNDEFINED;
|
|
133 m_min = m_max = NULL;
|
|
134 }
|
|
135
|
|
136 inline value_range_kind
|
|
137 value_range::kind () const
|
|
138 {
|
|
139 return m_kind;
|
|
140 }
|
|
141
|
|
142 inline tree
|
|
143 value_range::type () const
|
|
144 {
|
|
145 return TREE_TYPE (min ());
|
|
146 }
|
|
147
|
|
148 inline tree
|
|
149 value_range::min () const
|
|
150 {
|
|
151 return m_min;
|
|
152 }
|
|
153
|
|
154 inline tree
|
|
155 value_range::max () const
|
|
156 {
|
|
157 return m_max;
|
|
158 }
|
|
159
|
|
160 inline bool
|
|
161 value_range::varying_p () const
|
|
162 {
|
|
163 return m_kind == VR_VARYING;
|
|
164 }
|
|
165
|
|
166 inline bool
|
|
167 value_range::undefined_p () const
|
|
168 {
|
|
169 return m_kind == VR_UNDEFINED;
|
|
170 }
|
|
171
|
|
172 inline bool
|
|
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
|
|
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
|
|
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
|
|
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
|