]>
Commit | Line | Data |
---|---|---|
cca78449 | 1 | /* Support routines for value ranges. |
8d9254fc | 2 | Copyright (C) 2019-2020 Free Software Foundation, Inc. |
cca78449 AH |
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 | { | |
cca78449 AH |
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); | |
6ee86466 AH |
85 | void normalize_symbolics (); |
86 | void normalize_addresses (); | |
cca78449 AH |
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 |