annotate gcc/value-range.h @ 158:494b0b89df80 default tip

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