]>
Commit | Line | Data |
---|---|---|
c296f633 | 1 | /* Support routines for Value Range Propagation (VRP). |
fbd26352 | 2 | Copyright (C) 2016-2019 Free Software Foundation, Inc. |
c296f633 | 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 | ||
b7e72cd7 | 20 | #ifndef GCC_TREE_VRP_H |
21 | #define GCC_TREE_VRP_H | |
22 | ||
be44111e | 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 | }; | |
c296f633 | 37 | |
a1054504 | 38 | |
c296f633 | 39 | /* Range of values that can be associated with an SSA_NAME after VRP |
40 | has executed. */ | |
a1054504 | 41 | class GTY((for_user)) value_range_base |
42 | { | |
43 | public: | |
44 | value_range_base (); | |
45 | value_range_base (value_range_kind, tree, tree); | |
46 | ||
48625f58 | 47 | void set (value_range_kind, tree, tree); |
48 | void set (tree); | |
49 | void set_nonnull (tree); | |
50 | void set_null (tree); | |
51 | ||
a1054504 | 52 | enum value_range_kind kind () const; |
53 | tree min () const; | |
54 | tree max () const; | |
55 | ||
56 | /* Types of value ranges. */ | |
5a780b31 | 57 | bool symbolic_p () const; |
58 | bool constant_p () const; | |
a1054504 | 59 | bool undefined_p () const; |
60 | bool varying_p () const; | |
5a780b31 | 61 | void set_varying (); |
62 | void set_undefined (); | |
a1054504 | 63 | |
64 | void union_ (const value_range_base *); | |
65 | ||
2d5d5612 | 66 | bool operator== (const value_range_base &) const /* = delete */; |
67 | bool operator!= (const value_range_base &) const /* = delete */; | |
68 | bool equal_p (const value_range_base &) const; | |
a1054504 | 69 | |
a1054504 | 70 | /* Misc methods. */ |
71 | tree type () const; | |
72 | bool may_contain_p (tree) const; | |
73 | void set_and_canonicalize (enum value_range_kind, tree, tree); | |
5a780b31 | 74 | bool zero_p () const; |
75 | bool singleton_p (tree *result = NULL) const; | |
a1054504 | 76 | void dump (FILE *) const; |
77 | ||
78 | protected: | |
a1054504 | 79 | void check (); |
de9df22a | 80 | static value_range_base union_helper (const value_range_base *, |
81 | const value_range_base *); | |
a1054504 | 82 | |
83 | enum value_range_kind m_kind; | |
84 | ||
85 | tree m_min; | |
86 | tree m_max; | |
87 | ||
88 | friend void gt_ggc_mx_value_range_base (void *); | |
89 | friend void gt_pch_p_16value_range_base (void *, void *, | |
90 | gt_pointer_operator, void *); | |
91 | friend void gt_pch_nx_value_range_base (void *); | |
92 | friend void gt_ggc_mx (value_range_base &); | |
93 | friend void gt_ggc_mx (value_range_base *&); | |
94 | friend void gt_pch_nx (value_range_base &); | |
95 | friend void gt_pch_nx (value_range_base *, gt_pointer_operator, void *); | |
96 | }; | |
97 | ||
98 | /* Note value_range cannot currently be used with GC memory, only | |
99 | value_range_base is fully set up for this. */ | |
100 | class GTY((user)) value_range : public value_range_base | |
c296f633 | 101 | { |
be44111e | 102 | public: |
103 | value_range (); | |
a1054504 | 104 | value_range (const value_range_base &); |
48625f58 | 105 | /* Deep-copies equiv bitmap argument. */ |
be44111e | 106 | value_range (value_range_kind, tree, tree, bitmap = NULL); |
48625f58 | 107 | |
108 | /* Shallow-copies equiv bitmap. */ | |
109 | value_range (const value_range &) /* = delete */; | |
110 | /* Shallow-copies equiv bitmap. */ | |
111 | value_range& operator=(const value_range&) /* = delete */; | |
112 | ||
113 | /* Move equiv bitmap from source range. */ | |
114 | void move (value_range *); | |
115 | ||
116 | /* Leaves equiv bitmap alone. */ | |
be44111e | 117 | void update (value_range_kind, tree, tree); |
48625f58 | 118 | /* Deep-copies equiv bitmap argument. */ |
119 | void set (value_range_kind, tree, tree, bitmap = NULL); | |
120 | void set (tree); | |
121 | void set_nonnull (tree); | |
122 | void set_null (tree); | |
123 | ||
2d5d5612 | 124 | bool operator== (const value_range &) const /* = delete */; |
125 | bool operator!= (const value_range &) const /* = delete */; | |
be44111e | 126 | void intersect (const value_range *); |
127 | void union_ (const value_range *); | |
2d5d5612 | 128 | bool equal_p (const value_range &, bool ignore_equivs) const; |
be44111e | 129 | |
130 | /* Types of value ranges. */ | |
be44111e | 131 | void set_undefined (); |
132 | void set_varying (); | |
133 | ||
134 | /* Equivalence bitmap methods. */ | |
135 | bitmap equiv () const; | |
136 | void equiv_clear (); | |
137 | void equiv_add (const_tree, const value_range *, bitmap_obstack * = NULL); | |
138 | ||
139 | /* Misc methods. */ | |
be44111e | 140 | void deep_copy (const value_range *); |
48625f58 | 141 | void set_and_canonicalize (enum value_range_kind, tree, tree, bitmap = NULL); |
be44111e | 142 | void dump (FILE *) const; |
be44111e | 143 | |
be44111e | 144 | private: |
48625f58 | 145 | /* Deep-copies bitmap argument. */ |
a1054504 | 146 | void set_equiv (bitmap); |
be44111e | 147 | void check (); |
be44111e | 148 | void intersect_helper (value_range *, const value_range *); |
be44111e | 149 | |
be44111e | 150 | /* Set of SSA names whose value ranges are equivalent to this one. |
151 | This set is only valid when TYPE is VR_RANGE or VR_ANTI_RANGE. */ | |
152 | bitmap m_equiv; | |
153 | }; | |
c296f633 | 154 | |
be44111e | 155 | inline |
a1054504 | 156 | value_range_base::value_range_base () |
be44111e | 157 | { |
158 | m_kind = VR_UNDEFINED; | |
159 | m_min = m_max = NULL; | |
a1054504 | 160 | } |
161 | ||
162 | inline | |
163 | value_range::value_range () | |
164 | : value_range_base () | |
165 | { | |
be44111e | 166 | m_equiv = NULL; |
167 | } | |
c296f633 | 168 | |
be44111e | 169 | /* Return the kind of this range. */ |
c296f633 | 170 | |
be44111e | 171 | inline value_range_kind |
a1054504 | 172 | value_range_base::kind () const |
be44111e | 173 | { |
174 | return m_kind; | |
175 | } | |
c296f633 | 176 | |
be44111e | 177 | inline bitmap |
178 | value_range::equiv () const | |
179 | { | |
180 | return m_equiv; | |
181 | } | |
c296f633 | 182 | |
be44111e | 183 | /* Return the lower bound. */ |
11822fb2 | 184 | |
be44111e | 185 | inline tree |
a1054504 | 186 | value_range_base::min () const |
be44111e | 187 | { |
188 | return m_min; | |
189 | } | |
190 | ||
191 | /* Return the upper bound. */ | |
192 | ||
193 | inline tree | |
a1054504 | 194 | value_range_base::max () const |
be44111e | 195 | { |
196 | return m_max; | |
197 | } | |
198 | ||
199 | /* Return TRUE if range spans the entire possible domain. */ | |
200 | ||
201 | inline bool | |
a1054504 | 202 | value_range_base::varying_p () const |
be44111e | 203 | { |
204 | return m_kind == VR_VARYING; | |
205 | } | |
206 | ||
207 | /* Return TRUE if range is undefined (essentially the empty set). */ | |
208 | ||
209 | inline bool | |
a1054504 | 210 | value_range_base::undefined_p () const |
be44111e | 211 | { |
212 | return m_kind == VR_UNDEFINED; | |
213 | } | |
214 | ||
215 | /* Return TRUE if range is the constant zero. */ | |
216 | ||
217 | inline bool | |
5a780b31 | 218 | value_range_base::zero_p () const |
be44111e | 219 | { |
220 | return (m_kind == VR_RANGE | |
221 | && integer_zerop (m_min) | |
222 | && integer_zerop (m_max)); | |
223 | } | |
c296f633 | 224 | |
c296f633 | 225 | extern void dump_value_range (FILE *, const value_range *); |
5a780b31 | 226 | extern void dump_value_range (FILE *, const value_range_base *); |
9c015ccf | 227 | |
228 | struct assert_info | |
229 | { | |
230 | /* Predicate code for the ASSERT_EXPR. Must be COMPARISON_CLASS_P. */ | |
231 | enum tree_code comp_code; | |
232 | ||
233 | /* Name to register the assert for. */ | |
234 | tree name; | |
235 | ||
236 | /* Value being compared against. */ | |
237 | tree val; | |
238 | ||
239 | /* Expression to compare. */ | |
240 | tree expr; | |
241 | }; | |
242 | ||
243 | extern void register_edge_assert_for (tree, edge, enum tree_code, | |
244 | tree, tree, vec<assert_info> &); | |
245 | extern bool stmt_interesting_for_vrp (gimple *); | |
9435b515 | 246 | extern bool range_includes_p (const value_range_base *, HOST_WIDE_INT); |
9c015ccf | 247 | extern bool infer_value_range (gimple *, tree, tree_code *, tree *); |
248 | ||
94d86adc | 249 | extern bool vrp_bitmap_equal_p (const_bitmap, const_bitmap); |
5a780b31 | 250 | |
251 | extern tree value_range_constant_singleton (const value_range_base *); | |
252 | extern bool range_int_cst_p (const value_range_base *); | |
253 | extern bool range_int_cst_singleton_p (const value_range_base *); | |
254 | ||
94d86adc | 255 | extern int compare_values (tree, tree); |
256 | extern int compare_values_warnv (tree, tree, bool *); | |
5a780b31 | 257 | extern int operand_less_p (tree, tree); |
94d86adc | 258 | extern bool vrp_val_is_min (const_tree); |
259 | extern bool vrp_val_is_max (const_tree); | |
5a780b31 | 260 | extern int value_inside_range (tree, tree, tree); |
261 | ||
262 | extern tree vrp_val_min (const_tree); | |
263 | extern tree vrp_val_max (const_tree); | |
264 | ||
48625f58 | 265 | extern void extract_range_from_unary_expr (value_range_base *vr, |
5a780b31 | 266 | enum tree_code code, |
267 | tree type, | |
48625f58 | 268 | const value_range_base *vr0_, |
5a780b31 | 269 | tree op0_type); |
48625f58 | 270 | extern void extract_range_from_binary_expr (value_range_base *, |
271 | enum tree_code, | |
272 | tree, const value_range_base *, | |
273 | const value_range_base *); | |
5a780b31 | 274 | |
275 | extern bool vrp_operand_equal_p (const_tree, const_tree); | |
276 | extern enum value_range_kind intersect_range_with_nonzero_bits | |
277 | (enum value_range_kind, wide_int *, wide_int *, const wide_int &, signop); | |
278 | extern bool vrp_set_zero_nonzero_bits (const tree, const value_range_base *, | |
279 | wide_int *, wide_int *); | |
280 | ||
94d86adc | 281 | extern bool find_case_label_range (gswitch *, tree, tree, size_t *, size_t *); |
282 | extern bool find_case_label_index (gswitch *, size_t, tree, size_t *); | |
94d86adc | 283 | extern bool overflow_comparison_p (tree_code, tree, tree, bool, tree *); |
94d86adc | 284 | extern tree get_single_symbol (tree, bool *, tree *); |
dd435793 | 285 | extern void maybe_set_nonzero_bits (edge, tree); |
be44111e | 286 | extern value_range_kind determine_value_range (tree, wide_int *, wide_int *); |
5a780b31 | 287 | |
9435b515 | 288 | /* Return TRUE if *VR includes the value zero. */ |
289 | ||
290 | inline bool | |
291 | range_includes_zero_p (const value_range_base *vr) | |
292 | { | |
293 | return range_includes_p (vr, 0); | |
294 | } | |
295 | ||
b7e72cd7 | 296 | #endif /* GCC_TREE_VRP_H */ |