annotate gcc/analyzer/constraint-manager.cc @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents
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 /* Tracking equivalence classes and constraints at a point on an execution path.
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 Contributed by David Malcolm <dmalcolm@redhat.com>.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
4
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
5 This file is part of GCC.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
6
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
7 GCC is free software; you can redistribute it and/or modify it
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
8 under the terms of the GNU General Public License as published by
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
9 the Free Software Foundation; either version 3, or (at your option)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
10 any later version.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
11
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
12 GCC is distributed in the hope that it will be useful, but
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
13 WITHOUT ANY WARRANTY; without even the implied warranty of
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
15 General Public License for more details.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
16
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
18 along with GCC; see the file COPYING3. If not see
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
19 <http://www.gnu.org/licenses/>. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
20
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
21 #include "config.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
22 #include "system.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
23 #include "coretypes.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
24 #include "tree.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
25 #include "function.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
26 #include "basic-block.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
27 #include "gimple.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
28 #include "gimple-iterator.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
29 #include "fold-const.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
30 #include "selftest.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
31 #include "diagnostic-core.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
32 #include "graphviz.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
33 #include "function.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
34 #include "analyzer/analyzer.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
35 #include "ordered-hash-map.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
36 #include "options.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
37 #include "cgraph.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
38 #include "cfg.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
39 #include "digraph.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
40 #include "analyzer/supergraph.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
41 #include "sbitmap.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
42 #include "tristate.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
43 #include "analyzer/region-model.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
44 #include "analyzer/constraint-manager.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
45 #include "analyzer/analyzer-selftests.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
46
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
47 #if ENABLE_ANALYZER
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
48
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
49 namespace ana {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
50
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
51 /* One of the end-points of a range. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
52
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
53 struct bound
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
54 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
55 bound () : m_constant (NULL_TREE), m_closed (false) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
56 bound (tree constant, bool closed)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
57 : m_constant (constant), m_closed (closed) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
58
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
59 void ensure_closed (bool is_upper);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
60
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
61 const char * get_relation_as_str () const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
62
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
63 tree m_constant;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
64 bool m_closed;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
65 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
66
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
67 /* A range of values, used for determining if a value has been
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
68 constrained to just one possible constant value. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
69
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
70 struct range
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
71 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
72 range () : m_lower_bound (), m_upper_bound () {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
73 range (const bound &lower, const bound &upper)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
74 : m_lower_bound (lower), m_upper_bound (upper) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
75
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
76 void dump (pretty_printer *pp) const;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
77
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
78 bool constrained_to_single_element (tree *out);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
79
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
80 bound m_lower_bound;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
81 bound m_upper_bound;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
82 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
83
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
84 /* struct bound. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
85
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
86 /* Ensure that this bound is closed by converting an open bound to a
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
87 closed one. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
88
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
89 void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
90 bound::ensure_closed (bool is_upper)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
91 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
92 if (!m_closed)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
93 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
94 /* Offset by 1 in the appropriate direction.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
95 For example, convert 3 < x into 4 <= x,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
96 and convert x < 5 into x <= 4. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
97 gcc_assert (CONSTANT_CLASS_P (m_constant));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
98 m_constant = fold_build2 (is_upper ? MINUS_EXPR : PLUS_EXPR,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
99 TREE_TYPE (m_constant),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
100 m_constant, integer_one_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
101 gcc_assert (CONSTANT_CLASS_P (m_constant));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
102 m_closed = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
103 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
104 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
105
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
106 /* Get "<=" vs "<" for this bound. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
107
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
108 const char *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
109 bound::get_relation_as_str () const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
110 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
111 if (m_closed)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
112 return "<=";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
113 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
114 return "<";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
115 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
116
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
117 /* struct range. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
118
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
119 /* Dump this range to PP, which must support %E for tree. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
120
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
121 void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
122 range::dump (pretty_printer *pp) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
123 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
124 pp_printf (pp, "%qE %s x %s %qE",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
125 m_lower_bound.m_constant,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
126 m_lower_bound.get_relation_as_str (),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
127 m_upper_bound.get_relation_as_str (),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
128 m_upper_bound.m_constant);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
129 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
130
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
131 /* Determine if there is only one possible value for this range.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
132 If so, return true and write the constant to *OUT.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
133 Otherwise, return false. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
134
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
135 bool
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
136 range::constrained_to_single_element (tree *out)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
137 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
138 if (!INTEGRAL_TYPE_P (TREE_TYPE (m_lower_bound.m_constant)))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
139 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
140 if (!INTEGRAL_TYPE_P (TREE_TYPE (m_upper_bound.m_constant)))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
141 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
142
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
143 /* Convert any open bounds to closed bounds. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
144 m_lower_bound.ensure_closed (false);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
145 m_upper_bound.ensure_closed (true);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
146
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
147 // Are they equal?
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
148 tree comparison = fold_binary (EQ_EXPR, boolean_type_node,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
149 m_lower_bound.m_constant,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
150 m_upper_bound.m_constant);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
151 if (comparison == boolean_true_node)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
152 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
153 *out = m_lower_bound.m_constant;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
154 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
155 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
156 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
157 return false;
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 /* class equiv_class. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
161
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
162 /* equiv_class's default ctor. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
163
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
164 equiv_class::equiv_class ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
165 : m_constant (NULL_TREE), m_cst_sid (svalue_id::null ()),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
166 m_vars ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
167 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
168 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
169
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
170 /* equiv_class's copy ctor. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
171
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
172 equiv_class::equiv_class (const equiv_class &other)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
173 : m_constant (other.m_constant), m_cst_sid (other.m_cst_sid),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
174 m_vars (other.m_vars.length ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
175 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
176 int i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
177 svalue_id *sid;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
178 FOR_EACH_VEC_ELT (other.m_vars, i, sid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
179 m_vars.quick_push (*sid);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
180 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
181
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
182 /* Print an all-on-one-line representation of this equiv_class to PP,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
183 which must support %E for trees. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
184
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
185 void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
186 equiv_class::print (pretty_printer *pp) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
187 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
188 pp_character (pp, '{');
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
189 int i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
190 svalue_id *sid;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
191 FOR_EACH_VEC_ELT (m_vars, i, sid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
192 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
193 if (i > 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
194 pp_string (pp, " == ");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
195 sid->print (pp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
196 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
197 if (m_constant)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
198 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
199 if (i > 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
200 pp_string (pp, " == ");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
201 pp_printf (pp, "%qE", m_constant);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
202 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
203 pp_character (pp, '}');
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
204 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
205
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
206 /* Generate a hash value for this equiv_class. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
207
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
208 hashval_t
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
209 equiv_class::hash () const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
210 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
211 inchash::hash hstate;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
212 int i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
213 svalue_id *sid;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
214
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
215 inchash::add_expr (m_constant, hstate);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
216 FOR_EACH_VEC_ELT (m_vars, i, sid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
217 inchash::add (*sid, hstate);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
218 return hstate.end ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
219 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
220
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
221 /* Equality operator for equiv_class. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
222
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
223 bool
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
224 equiv_class::operator== (const equiv_class &other)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
225 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
226 if (m_constant != other.m_constant)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
227 return false; // TODO: use tree equality here?
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
228
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
229 /* FIXME: should we compare m_cst_sid? */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
230
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
231 if (m_vars.length () != other.m_vars.length ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
232 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
233
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
234 int i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
235 svalue_id *sid;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
236 FOR_EACH_VEC_ELT (m_vars, i, sid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
237 if (! (*sid == other.m_vars[i]))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
238 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
239
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
240 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
241 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
242
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
243 /* Add SID to this equiv_class, using CM to check if it's a constant. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
244
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
245 void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
246 equiv_class::add (svalue_id sid, const constraint_manager &cm)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
247 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
248 gcc_assert (!sid.null_p ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
249 if (tree cst = cm.maybe_get_constant (sid))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
250 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
251 gcc_assert (CONSTANT_CLASS_P (cst));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
252 /* FIXME: should we canonicalize which svalue is the constant
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
253 when there are multiple equal constants? */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
254 m_constant = cst;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
255 m_cst_sid = sid;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
256 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
257 m_vars.safe_push (sid);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
258 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
259
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
260 /* Remove SID from this equivalence class.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
261 Return true if SID was the last var in the equivalence class (suggesting
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
262 a possible leak). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
263
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
264 bool
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
265 equiv_class::del (svalue_id sid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
266 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
267 gcc_assert (!sid.null_p ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
268 gcc_assert (sid != m_cst_sid);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
269
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
270 int i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
271 svalue_id *iv;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
272 FOR_EACH_VEC_ELT (m_vars, i, iv)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
273 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
274 if (*iv == sid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
275 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
276 m_vars[i] = m_vars[m_vars.length () - 1];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
277 m_vars.pop ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
278 return m_vars.length () == 0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
279 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
280 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
281
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
282 /* SID must be in the class. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
283 gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
284 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
285 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
286
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
287 /* Get a representative member of this class, for handling cases
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
288 where the IDs can change mid-traversal. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
289
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
290 svalue_id
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
291 equiv_class::get_representative () const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
292 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
293 if (!m_cst_sid.null_p ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
294 return m_cst_sid;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
295 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
296 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
297 gcc_assert (m_vars.length () > 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
298 return m_vars[0];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
299 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
300 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
301
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
302 /* Remap all svalue_ids within this equiv_class using MAP. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
303
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
304 void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
305 equiv_class::remap_svalue_ids (const svalue_id_map &map)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
306 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
307 int i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
308 svalue_id *iv;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
309 FOR_EACH_VEC_ELT (m_vars, i, iv)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
310 map.update (iv);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
311 map.update (&m_cst_sid);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
312 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
313
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
314 /* Comparator for use by equiv_class::canonicalize. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
315
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
316 static int
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
317 svalue_id_cmp_by_id (const void *p1, const void *p2)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
318 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
319 const svalue_id *sid1 = (const svalue_id *)p1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
320 const svalue_id *sid2 = (const svalue_id *)p2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
321 return sid1->as_int () - sid2->as_int ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
322 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
323
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
324 /* Sort the svalues_ids within this equiv_class. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
325
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
326 void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
327 equiv_class::canonicalize ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
328 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
329 m_vars.qsort (svalue_id_cmp_by_id);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
330 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
331
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
332 /* Get a debug string for C_OP. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
333
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
334 const char *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
335 constraint_op_code (enum constraint_op c_op)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
336 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
337 switch (c_op)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
338 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
339 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
340 gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
341 case CONSTRAINT_NE: return "!=";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
342 case CONSTRAINT_LT: return "<";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
343 case CONSTRAINT_LE: return "<=";
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
344 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
345 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
346
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
347 /* Convert C_OP to an enum tree_code. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
348
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
349 enum tree_code
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
350 constraint_tree_code (enum constraint_op c_op)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
351 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
352 switch (c_op)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
353 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
354 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
355 gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
356 case CONSTRAINT_NE: return NE_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
357 case CONSTRAINT_LT: return LT_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
358 case CONSTRAINT_LE: return LE_EXPR;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
359 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
360 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
361
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
362 /* Given "lhs C_OP rhs", determine "lhs T_OP rhs".
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
363
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
364 For example, given "x < y", then "x > y" is false. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
365
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
366 static tristate
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
367 eval_constraint_op_for_op (enum constraint_op c_op, enum tree_code t_op)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
368 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
369 switch (c_op)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
370 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
371 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
372 gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
373 case CONSTRAINT_NE:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
374 if (t_op == EQ_EXPR)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
375 return tristate (tristate::TS_FALSE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
376 if (t_op == NE_EXPR)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
377 return tristate (tristate::TS_TRUE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
378 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
379 case CONSTRAINT_LT:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
380 if (t_op == LT_EXPR || t_op == LE_EXPR || t_op == NE_EXPR)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
381 return tristate (tristate::TS_TRUE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
382 if (t_op == EQ_EXPR || t_op == GT_EXPR || t_op == GE_EXPR)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
383 return tristate (tristate::TS_FALSE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
384 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
385 case CONSTRAINT_LE:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
386 if (t_op == LE_EXPR)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
387 return tristate (tristate::TS_TRUE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
388 if (t_op == GT_EXPR)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
389 return tristate (tristate::TS_FALSE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
390 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
391 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
392 return tristate (tristate::TS_UNKNOWN);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
393 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
394
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
395 /* class constraint. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
396
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
397 /* Print this constraint to PP (which must support %E for trees),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
398 using CM to look up equiv_class instances from ids. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
399
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
400 void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
401 constraint::print (pretty_printer *pp, const constraint_manager &cm) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
402 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
403 m_lhs.print (pp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
404 pp_string (pp, ": ");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
405 m_lhs.get_obj (cm).print (pp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
406 pp_string (pp, " ");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
407 pp_string (pp, constraint_op_code (m_op));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
408 pp_string (pp, " ");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
409 m_rhs.print (pp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
410 pp_string (pp, ": ");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
411 m_rhs.get_obj (cm).print (pp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
412 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
413
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
414 /* Generate a hash value for this constraint. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
415
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
416 hashval_t
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
417 constraint::hash () const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
418 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
419 inchash::hash hstate;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
420 hstate.add_int (m_lhs.m_idx);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
421 hstate.add_int (m_op);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
422 hstate.add_int (m_rhs.m_idx);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
423 return hstate.end ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
424 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
425
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
426 /* Equality operator for constraints. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
427
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
428 bool
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
429 constraint::operator== (const constraint &other) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
430 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
431 if (m_lhs != other.m_lhs)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
432 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
433 if (m_op != other.m_op)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
434 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
435 if (m_rhs != other.m_rhs)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
436 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
437 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
438 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
439
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
440 /* class equiv_class_id. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
441
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
442 /* Get the underlying equiv_class for this ID from CM. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
443
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
444 const equiv_class &
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
445 equiv_class_id::get_obj (const constraint_manager &cm) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
446 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
447 return cm.get_equiv_class_by_index (m_idx);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
448 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
449
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
450 /* Access the underlying equiv_class for this ID from CM. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
451
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
452 equiv_class &
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
453 equiv_class_id::get_obj (constraint_manager &cm) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
454 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
455 return cm.get_equiv_class_by_index (m_idx);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
456 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
457
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
458 /* Print this equiv_class_id to PP. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
459
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
460 void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
461 equiv_class_id::print (pretty_printer *pp) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
462 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
463 if (null_p ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
464 pp_printf (pp, "null");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
465 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
466 pp_printf (pp, "ec%i", m_idx);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
467 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
468
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
469 /* class constraint_manager. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
470
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
471 /* constraint_manager's copy ctor. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
472
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
473 constraint_manager::constraint_manager (const constraint_manager &other)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
474 : m_equiv_classes (other.m_equiv_classes.length ()),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
475 m_constraints (other.m_constraints.length ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
476 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
477 int i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
478 equiv_class *ec;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
479 FOR_EACH_VEC_ELT (other.m_equiv_classes, i, ec)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
480 m_equiv_classes.quick_push (new equiv_class (*ec));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
481 constraint *c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
482 FOR_EACH_VEC_ELT (other.m_constraints, i, c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
483 m_constraints.quick_push (*c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
484 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
485
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
486 /* constraint_manager's assignment operator. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
487
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
488 constraint_manager&
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
489 constraint_manager::operator= (const constraint_manager &other)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
490 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
491 gcc_assert (m_equiv_classes.length () == 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
492 gcc_assert (m_constraints.length () == 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
493
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
494 int i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
495 equiv_class *ec;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
496 m_equiv_classes.reserve (other.m_equiv_classes.length ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
497 FOR_EACH_VEC_ELT (other.m_equiv_classes, i, ec)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
498 m_equiv_classes.quick_push (new equiv_class (*ec));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
499 constraint *c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
500 m_constraints.reserve (other.m_constraints.length ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
501 FOR_EACH_VEC_ELT (other.m_constraints, i, c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
502 m_constraints.quick_push (*c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
503
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
504 return *this;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
505 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
506
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
507 /* Generate a hash value for this constraint_manager. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
508
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
509 hashval_t
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
510 constraint_manager::hash () const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
511 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
512 inchash::hash hstate;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
513 int i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
514 equiv_class *ec;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
515 constraint *c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
516
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
517 FOR_EACH_VEC_ELT (m_equiv_classes, i, ec)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
518 hstate.merge_hash (ec->hash ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
519 FOR_EACH_VEC_ELT (m_constraints, i, c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
520 hstate.merge_hash (c->hash ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
521 return hstate.end ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
522 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
523
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
524 /* Equality operator for constraint_manager. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
525
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
526 bool
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
527 constraint_manager::operator== (const constraint_manager &other) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
528 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
529 if (m_equiv_classes.length () != other.m_equiv_classes.length ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
530 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
531 if (m_constraints.length () != other.m_constraints.length ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
532 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
533
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
534 int i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
535 equiv_class *ec;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
536
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
537 FOR_EACH_VEC_ELT (m_equiv_classes, i, ec)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
538 if (!(*ec == *other.m_equiv_classes[i]))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
539 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
540
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
541 constraint *c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
542
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
543 FOR_EACH_VEC_ELT (m_constraints, i, c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
544 if (!(*c == other.m_constraints[i]))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
545 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
546
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
547 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
548 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
549
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
550 /* Print this constraint_manager to PP (which must support %E for trees). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
551
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
552 void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
553 constraint_manager::print (pretty_printer *pp) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
554 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
555 pp_string (pp, "{");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
556 int i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
557 equiv_class *ec;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
558 FOR_EACH_VEC_ELT (m_equiv_classes, i, ec)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
559 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
560 if (i > 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
561 pp_string (pp, ", ");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
562 equiv_class_id (i).print (pp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
563 pp_string (pp, ": ");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
564 ec->print (pp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
565 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
566 pp_string (pp, " | ");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
567 constraint *c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
568 FOR_EACH_VEC_ELT (m_constraints, i, c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
569 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
570 if (i > 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
571 pp_string (pp, " && ");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
572 c->print (pp, *this);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
573 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
574 pp_printf (pp, "}");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
575 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
576
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
577 /* Dump a multiline representation of this constraint_manager to PP
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
578 (which must support %E for trees). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
579
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
580 void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
581 constraint_manager::dump_to_pp (pretty_printer *pp) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
582 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
583 // TODO
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
584 pp_string (pp, " equiv classes:");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
585 pp_newline (pp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
586 int i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
587 equiv_class *ec;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
588 FOR_EACH_VEC_ELT (m_equiv_classes, i, ec)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
589 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
590 pp_string (pp, " ");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
591 equiv_class_id (i).print (pp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
592 pp_string (pp, ": ");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
593 ec->print (pp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
594 pp_newline (pp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
595 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
596 pp_string (pp, " constraints:");
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
597 pp_newline (pp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
598 constraint *c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
599 FOR_EACH_VEC_ELT (m_constraints, i, c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
600 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
601 pp_printf (pp, " %i: ", i);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
602 c->print (pp, *this);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
603 pp_newline (pp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
604 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
605 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
606
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
607 /* Dump a multiline representation of this constraint_manager to FP. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
608
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
609 void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
610 constraint_manager::dump (FILE *fp) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
611 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
612 pretty_printer pp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
613 pp_format_decoder (&pp) = default_tree_printer;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
614 pp_show_color (&pp) = pp_show_color (global_dc->printer);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
615 pp.buffer->stream = fp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
616 dump_to_pp (&pp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
617 pp_flush (&pp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
618 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
619
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
620 /* Dump a multiline representation of this constraint_manager to stderr. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
621
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
622 DEBUG_FUNCTION void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
623 constraint_manager::dump () const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
624 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
625 dump (stderr);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
626 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
627
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
628 /* Dump a multiline representation of CM to stderr. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
629
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
630 DEBUG_FUNCTION void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
631 debug (const constraint_manager &cm)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
632 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
633 cm.dump ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
634 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
635
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
636 /* Attempt to add the constraint LHS OP RHS to this constraint_manager.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
637 Return true if the constraint could be added (or is already true).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
638 Return false if the constraint contradicts existing knowledge. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
639
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
640 bool
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
641 constraint_manager::add_constraint (svalue_id lhs,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
642 enum tree_code op,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
643 svalue_id rhs)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
644 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
645 equiv_class_id lhs_ec_id = get_or_add_equiv_class (lhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
646 equiv_class_id rhs_ec_id = get_or_add_equiv_class (rhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
647 return add_constraint (lhs_ec_id, op,rhs_ec_id);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
648 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
649
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
650 /* Attempt to add the constraint LHS_EC_ID OP RHS_EC_ID to this
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
651 constraint_manager.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
652 Return true if the constraint could be added (or is already true).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
653 Return false if the constraint contradicts existing knowledge. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
654
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
655 bool
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
656 constraint_manager::add_constraint (equiv_class_id lhs_ec_id,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
657 enum tree_code op,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
658 equiv_class_id rhs_ec_id)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
659 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
660 tristate t = eval_condition (lhs_ec_id, op, rhs_ec_id);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
661
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
662 /* Discard constraints that are already known. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
663 if (t.is_true ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
664 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
665
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
666 /* Reject unsatisfiable constraints. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
667 if (t.is_false ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
668 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
669
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
670 gcc_assert (lhs_ec_id != rhs_ec_id);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
671
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
672 /* For now, simply accumulate constraints, without attempting any further
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
673 optimization. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
674 switch (op)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
675 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
676 case EQ_EXPR:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
677 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
678 /* Merge rhs_ec into lhs_ec. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
679 equiv_class &lhs_ec_obj = lhs_ec_id.get_obj (*this);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
680 const equiv_class &rhs_ec_obj = rhs_ec_id.get_obj (*this);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
681
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
682 int i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
683 svalue_id *sid;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
684 FOR_EACH_VEC_ELT (rhs_ec_obj.m_vars, i, sid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
685 lhs_ec_obj.add (*sid, *this);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
686
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
687 if (rhs_ec_obj.m_constant)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
688 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
689 lhs_ec_obj.m_constant = rhs_ec_obj.m_constant;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
690 lhs_ec_obj.m_cst_sid = rhs_ec_obj.m_cst_sid;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
691 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
692
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
693 /* Drop rhs equivalence class, overwriting it with the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
694 final ec (which might be the same one). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
695 equiv_class_id final_ec_id = m_equiv_classes.length () - 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
696 equiv_class *old_ec = m_equiv_classes[rhs_ec_id.m_idx];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
697 equiv_class *final_ec = m_equiv_classes.pop ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
698 if (final_ec != old_ec)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
699 m_equiv_classes[rhs_ec_id.m_idx] = final_ec;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
700 delete old_ec;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
701
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
702 /* Update the constraints. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
703 constraint *c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
704 FOR_EACH_VEC_ELT (m_constraints, i, c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
705 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
706 /* Update references to the rhs_ec so that
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
707 they refer to the lhs_ec. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
708 if (c->m_lhs == rhs_ec_id)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
709 c->m_lhs = lhs_ec_id;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
710 if (c->m_rhs == rhs_ec_id)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
711 c->m_rhs = lhs_ec_id;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
712
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
713 /* Renumber all constraints that refer to the final rhs_ec
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
714 to the old rhs_ec, where the old final_ec now lives. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
715 if (c->m_lhs == final_ec_id)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
716 c->m_lhs = rhs_ec_id;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
717 if (c->m_rhs == final_ec_id)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
718 c->m_rhs = rhs_ec_id;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
719 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
720 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
721 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
722 case GE_EXPR:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
723 add_constraint_internal (rhs_ec_id, CONSTRAINT_LE, lhs_ec_id);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
724 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
725 case LE_EXPR:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
726 add_constraint_internal (lhs_ec_id, CONSTRAINT_LE, rhs_ec_id);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
727 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
728 case NE_EXPR:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
729 add_constraint_internal (lhs_ec_id, CONSTRAINT_NE, rhs_ec_id);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
730 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
731 case GT_EXPR:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
732 add_constraint_internal (rhs_ec_id, CONSTRAINT_LT, lhs_ec_id);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
733 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
734 case LT_EXPR:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
735 add_constraint_internal (lhs_ec_id, CONSTRAINT_LT, rhs_ec_id);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
736 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
737 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
738 /* do nothing. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
739 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
740 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
741 validate ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
742 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
743 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
744
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
745 /* Subroutine of constraint_manager::add_constraint, for handling all
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
746 operations other than equality (for which equiv classes are merged). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
747
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
748 void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
749 constraint_manager::add_constraint_internal (equiv_class_id lhs_id,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
750 enum constraint_op c_op,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
751 equiv_class_id rhs_id)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
752 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
753 /* Add the constraint. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
754 m_constraints.safe_push (constraint (lhs_id, c_op, rhs_id));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
755
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
756 if (!flag_analyzer_transitivity)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
757 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
758
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
759 if (c_op != CONSTRAINT_NE)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
760 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
761 /* The following can potentially add EQ_EXPR facts, which could lead
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
762 to ECs being merged, which would change the meaning of the EC IDs.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
763 Hence we need to do this via representatives. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
764 svalue_id lhs = lhs_id.get_obj (*this).get_representative ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
765 svalue_id rhs = rhs_id.get_obj (*this).get_representative ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
766
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
767 /* We have LHS </<= RHS */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
768
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
769 /* Handle transitivity of ordering by adding additional constraints
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
770 based on what we already knew.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
771
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
772 So if we have already have:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
773 (a < b)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
774 (c < d)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
775 Then adding:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
776 (b < c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
777 will also add:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
778 (a < c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
779 (b < d)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
780 We need to recurse to ensure we also add:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
781 (a < d).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
782 We call the checked add_constraint to avoid adding constraints
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
783 that are already present. Doing so also ensures termination
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
784 in the case of cycles.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
785
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
786 We also check for single-element ranges, adding EQ_EXPR facts
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
787 where we discover them. For example 3 < x < 5 implies
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
788 that x == 4 (if x is an integer). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
789 for (unsigned i = 0; i < m_constraints.length (); i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
790 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
791 const constraint *other = &m_constraints[i];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
792 if (other->is_ordering_p ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
793 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
794 /* Refresh the EC IDs, in case any mergers have happened. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
795 lhs_id = get_or_add_equiv_class (lhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
796 rhs_id = get_or_add_equiv_class (rhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
797
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
798 tree lhs_const = lhs_id.get_obj (*this).m_constant;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
799 tree rhs_const = rhs_id.get_obj (*this).m_constant;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
800 tree other_lhs_const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
801 = other->m_lhs.get_obj (*this).m_constant;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
802 tree other_rhs_const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
803 = other->m_rhs.get_obj (*this).m_constant;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
804
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
805 /* We have "LHS </<= RHS" and "other.lhs </<= other.rhs". */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
806
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
807 /* If we have LHS </<= RHS and RHS </<= LHS, then we have a
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
808 cycle. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
809 if (rhs_id == other->m_lhs
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
810 && other->m_rhs == lhs_id)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
811 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
812 /* We must have equality for this to be possible. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
813 gcc_assert (c_op == CONSTRAINT_LE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
814 && other->m_op == CONSTRAINT_LE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
815 add_constraint (lhs_id, EQ_EXPR, rhs_id);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
816 /* Adding an equality will merge the two ECs and potentially
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
817 reorganize the constraints. Stop iterating. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
818 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
819 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
820 /* Otherwise, check for transitivity. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
821 if (rhs_id == other->m_lhs)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
822 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
823 /* With RHS == other.lhs, we have:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
824 "LHS </<= (RHS, other.lhs) </<= other.rhs"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
825 and thus this implies "LHS </<= other.rhs". */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
826
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
827 /* Do we have a tightly-constrained range? */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
828 if (lhs_const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
829 && !rhs_const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
830 && other_rhs_const)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
831 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
832 range r (bound (lhs_const, c_op == CONSTRAINT_LE),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
833 bound (other_rhs_const,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
834 other->m_op == CONSTRAINT_LE));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
835 tree constant;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
836 if (r.constrained_to_single_element (&constant))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
837 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
838 svalue_id cst_sid = get_sid_for_constant (constant);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
839 add_constraint
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
840 (rhs_id, EQ_EXPR,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
841 get_or_add_equiv_class (cst_sid));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
842 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
843 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
844 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
845
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
846 /* Otherwise, add the constraint implied by transitivity. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
847 enum tree_code new_op
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
848 = ((c_op == CONSTRAINT_LE && other->m_op == CONSTRAINT_LE)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
849 ? LE_EXPR : LT_EXPR);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
850 add_constraint (lhs_id, new_op, other->m_rhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
851 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
852 else if (other->m_rhs == lhs_id)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
853 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
854 /* With other.rhs == LHS, we have:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
855 "other.lhs </<= (other.rhs, LHS) </<= RHS"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
856 and thus this implies "other.lhs </<= RHS". */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
857
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
858 /* Do we have a tightly-constrained range? */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
859 if (other_lhs_const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
860 && !lhs_const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
861 && rhs_const)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
862 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
863 range r (bound (other_lhs_const,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
864 other->m_op == CONSTRAINT_LE),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
865 bound (rhs_const,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
866 c_op == CONSTRAINT_LE));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
867 tree constant;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
868 if (r.constrained_to_single_element (&constant))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
869 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
870 svalue_id cst_sid = get_sid_for_constant (constant);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
871 add_constraint
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
872 (lhs_id, EQ_EXPR,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
873 get_or_add_equiv_class (cst_sid));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
874 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
875 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
876 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
877
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
878 /* Otherwise, add the constraint implied by transitivity. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
879 enum tree_code new_op
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
880 = ((c_op == CONSTRAINT_LE && other->m_op == CONSTRAINT_LE)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
881 ? LE_EXPR : LT_EXPR);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
882 add_constraint (other->m_lhs, new_op, rhs_id);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
883 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
884 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
885 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
886 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
887 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
888
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
889 /* Look for SID within the equivalence classes of this constraint_manager;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
890 if found, write the id to *OUT and return true, otherwise return false. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
891
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
892 bool
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
893 constraint_manager::get_equiv_class_by_sid (svalue_id sid, equiv_class_id *out) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
894 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
895 /* TODO: should we have a map, rather than these searches? */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
896 int i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
897 equiv_class *ec;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
898 FOR_EACH_VEC_ELT (m_equiv_classes, i, ec)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
899 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
900 int j;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
901 svalue_id *iv;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
902 FOR_EACH_VEC_ELT (ec->m_vars, j, iv)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
903 if (*iv == sid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
904 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
905 *out = equiv_class_id (i);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
906 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
907 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
908 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
909 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
910 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
911
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
912 /* Ensure that SID has an equivalence class within this constraint_manager;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
913 return the ID of the class. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
914
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
915 equiv_class_id
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
916 constraint_manager::get_or_add_equiv_class (svalue_id sid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
917 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
918 equiv_class_id result (-1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
919
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
920 /* Try svalue_id match. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
921 if (get_equiv_class_by_sid (sid, &result))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
922 return result;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
923
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
924 /* Try equality of constants. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
925 if (tree cst = maybe_get_constant (sid))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
926 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
927 int i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
928 equiv_class *ec;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
929 FOR_EACH_VEC_ELT (m_equiv_classes, i, ec)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
930 if (ec->m_constant
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
931 && types_compatible_p (TREE_TYPE (cst),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
932 TREE_TYPE (ec->m_constant)))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
933 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
934 tree eq = fold_binary (EQ_EXPR, boolean_type_node,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
935 cst, ec->m_constant);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
936 if (eq == boolean_true_node)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
937 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
938 ec->add (sid, *this);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
939 return equiv_class_id (i);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
940 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
941 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
942 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
943
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
944
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
945 /* Not found. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
946 equiv_class *new_ec = new equiv_class ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
947 new_ec->add (sid, *this);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
948 m_equiv_classes.safe_push (new_ec);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
949
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
950 equiv_class_id new_id (m_equiv_classes.length () - 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
951
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
952 if (maybe_get_constant (sid))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
953 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
954 /* If we have a new EC for a constant, add constraints comparing this
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
955 to other constants we may have (so that we accumulate the transitive
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
956 closure of all constraints on constants as the constants are
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
957 added). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
958 for (equiv_class_id other_id (0); other_id.m_idx < new_id.m_idx;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
959 other_id.m_idx++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
960 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
961 const equiv_class &other_ec = other_id.get_obj (*this);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
962 if (other_ec.m_constant
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
963 && types_compatible_p (TREE_TYPE (new_ec->m_constant),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
964 TREE_TYPE (other_ec.m_constant)))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
965 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
966 /* If we have two ECs, both with constants, the constants must be
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
967 non-equal (or they would be in the same EC).
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
968 Determine the direction of the inequality, and record that
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
969 fact. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
970 tree lt
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
971 = fold_binary (LT_EXPR, boolean_type_node,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
972 new_ec->m_constant, other_ec.m_constant);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
973 if (lt == boolean_true_node)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
974 add_constraint_internal (new_id, CONSTRAINT_LT, other_id);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
975 else if (lt == boolean_false_node)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
976 add_constraint_internal (other_id, CONSTRAINT_LT, new_id);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
977 /* Refresh new_id, in case ECs were merged. SID should always
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
978 be present by now, so this should never lead to a
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
979 recursion. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
980 new_id = get_or_add_equiv_class (sid);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
981 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
982 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
983 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
984
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
985 return new_id;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
986 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
987
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
988 /* Evaluate the condition LHS_EC OP RHS_EC. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
989
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
990 tristate
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
991 constraint_manager::eval_condition (equiv_class_id lhs_ec,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
992 enum tree_code op,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
993 equiv_class_id rhs_ec)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
994 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
995 if (lhs_ec == rhs_ec)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
996 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
997 switch (op)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
998 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
999 case EQ_EXPR:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1000 case GE_EXPR:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1001 case LE_EXPR:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1002 return tristate (tristate::TS_TRUE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1003
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1004 case NE_EXPR:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1005 case GT_EXPR:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1006 case LT_EXPR:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1007 return tristate (tristate::TS_FALSE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1008 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1009 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1010 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1011 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1012
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1013 tree lhs_const = lhs_ec.get_obj (*this).get_any_constant ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1014 tree rhs_const = rhs_ec.get_obj (*this).get_any_constant ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1015 if (lhs_const && rhs_const)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1016 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1017 tree comparison
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1018 = fold_binary (op, boolean_type_node, lhs_const, rhs_const);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1019 if (comparison == boolean_true_node)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1020 return tristate (tristate::TS_TRUE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1021 if (comparison == boolean_false_node)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1022 return tristate (tristate::TS_FALSE);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1023 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1024
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1025 enum tree_code swapped_op = swap_tree_comparison (op);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1026
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1027 int i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1028 constraint *c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1029 FOR_EACH_VEC_ELT (m_constraints, i, c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1030 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1031 if (c->m_lhs == lhs_ec
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1032 && c->m_rhs == rhs_ec)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1033 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1034 tristate result_for_constraint
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1035 = eval_constraint_op_for_op (c->m_op, op);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1036 if (result_for_constraint.is_known ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1037 return result_for_constraint;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1038 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1039 /* Swapped operands. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1040 if (c->m_lhs == rhs_ec
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1041 && c->m_rhs == lhs_ec)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1042 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1043 tristate result_for_constraint
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1044 = eval_constraint_op_for_op (c->m_op, swapped_op);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1045 if (result_for_constraint.is_known ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1046 return result_for_constraint;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1047 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1048 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1049
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1050 return tristate (tristate::TS_UNKNOWN);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1051 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1052
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1053 /* Evaluate the condition LHS OP RHS, creating equiv_class instances for
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1054 LHS and RHS if they aren't already in equiv_classes. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1055
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1056 tristate
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1057 constraint_manager::eval_condition (svalue_id lhs,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1058 enum tree_code op,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1059 svalue_id rhs)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1060 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1061 return eval_condition (get_or_add_equiv_class (lhs),
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1062 op,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1063 get_or_add_equiv_class (rhs));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1064 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1065
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1066 /* Delete any information about svalue_id instances identified by P.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1067 Such instances are removed from equivalence classes, and any
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1068 redundant ECs and constraints are also removed.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1069 Accumulate stats into STATS. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1070
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1071 void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1072 constraint_manager::purge (const purge_criteria &p, purge_stats *stats)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1073 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1074 /* Delete any svalue_ids identified by P within the various equivalence
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1075 classes. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1076 for (unsigned ec_idx = 0; ec_idx < m_equiv_classes.length (); )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1077 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1078 equiv_class *ec = m_equiv_classes[ec_idx];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1079
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1080 int i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1081 svalue_id *pv;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1082 bool delete_ec = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1083 FOR_EACH_VEC_ELT (ec->m_vars, i, pv)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1084 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1085 if (*pv == ec->m_cst_sid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1086 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1087 if (p.should_purge_p (*pv))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1088 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1089 if (ec->del (*pv))
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1090 if (!ec->m_constant)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1091 delete_ec = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1092 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1093 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1094
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1095 if (delete_ec)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1096 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1097 delete ec;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1098 m_equiv_classes.ordered_remove (ec_idx);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1099 if (stats)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1100 stats->m_num_equiv_classes++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1101
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1102 /* Update the constraints, potentially removing some. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1103 for (unsigned con_idx = 0; con_idx < m_constraints.length (); )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1104 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1105 constraint *c = &m_constraints[con_idx];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1106
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1107 /* Remove constraints that refer to the deleted EC. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1108 if (c->m_lhs == ec_idx
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1109 || c->m_rhs == ec_idx)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1110 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1111 m_constraints.ordered_remove (con_idx);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1112 if (stats)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1113 stats->m_num_constraints++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1114 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1115 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1116 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1117 /* Renumber constraints that refer to ECs that have
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1118 had their idx changed. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1119 c->m_lhs.update_for_removal (ec_idx);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1120 c->m_rhs.update_for_removal (ec_idx);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1121
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1122 con_idx++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1123 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1124 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1125 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1126 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1127 ec_idx++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1128 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1129
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1130 /* Now delete any constraints that are purely between constants. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1131 for (unsigned con_idx = 0; con_idx < m_constraints.length (); )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1132 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1133 constraint *c = &m_constraints[con_idx];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1134 if (m_equiv_classes[c->m_lhs.m_idx]->m_vars.length () == 0
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1135 && m_equiv_classes[c->m_rhs.m_idx]->m_vars.length () == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1136 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1137 m_constraints.ordered_remove (con_idx);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1138 if (stats)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1139 stats->m_num_constraints++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1140 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1141 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1142 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1143 con_idx++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1144 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1145 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1146
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1147 /* Finally, delete any ECs that purely contain constants and aren't
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1148 referenced by any constraints. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1149 for (unsigned ec_idx = 0; ec_idx < m_equiv_classes.length (); )
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1150 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1151 equiv_class *ec = m_equiv_classes[ec_idx];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1152 if (ec->m_vars.length () == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1153 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1154 equiv_class_id ec_id (ec_idx);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1155 bool has_constraint = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1156 for (unsigned con_idx = 0; con_idx < m_constraints.length ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1157 con_idx++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1158 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1159 constraint *c = &m_constraints[con_idx];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1160 if (c->m_lhs == ec_id
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1161 || c->m_rhs == ec_id)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1162 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1163 has_constraint = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1164 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1165 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1166 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1167 if (!has_constraint)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1168 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1169 delete ec;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1170 m_equiv_classes.ordered_remove (ec_idx);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1171 if (stats)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1172 stats->m_num_equiv_classes++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1173
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1174 /* Renumber constraints that refer to ECs that have
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1175 had their idx changed. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1176 for (unsigned con_idx = 0; con_idx < m_constraints.length ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1177 con_idx++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1178 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1179 constraint *c = &m_constraints[con_idx];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1180 c->m_lhs.update_for_removal (ec_idx);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1181 c->m_rhs.update_for_removal (ec_idx);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1182 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1183 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1184 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1185 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1186 ec_idx++;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1187 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1188
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1189 validate ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1190 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1191
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1192 /* Remap all svalue_ids within this constraint_manager using MAP. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1193
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1194 void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1195 constraint_manager::remap_svalue_ids (const svalue_id_map &map)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1196 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1197 int i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1198 equiv_class *ec;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1199 FOR_EACH_VEC_ELT (m_equiv_classes, i, ec)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1200 ec->remap_svalue_ids (map);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1201 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1202
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1203 /* Comparator for use by constraint_manager::canonicalize.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1204 Sort a pair of equiv_class instances, using the representative
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1205 svalue_id as a sort key. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1206
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1207 static int
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1208 equiv_class_cmp (const void *p1, const void *p2)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1209 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1210 const equiv_class *ec1 = *(const equiv_class * const *)p1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1211 const equiv_class *ec2 = *(const equiv_class * const *)p2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1212
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1213 svalue_id rep1 = ec1->get_representative ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1214 svalue_id rep2 = ec2->get_representative ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1215
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1216 return rep1.as_int () - rep2.as_int ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1217 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1218
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1219 /* Comparator for use by constraint_manager::canonicalize.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1220 Sort a pair of constraint instances. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1221
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1222 static int
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1223 constraint_cmp (const void *p1, const void *p2)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1224 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1225 const constraint *c1 = (const constraint *)p1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1226 const constraint *c2 = (const constraint *)p2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1227 int lhs_cmp = c1->m_lhs.as_int () - c2->m_lhs.as_int ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1228 if (lhs_cmp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1229 return lhs_cmp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1230 int rhs_cmp = c1->m_rhs.as_int () - c2->m_rhs.as_int ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1231 if (rhs_cmp)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1232 return rhs_cmp;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1233 return c1->m_op - c2->m_op;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1234 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1235
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1236 /* Reorder the equivalence classes and constraints within this
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1237 constraint_manager into a canonical order, to increase the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1238 chances of finding equality with another instance. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1239
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1240 void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1241 constraint_manager::canonicalize (unsigned num_svalue_ids)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1242 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1243 /* First, sort svalue_ids within the ECs. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1244 unsigned i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1245 equiv_class *ec;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1246 FOR_EACH_VEC_ELT (m_equiv_classes, i, ec)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1247 ec->canonicalize ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1248
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1249 /* Next, sort the ECs into a canonical order. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1250
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1251 /* We will need to remap the equiv_class_ids in the constraints,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1252 so we need to store the original index of each EC.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1253 Build a lookup table, mapping from representative svalue_id
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1254 to the original equiv_class_id of that svalue_id. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1255 auto_vec<equiv_class_id> original_ec_id (num_svalue_ids);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1256 for (i = 0; i < num_svalue_ids; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1257 original_ec_id.quick_push (equiv_class_id::null ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1258 FOR_EACH_VEC_ELT (m_equiv_classes, i, ec)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1259 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1260 svalue_id rep = ec->get_representative ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1261 gcc_assert (!rep.null_p ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1262 original_ec_id[rep.as_int ()] = i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1263 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1264
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1265 /* Sort the equivalence classes. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1266 m_equiv_classes.qsort (equiv_class_cmp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1267
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1268 /* Populate ec_id_map based on the old vs new EC ids. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1269 one_way_id_map<equiv_class_id> ec_id_map (m_equiv_classes.length ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1270 FOR_EACH_VEC_ELT (m_equiv_classes, i, ec)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1271 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1272 svalue_id rep = ec->get_representative ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1273 ec_id_map.put (original_ec_id[rep.as_int ()], i);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1274 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1275
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1276 /* Update the EC ids within the constraints. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1277 constraint *c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1278 FOR_EACH_VEC_ELT (m_constraints, i, c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1279 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1280 ec_id_map.update (&c->m_lhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1281 ec_id_map.update (&c->m_rhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1282 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1283
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1284 /* Finally, sort the constraints. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1285 m_constraints.qsort (constraint_cmp);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1286 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1287
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1288 /* A concrete subclass of constraint_manager for use when
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1289 merging two constraint_manager into a third constraint_manager,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1290 each of which has its own region_model.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1291 Calls are delegated to the constraint_manager for the merged model,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1292 and thus affect its region_model. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1293
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1294 class cleaned_constraint_manager : public constraint_manager
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1295 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1296 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1297 cleaned_constraint_manager (constraint_manager *merged) : m_merged (merged) {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1298
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1299 constraint_manager *clone (region_model *) const FINAL OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1300 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1301 gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1302 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1303 tree maybe_get_constant (svalue_id sid) const FINAL OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1304 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1305 return m_merged->maybe_get_constant (sid);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1306 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1307 svalue_id get_sid_for_constant (tree cst) const FINAL OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1308 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1309 return m_merged->get_sid_for_constant (cst);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1310 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1311 virtual int get_num_svalues () const FINAL OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1312 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1313 return m_merged->get_num_svalues ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1314 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1315 private:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1316 constraint_manager *m_merged;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1317 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1318
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1319 /* Concrete subclass of fact_visitor for use by constraint_manager::merge.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1320 For every fact in CM_A, see if it is also true in *CM_B. Add such
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1321 facts to *OUT. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1322
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1323 class merger_fact_visitor : public fact_visitor
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1324 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1325 public:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1326 merger_fact_visitor (constraint_manager *cm_b,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1327 constraint_manager *out)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1328 : m_cm_b (cm_b), m_out (out)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1329 {}
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1330
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1331 void on_fact (svalue_id lhs, enum tree_code code, svalue_id rhs)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1332 FINAL OVERRIDE
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1333 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1334 if (m_cm_b->eval_condition (lhs, code, rhs).is_true ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1335 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1336 bool sat = m_out->add_constraint (lhs, code, rhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1337 gcc_assert (sat);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1338 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1339 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1340
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1341 private:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1342 constraint_manager *m_cm_b;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1343 constraint_manager *m_out;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1344 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1345
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1346 /* Use MERGER to merge CM_A and CM_B into *OUT.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1347 If one thinks of a constraint_manager as a subset of N-dimensional
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1348 space, this takes the union of the points of CM_A and CM_B, and
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1349 expresses that into *OUT. Alternatively, it can be thought of
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1350 as the intersection of the constraints. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1351
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1352 void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1353 constraint_manager::merge (const constraint_manager &cm_a,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1354 const constraint_manager &cm_b,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1355 constraint_manager *out,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1356 const model_merger &merger)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1357 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1358 gcc_assert (merger.m_sid_mapping);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1359
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1360 /* Map svalue_ids in each equiv class from both sources
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1361 to the merged region_model, dropping ids that don't survive merger,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1362 and potentially creating svalues in *OUT for constants. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1363 cleaned_constraint_manager cleaned_cm_a (out);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1364 const one_way_svalue_id_map &map_a_to_m
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1365 = merger.m_sid_mapping->m_map_from_a_to_m;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1366 clean_merger_input (cm_a, map_a_to_m, &cleaned_cm_a);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1367
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1368 cleaned_constraint_manager cleaned_cm_b (out);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1369 const one_way_svalue_id_map &map_b_to_m
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1370 = merger.m_sid_mapping->m_map_from_b_to_m;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1371 clean_merger_input (cm_b, map_b_to_m, &cleaned_cm_b);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1372
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1373 /* At this point, the two cleaned CMs have ECs and constraints referring
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1374 to svalues in the merged region model, but both of them have separate
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1375 ECs. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1376
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1377 /* Merge the equivalence classes and constraints.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1378 The easiest way to do this seems to be to enumerate all of the facts
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1379 in cleaned_cm_a, see which are also true in cleaned_cm_b,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1380 and add those to *OUT. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1381 merger_fact_visitor v (&cleaned_cm_b, out);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1382 cleaned_cm_a.for_each_fact (&v);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1383 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1384
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1385 /* A subroutine of constraint_manager::merge.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1386 Use MAP_SID_TO_M to map equivalence classes and constraints from
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1387 SM_IN to *OUT. Purge any non-constant svalue_id that don't appear
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1388 in the result of MAP_SID_TO_M, purging any ECs and their constraints
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1389 that become empty as a result. Potentially create svalues in
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1390 the merged region_model for constants that weren't already in use there. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1391
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1392 void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1393 constraint_manager::
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1394 clean_merger_input (const constraint_manager &cm_in,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1395 const one_way_svalue_id_map &map_sid_to_m,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1396 constraint_manager *out)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1397 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1398 one_way_id_map<equiv_class_id> map_ec_to_m
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1399 (cm_in.m_equiv_classes.length ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1400 unsigned ec_idx;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1401 equiv_class *ec;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1402 FOR_EACH_VEC_ELT (cm_in.m_equiv_classes, ec_idx, ec)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1403 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1404 equiv_class cleaned_ec;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1405 if (tree cst = ec->get_any_constant ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1406 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1407 cleaned_ec.m_constant = cst;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1408 /* Lazily create the constant in the out region_model. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1409 cleaned_ec.m_cst_sid = out->get_sid_for_constant (cst);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1410 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1411 unsigned var_idx;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1412 svalue_id *var_in_sid;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1413 FOR_EACH_VEC_ELT (ec->m_vars, var_idx, var_in_sid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1414 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1415 svalue_id var_m_sid = map_sid_to_m.get_dst_for_src (*var_in_sid);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1416 if (!var_m_sid.null_p ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1417 cleaned_ec.m_vars.safe_push (var_m_sid);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1418 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1419 if (cleaned_ec.get_any_constant () || !cleaned_ec.m_vars.is_empty ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1420 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1421 map_ec_to_m.put (ec_idx, out->m_equiv_classes.length ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1422 out->m_equiv_classes.safe_push (new equiv_class (cleaned_ec));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1423 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1424 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1425
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1426 /* Write out to *OUT any constraints for which both sides survived
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1427 cleaning, using the new EC IDs. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1428 unsigned con_idx;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1429 constraint *c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1430 FOR_EACH_VEC_ELT (cm_in.m_constraints, con_idx, c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1431 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1432 equiv_class_id new_lhs = map_ec_to_m.get_dst_for_src (c->m_lhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1433 if (new_lhs.null_p ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1434 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1435 equiv_class_id new_rhs = map_ec_to_m.get_dst_for_src (c->m_rhs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1436 if (new_rhs.null_p ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1437 continue;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1438 out->m_constraints.safe_push (constraint (new_lhs,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1439 c->m_op,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1440 new_rhs));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1441 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1442 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1443
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1444 /* Call VISITOR's on_fact vfunc repeatedly to express the various
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1445 equivalence classes and constraints.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1446 This is used by constraint_manager::merge to find the common
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1447 facts between two input constraint_managers. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1448
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1449 void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1450 constraint_manager::for_each_fact (fact_visitor *visitor) const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1451 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1452 /* First, call EQ_EXPR within the various equivalence classes. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1453 unsigned ec_idx;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1454 equiv_class *ec;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1455 FOR_EACH_VEC_ELT (m_equiv_classes, ec_idx, ec)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1456 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1457 if (!ec->m_cst_sid.null_p ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1458 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1459 unsigned i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1460 svalue_id *sid;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1461 FOR_EACH_VEC_ELT (ec->m_vars, i, sid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1462 visitor->on_fact (ec->m_cst_sid, EQ_EXPR, *sid);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1463 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1464 for (unsigned i = 0; i < ec->m_vars.length (); i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1465 for (unsigned j = i + 1; j < ec->m_vars.length (); j++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1466 visitor->on_fact (ec->m_vars[i], EQ_EXPR, ec->m_vars[j]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1467 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1468
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1469 /* Now, express the various constraints. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1470 unsigned con_idx;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1471 constraint *c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1472 FOR_EACH_VEC_ELT (m_constraints, con_idx, c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1473 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1474 const equiv_class &ec_lhs = c->m_lhs.get_obj (*this);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1475 const equiv_class &ec_rhs = c->m_rhs.get_obj (*this);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1476 enum tree_code code = constraint_tree_code (c->m_op);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1477
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1478 if (!ec_lhs.m_cst_sid.null_p ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1479 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1480 for (unsigned j = 0; j < ec_rhs.m_vars.length (); j++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1481 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1482 visitor->on_fact (ec_lhs.m_cst_sid, code, ec_rhs.m_vars[j]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1483 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1484 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1485 for (unsigned i = 0; i < ec_lhs.m_vars.length (); i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1486 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1487 if (!ec_rhs.m_cst_sid.null_p ())
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1488 visitor->on_fact (ec_lhs.m_vars[i], code, ec_rhs.m_cst_sid);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1489 for (unsigned j = 0; j < ec_rhs.m_vars.length (); j++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1490 visitor->on_fact (ec_lhs.m_vars[i], code, ec_rhs.m_vars[j]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1491 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1492 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1493 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1494
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1495 /* Assert that this object is valid. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1496
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1497 void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1498 constraint_manager::validate () const
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1499 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1500 /* Skip this in a release build. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1501 #if !CHECKING_P
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1502 return;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1503 #endif
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1504
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1505 int i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1506 equiv_class *ec;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1507 FOR_EACH_VEC_ELT (m_equiv_classes, i, ec)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1508 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1509 gcc_assert (ec);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1510
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1511 int j;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1512 svalue_id *sid;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1513 FOR_EACH_VEC_ELT (ec->m_vars, j, sid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1514 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1515 gcc_assert (!sid->null_p ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1516 gcc_assert (sid->as_int () < get_num_svalues ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1517 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1518 if (ec->m_constant)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1519 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1520 gcc_assert (CONSTANT_CLASS_P (ec->m_constant));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1521 gcc_assert (!ec->m_cst_sid.null_p ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1522 gcc_assert (ec->m_cst_sid.as_int () < get_num_svalues ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1523 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1524 #if 0
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1525 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1526 gcc_assert (ec->m_vars.length () > 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1527 #endif
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1528 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1529
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1530 constraint *c;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1531 FOR_EACH_VEC_ELT (m_constraints, i, c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1532 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1533 gcc_assert (!c->m_lhs.null_p ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1534 gcc_assert (c->m_lhs.as_int () <= (int)m_equiv_classes.length ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1535 gcc_assert (!c->m_rhs.null_p ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1536 gcc_assert (c->m_rhs.as_int () <= (int)m_equiv_classes.length ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1537 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1538 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1539
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1540 #if CHECKING_P
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1541
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1542 namespace selftest {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1543
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1544 /* Various constraint_manager selftests.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1545 These have to be written in terms of a region_model, since
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1546 the latter is responsible for managing svalue and svalue_id
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1547 instances. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1548
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1549 /* Verify that setting and getting simple conditions within a region_model
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1550 work (thus exercising the underlying constraint_manager). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1551
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1552 static void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1553 test_constraint_conditions ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1554 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1555 tree int_42 = build_int_cst (integer_type_node, 42);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1556 tree int_0 = build_int_cst (integer_type_node, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1557
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1558 tree x = build_global_decl ("x", integer_type_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1559 tree y = build_global_decl ("y", integer_type_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1560 tree z = build_global_decl ("z", integer_type_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1561
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1562 /* Self-comparisons. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1563 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1564 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1565 ASSERT_CONDITION_TRUE (model, x, EQ_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1566 ASSERT_CONDITION_TRUE (model, x, LE_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1567 ASSERT_CONDITION_TRUE (model, x, GE_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1568 ASSERT_CONDITION_FALSE (model, x, NE_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1569 ASSERT_CONDITION_FALSE (model, x, LT_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1570 ASSERT_CONDITION_FALSE (model, x, GT_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1571 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1572
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1573 /* x == y. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1574 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1575 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1576 ASSERT_CONDITION_UNKNOWN (model, x, EQ_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1577
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1578 ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1579
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1580 ASSERT_CONDITION_TRUE (model, x, EQ_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1581 ASSERT_CONDITION_TRUE (model, x, LE_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1582 ASSERT_CONDITION_TRUE (model, x, GE_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1583 ASSERT_CONDITION_FALSE (model, x, NE_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1584 ASSERT_CONDITION_FALSE (model, x, LT_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1585 ASSERT_CONDITION_FALSE (model, x, GT_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1586
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1587 /* Swapped operands. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1588 ASSERT_CONDITION_TRUE (model, y, EQ_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1589 ASSERT_CONDITION_TRUE (model, y, LE_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1590 ASSERT_CONDITION_TRUE (model, y, GE_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1591 ASSERT_CONDITION_FALSE (model, y, NE_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1592 ASSERT_CONDITION_FALSE (model, y, LT_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1593 ASSERT_CONDITION_FALSE (model, y, GT_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1594
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1595 /* Comparison with other var. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1596 ASSERT_CONDITION_UNKNOWN (model, x, EQ_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1597 ASSERT_CONDITION_UNKNOWN (model, x, LE_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1598 ASSERT_CONDITION_UNKNOWN (model, x, GE_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1599 ASSERT_CONDITION_UNKNOWN (model, x, NE_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1600 ASSERT_CONDITION_UNKNOWN (model, x, LT_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1601 ASSERT_CONDITION_UNKNOWN (model, x, GT_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1602 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1603
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1604 /* x == y, then y == z */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1605 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1606 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1607 ASSERT_CONDITION_UNKNOWN (model, x, EQ_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1608
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1609 ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1610 ADD_SAT_CONSTRAINT (model, y, EQ_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1611
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1612 ASSERT_CONDITION_TRUE (model, x, EQ_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1613 ASSERT_CONDITION_TRUE (model, x, LE_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1614 ASSERT_CONDITION_TRUE (model, x, GE_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1615 ASSERT_CONDITION_FALSE (model, x, NE_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1616 ASSERT_CONDITION_FALSE (model, x, LT_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1617 ASSERT_CONDITION_FALSE (model, x, GT_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1618 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1619
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1620 /* x != y. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1621 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1622 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1623
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1624 ADD_SAT_CONSTRAINT (model, x, NE_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1625
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1626 ASSERT_CONDITION_TRUE (model, x, NE_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1627 ASSERT_CONDITION_FALSE (model, x, EQ_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1628 ASSERT_CONDITION_UNKNOWN (model, x, LE_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1629 ASSERT_CONDITION_UNKNOWN (model, x, GE_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1630 ASSERT_CONDITION_UNKNOWN (model, x, LT_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1631 ASSERT_CONDITION_UNKNOWN (model, x, GT_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1632
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1633 /* Swapped operands. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1634 ASSERT_CONDITION_TRUE (model, y, NE_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1635 ASSERT_CONDITION_FALSE (model, y, EQ_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1636 ASSERT_CONDITION_UNKNOWN (model, y, LE_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1637 ASSERT_CONDITION_UNKNOWN (model, y, GE_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1638 ASSERT_CONDITION_UNKNOWN (model, y, LT_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1639 ASSERT_CONDITION_UNKNOWN (model, y, GT_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1640
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1641 /* Comparison with other var. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1642 ASSERT_CONDITION_UNKNOWN (model, x, EQ_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1643 ASSERT_CONDITION_UNKNOWN (model, x, LE_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1644 ASSERT_CONDITION_UNKNOWN (model, x, GE_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1645 ASSERT_CONDITION_UNKNOWN (model, x, NE_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1646 ASSERT_CONDITION_UNKNOWN (model, x, LT_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1647 ASSERT_CONDITION_UNKNOWN (model, x, GT_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1648 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1649
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1650 /* x < y. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1651 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1652 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1653
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1654 ADD_SAT_CONSTRAINT (model, x, LT_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1655
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1656 ASSERT_CONDITION_TRUE (model, x, LT_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1657 ASSERT_CONDITION_TRUE (model, x, LE_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1658 ASSERT_CONDITION_TRUE (model, x, NE_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1659 ASSERT_CONDITION_FALSE (model, x, EQ_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1660 ASSERT_CONDITION_FALSE (model, x, GT_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1661 ASSERT_CONDITION_FALSE (model, x, GE_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1662
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1663 /* Swapped operands. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1664 ASSERT_CONDITION_FALSE (model, y, LT_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1665 ASSERT_CONDITION_FALSE (model, y, LE_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1666 ASSERT_CONDITION_TRUE (model, y, NE_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1667 ASSERT_CONDITION_FALSE (model, y, EQ_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1668 ASSERT_CONDITION_TRUE (model, y, GT_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1669 ASSERT_CONDITION_TRUE (model, y, GE_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1670 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1671
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1672 /* x <= y. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1673 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1674 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1675
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1676 ADD_SAT_CONSTRAINT (model, x, LE_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1677
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1678 ASSERT_CONDITION_UNKNOWN (model, x, LT_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1679 ASSERT_CONDITION_TRUE (model, x, LE_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1680 ASSERT_CONDITION_UNKNOWN (model, x, NE_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1681 ASSERT_CONDITION_UNKNOWN (model, x, EQ_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1682 ASSERT_CONDITION_FALSE (model, x, GT_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1683 ASSERT_CONDITION_UNKNOWN (model, x, GE_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1684
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1685 /* Swapped operands. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1686 ASSERT_CONDITION_FALSE (model, y, LT_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1687 ASSERT_CONDITION_UNKNOWN (model, y, LE_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1688 ASSERT_CONDITION_UNKNOWN (model, y, NE_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1689 ASSERT_CONDITION_UNKNOWN (model, y, EQ_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1690 ASSERT_CONDITION_UNKNOWN (model, y, GT_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1691 ASSERT_CONDITION_TRUE (model, y, GE_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1692 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1693
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1694 /* x > y. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1695 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1696 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1697
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1698 ADD_SAT_CONSTRAINT (model, x, GT_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1699
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1700 ASSERT_CONDITION_TRUE (model, x, GT_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1701 ASSERT_CONDITION_TRUE (model, x, GE_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1702 ASSERT_CONDITION_TRUE (model, x, NE_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1703 ASSERT_CONDITION_FALSE (model, x, EQ_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1704 ASSERT_CONDITION_FALSE (model, x, LT_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1705 ASSERT_CONDITION_FALSE (model, x, LE_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1706
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1707 /* Swapped operands. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1708 ASSERT_CONDITION_FALSE (model, y, GT_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1709 ASSERT_CONDITION_FALSE (model, y, GE_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1710 ASSERT_CONDITION_TRUE (model, y, NE_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1711 ASSERT_CONDITION_FALSE (model, y, EQ_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1712 ASSERT_CONDITION_TRUE (model, y, LT_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1713 ASSERT_CONDITION_TRUE (model, y, LE_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1714 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1715
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1716 /* x >= y. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1717 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1718 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1719
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1720 ADD_SAT_CONSTRAINT (model, x, GE_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1721
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1722 ASSERT_CONDITION_UNKNOWN (model, x, GT_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1723 ASSERT_CONDITION_TRUE (model, x, GE_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1724 ASSERT_CONDITION_UNKNOWN (model, x, NE_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1725 ASSERT_CONDITION_UNKNOWN (model, x, EQ_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1726 ASSERT_CONDITION_FALSE (model, x, LT_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1727 ASSERT_CONDITION_UNKNOWN (model, x, LE_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1728
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1729 /* Swapped operands. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1730 ASSERT_CONDITION_FALSE (model, y, GT_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1731 ASSERT_CONDITION_UNKNOWN (model, y, GE_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1732 ASSERT_CONDITION_UNKNOWN (model, y, NE_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1733 ASSERT_CONDITION_UNKNOWN (model, y, EQ_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1734 ASSERT_CONDITION_UNKNOWN (model, y, LT_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1735 ASSERT_CONDITION_TRUE (model, y, LE_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1736 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1737
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1738 // TODO: implied orderings
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1739
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1740 /* Constants. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1741 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1742 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1743 ASSERT_CONDITION_FALSE (model, int_0, EQ_EXPR, int_42);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1744 ASSERT_CONDITION_TRUE (model, int_0, NE_EXPR, int_42);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1745 ASSERT_CONDITION_TRUE (model, int_0, LT_EXPR, int_42);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1746 ASSERT_CONDITION_TRUE (model, int_0, LE_EXPR, int_42);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1747 ASSERT_CONDITION_FALSE (model, int_0, GT_EXPR, int_42);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1748 ASSERT_CONDITION_FALSE (model, int_0, GE_EXPR, int_42);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1749 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1750
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1751 /* x == 0, y == 42. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1752 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1753 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1754 ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, int_0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1755 ADD_SAT_CONSTRAINT (model, y, EQ_EXPR, int_42);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1756
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1757 ASSERT_CONDITION_TRUE (model, x, NE_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1758 ASSERT_CONDITION_FALSE (model, x, EQ_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1759 ASSERT_CONDITION_TRUE (model, x, LE_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1760 ASSERT_CONDITION_FALSE (model, x, GE_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1761 ASSERT_CONDITION_TRUE (model, x, LT_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1762 ASSERT_CONDITION_FALSE (model, x, GT_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1763 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1764
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1765 /* Unsatisfiable combinations. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1766
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1767 /* x == y && x != y. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1768 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1769 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1770 ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1771 ADD_UNSAT_CONSTRAINT (model, x, NE_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1772 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1773
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1774 /* x == 0 then x == 42. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1775 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1776 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1777 ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, int_0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1778 ADD_UNSAT_CONSTRAINT (model, x, EQ_EXPR, int_42);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1779 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1780
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1781 /* x == 0 then x != 0. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1782 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1783 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1784 ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, int_0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1785 ADD_UNSAT_CONSTRAINT (model, x, NE_EXPR, int_0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1786 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1787
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1788 /* x == 0 then x > 0. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1789 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1790 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1791 ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, int_0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1792 ADD_UNSAT_CONSTRAINT (model, x, GT_EXPR, int_0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1793 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1794
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1795 /* x != y && x == y. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1796 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1797 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1798 ADD_SAT_CONSTRAINT (model, x, NE_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1799 ADD_UNSAT_CONSTRAINT (model, x, EQ_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1800 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1801
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1802 /* x <= y && x > y. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1803 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1804 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1805 ADD_SAT_CONSTRAINT (model, x, LE_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1806 ADD_UNSAT_CONSTRAINT (model, x, GT_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1807 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1808
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1809 // etc
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1810 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1811
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1812 /* Test transitivity of conditions. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1813
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1814 static void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1815 test_transitivity ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1816 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1817 tree a = build_global_decl ("a", integer_type_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1818 tree b = build_global_decl ("b", integer_type_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1819 tree c = build_global_decl ("c", integer_type_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1820 tree d = build_global_decl ("d", integer_type_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1821
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1822 /* a == b, then c == d, then c == b. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1823 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1824 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1825 ASSERT_CONDITION_UNKNOWN (model, a, EQ_EXPR, b);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1826 ASSERT_CONDITION_UNKNOWN (model, b, EQ_EXPR, c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1827 ASSERT_CONDITION_UNKNOWN (model, c, EQ_EXPR, d);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1828 ASSERT_CONDITION_UNKNOWN (model, a, EQ_EXPR, d);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1829
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1830 ADD_SAT_CONSTRAINT (model, a, EQ_EXPR, b);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1831 ASSERT_CONDITION_TRUE (model, a, EQ_EXPR, b);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1832
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1833 ADD_SAT_CONSTRAINT (model, c, EQ_EXPR, d);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1834 ASSERT_CONDITION_TRUE (model, c, EQ_EXPR, d);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1835 ASSERT_CONDITION_UNKNOWN (model, a, EQ_EXPR, d);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1836
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1837 ADD_SAT_CONSTRAINT (model, c, EQ_EXPR, b);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1838 ASSERT_CONDITION_TRUE (model, c, EQ_EXPR, b);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1839 ASSERT_CONDITION_TRUE (model, a, EQ_EXPR, d);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1840 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1841
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1842 /* Transitivity: "a < b", "b < c" should imply "a < c". */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1843 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1844 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1845 ADD_SAT_CONSTRAINT (model, a, LT_EXPR, b);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1846 ADD_SAT_CONSTRAINT (model, b, LT_EXPR, c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1847
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1848 ASSERT_CONDITION_TRUE (model, a, LT_EXPR, c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1849 ASSERT_CONDITION_FALSE (model, a, EQ_EXPR, c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1850 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1851
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1852 /* Transitivity: "a <= b", "b < c" should imply "a < c". */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1853 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1854 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1855 ADD_SAT_CONSTRAINT (model, a, LE_EXPR, b);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1856 ADD_SAT_CONSTRAINT (model, b, LT_EXPR, c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1857
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1858 ASSERT_CONDITION_TRUE (model, a, LT_EXPR, c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1859 ASSERT_CONDITION_FALSE (model, a, EQ_EXPR, c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1860 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1861
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1862 /* Transitivity: "a <= b", "b <= c" should imply "a <= c". */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1863 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1864 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1865 ADD_SAT_CONSTRAINT (model, a, LE_EXPR, b);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1866 ADD_SAT_CONSTRAINT (model, b, LE_EXPR, c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1867
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1868 ASSERT_CONDITION_TRUE (model, a, LE_EXPR, c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1869 ASSERT_CONDITION_UNKNOWN (model, a, EQ_EXPR, c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1870 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1871
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1872 /* Transitivity: "a > b", "b > c" should imply "a > c". */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1873 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1874 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1875 ADD_SAT_CONSTRAINT (model, a, GT_EXPR, b);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1876 ADD_SAT_CONSTRAINT (model, b, GT_EXPR, c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1877
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1878 ASSERT_CONDITION_TRUE (model, a, GT_EXPR, c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1879 ASSERT_CONDITION_FALSE (model, a, EQ_EXPR, c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1880 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1881
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1882 /* Transitivity: "a >= b", "b > c" should imply " a > c". */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1883 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1884 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1885 ADD_SAT_CONSTRAINT (model, a, GE_EXPR, b);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1886 ADD_SAT_CONSTRAINT (model, b, GT_EXPR, c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1887
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1888 ASSERT_CONDITION_TRUE (model, a, GT_EXPR, c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1889 ASSERT_CONDITION_FALSE (model, a, EQ_EXPR, c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1890 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1891
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1892 /* Transitivity: "a >= b", "b >= c" should imply "a >= c". */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1893 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1894 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1895 ADD_SAT_CONSTRAINT (model, a, GE_EXPR, b);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1896 ADD_SAT_CONSTRAINT (model, b, GE_EXPR, c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1897
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1898 ASSERT_CONDITION_TRUE (model, a, GE_EXPR, c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1899 ASSERT_CONDITION_UNKNOWN (model, a, EQ_EXPR, c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1900 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1901
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1902 /* Transitivity: "(a < b)", "(c < d)", "(b < c)" should
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1903 imply the easy cases:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1904 (a < c)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1905 (b < d)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1906 but also that:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1907 (a < d). */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1908 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1909 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1910 ADD_SAT_CONSTRAINT (model, a, LT_EXPR, b);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1911 ADD_SAT_CONSTRAINT (model, c, LT_EXPR, d);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1912 ADD_SAT_CONSTRAINT (model, b, LT_EXPR, c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1913
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1914 ASSERT_CONDITION_TRUE (model, a, LT_EXPR, c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1915 ASSERT_CONDITION_TRUE (model, b, LT_EXPR, d);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1916 ASSERT_CONDITION_TRUE (model, a, LT_EXPR, d);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1917 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1918
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1919 /* Transitivity: "a >= b", "b >= a" should imply that a == b. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1920 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1921 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1922 ADD_SAT_CONSTRAINT (model, a, GE_EXPR, b);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1923 ADD_SAT_CONSTRAINT (model, b, GE_EXPR, a);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1924
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1925 // TODO:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1926 ASSERT_CONDITION_TRUE (model, a, EQ_EXPR, b);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1927 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1928
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1929 /* Transitivity: "a >= b", "b > a" should be impossible. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1930 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1931 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1932 ADD_SAT_CONSTRAINT (model, a, GE_EXPR, b);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1933 ADD_UNSAT_CONSTRAINT (model, b, GT_EXPR, a);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1934 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1935
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1936 /* Transitivity: "a >= b", "b >= c", "c >= a" should imply
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1937 that a == b == c. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1938 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1939 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1940 ADD_SAT_CONSTRAINT (model, a, GE_EXPR, b);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1941 ADD_SAT_CONSTRAINT (model, b, GE_EXPR, c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1942 ADD_SAT_CONSTRAINT (model, c, GE_EXPR, a);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1943
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1944 ASSERT_CONDITION_TRUE (model, a, EQ_EXPR, c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1945 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1946
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1947 /* Transitivity: "a > b", "b > c", "c > a"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1948 should be impossible. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1949 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1950 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1951 ADD_SAT_CONSTRAINT (model, a, GT_EXPR, b);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1952 ADD_SAT_CONSTRAINT (model, b, GT_EXPR, c);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1953 ADD_UNSAT_CONSTRAINT (model, c, GT_EXPR, a);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1954 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1955
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1956 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1957
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1958 /* Test various conditionals involving constants where the results
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1959 ought to be implied based on the values of the constants. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1960
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1961 static void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1962 test_constant_comparisons ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1963 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1964 tree int_3 = build_int_cst (integer_type_node, 3);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1965 tree int_4 = build_int_cst (integer_type_node, 4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1966 tree int_5 = build_int_cst (integer_type_node, 5);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1967
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1968 tree int_1023 = build_int_cst (integer_type_node, 1023);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1969 tree int_1024 = build_int_cst (integer_type_node, 1024);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1970
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1971 tree a = build_global_decl ("a", integer_type_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1972 tree b = build_global_decl ("b", integer_type_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1973
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1974 /* Given a >= 1024, then a <= 1023 should be impossible. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1975 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1976 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1977 ADD_SAT_CONSTRAINT (model, a, GE_EXPR, int_1024);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1978 ADD_UNSAT_CONSTRAINT (model, a, LE_EXPR, int_1023);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1979 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1980
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1981 /* a > 4. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1982 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1983 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1984 ADD_SAT_CONSTRAINT (model, a, GT_EXPR, int_4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1985 ASSERT_CONDITION_TRUE (model, a, GT_EXPR, int_4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1986 ASSERT_CONDITION_TRUE (model, a, NE_EXPR, int_3);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1987 ASSERT_CONDITION_UNKNOWN (model, a, NE_EXPR, int_5);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1988 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1989
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1990 /* a <= 4. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1991 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1992 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1993 ADD_SAT_CONSTRAINT (model, a, LE_EXPR, int_4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1994 ASSERT_CONDITION_FALSE (model, a, GT_EXPR, int_4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1995 ASSERT_CONDITION_FALSE (model, a, GT_EXPR, int_5);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1996 ASSERT_CONDITION_UNKNOWN (model, a, NE_EXPR, int_3);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1997 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1998
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1999 /* If "a > b" and "a == 3", then "b == 4" ought to be unsatisfiable. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2000 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2001 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2002 ADD_SAT_CONSTRAINT (model, a, GT_EXPR, b);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2003 ADD_SAT_CONSTRAINT (model, a, EQ_EXPR, int_3);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2004 ADD_UNSAT_CONSTRAINT (model, b, EQ_EXPR, int_4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2005 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2006
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2007 /* Various tests of int ranges where there is only one possible candidate. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2008 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2009 /* If "a <= 4" && "a > 3", then "a == 4",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2010 assuming a is of integral type. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2011 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2012 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2013 ADD_SAT_CONSTRAINT (model, a, LE_EXPR, int_4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2014 ADD_SAT_CONSTRAINT (model, a, GT_EXPR, int_3);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2015 ASSERT_CONDITION_TRUE (model, a, EQ_EXPR, int_4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2016 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2017
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2018 /* If "a > 3" && "a <= 4", then "a == 4",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2019 assuming a is of integral type. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2020 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2021 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2022 ADD_SAT_CONSTRAINT (model, a, GT_EXPR, int_3);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2023 ADD_SAT_CONSTRAINT (model, a, LE_EXPR, int_4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2024 ASSERT_CONDITION_TRUE (model, a, EQ_EXPR, int_4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2025 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2026 /* If "a > 3" && "a < 5", then "a == 4",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2027 assuming a is of integral type. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2028 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2029 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2030 ADD_SAT_CONSTRAINT (model, a, GT_EXPR, int_3);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2031 ADD_SAT_CONSTRAINT (model, a, LT_EXPR, int_5);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2032 ASSERT_CONDITION_TRUE (model, a, EQ_EXPR, int_4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2033 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2034 /* If "a >= 4" && "a < 5", then "a == 4",
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2035 assuming a is of integral type. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2036 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2037 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2038 ADD_SAT_CONSTRAINT (model, a, GE_EXPR, int_4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2039 ADD_SAT_CONSTRAINT (model, a, LT_EXPR, int_5);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2040 ASSERT_CONDITION_TRUE (model, a, EQ_EXPR, int_4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2041 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2042 /* If "a >= 4" && "a <= 4", then "a == 4". */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2043 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2044 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2045 ADD_SAT_CONSTRAINT (model, a, GE_EXPR, int_4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2046 ADD_SAT_CONSTRAINT (model, a, LE_EXPR, int_4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2047 ASSERT_CONDITION_TRUE (model, a, EQ_EXPR, int_4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2048 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2049 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2050
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2051 /* As above, but for floating-point:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2052 if "f > 3" && "f <= 4" we don't know that f == 4. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2053 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2054 tree f = build_global_decl ("f", double_type_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2055 tree float_3 = build_real_from_int_cst (double_type_node, int_3);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2056 tree float_4 = build_real_from_int_cst (double_type_node, int_4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2057
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2058 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2059 ADD_SAT_CONSTRAINT (model, f, GT_EXPR, float_3);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2060 ADD_SAT_CONSTRAINT (model, f, LE_EXPR, float_4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2061 ASSERT_CONDITION_UNKNOWN (model, f, EQ_EXPR, float_4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2062 ASSERT_CONDITION_UNKNOWN (model, f, EQ_EXPR, int_4);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2063 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2064 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2065
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2066 /* Verify various lower-level implementation details about
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2067 constraint_manager. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2068
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2069 static void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2070 test_constraint_impl ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2071 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2072 tree int_42 = build_int_cst (integer_type_node, 42);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2073 tree int_0 = build_int_cst (integer_type_node, 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2074
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2075 tree x = build_global_decl ("x", integer_type_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2076 tree y = build_global_decl ("y", integer_type_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2077 tree z = build_global_decl ("z", integer_type_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2078
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2079 /* x == y. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2080 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2081 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2082
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2083 ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2084
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2085 /* Assert various things about the insides of model. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2086 constraint_manager *cm = model.get_constraints ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2087 ASSERT_EQ (cm->m_constraints.length (), 0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2088 ASSERT_EQ (cm->m_equiv_classes.length (), 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2089 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2090
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2091 /* y <= z; x == y. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2092 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2093 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2094 ASSERT_CONDITION_UNKNOWN (model, x, EQ_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2095 ASSERT_CONDITION_UNKNOWN (model, x, GE_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2096
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2097 ADD_SAT_CONSTRAINT (model, y, GE_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2098 ASSERT_CONDITION_TRUE (model, y, GE_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2099 ASSERT_CONDITION_UNKNOWN (model, x, GE_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2100
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2101 ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2102
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2103 /* Assert various things about the insides of model. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2104 constraint_manager *cm = model.get_constraints ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2105 ASSERT_EQ (cm->m_constraints.length (), 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2106 ASSERT_EQ (cm->m_equiv_classes.length (), 2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2107
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2108 /* Ensure that we merged the constraints. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2109 ASSERT_CONDITION_TRUE (model, x, GE_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2110 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2111
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2112 /* y <= z; y == x. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2113 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2114 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2115 ASSERT_CONDITION_UNKNOWN (model, x, EQ_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2116 ASSERT_CONDITION_UNKNOWN (model, x, GE_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2117
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2118 ADD_SAT_CONSTRAINT (model, y, GE_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2119 ASSERT_CONDITION_TRUE (model, y, GE_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2120 ASSERT_CONDITION_UNKNOWN (model, x, GE_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2121
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2122 ADD_SAT_CONSTRAINT (model, y, EQ_EXPR, x);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2123
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2124 /* Assert various things about the insides of model. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2125 constraint_manager *cm = model.get_constraints ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2126 ASSERT_EQ (cm->m_constraints.length (), 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2127 ASSERT_EQ (cm->m_equiv_classes.length (), 2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2128
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2129 /* Ensure that we merged the constraints. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2130 ASSERT_CONDITION_TRUE (model, x, GE_EXPR, z);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2131 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2132
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2133 /* x == 0, then x != 42. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2134 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2135 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2136
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2137 ADD_SAT_CONSTRAINT (model, x, EQ_EXPR, int_0);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2138 ADD_SAT_CONSTRAINT (model, x, NE_EXPR, int_42);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2139
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2140 /* Assert various things about the insides of model. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2141 constraint_manager *cm = model.get_constraints ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2142 ASSERT_EQ (cm->m_constraints.length (), 1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2143 ASSERT_EQ (cm->m_equiv_classes.length (), 2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2144 ASSERT_EQ (cm->m_constraints[0].m_lhs,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2145 cm->get_or_add_equiv_class (model.get_rvalue (int_0, NULL)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2146 ASSERT_EQ (cm->m_constraints[0].m_rhs,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2147 cm->get_or_add_equiv_class (model.get_rvalue (int_42, NULL)));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2148 ASSERT_EQ (cm->m_constraints[0].m_op, CONSTRAINT_LT);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2149 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2150
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2151 // TODO: selftest for merging ecs "in the middle"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2152 // where a non-final one gets overwritten
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2153
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2154 // TODO: selftest where there are pre-existing constraints
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2155 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2156
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2157 /* Check that operator== and hashing works as expected for the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2158 various types. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2159
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2160 static void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2161 test_equality ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2162 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2163 tree x = build_global_decl ("x", integer_type_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2164 tree y = build_global_decl ("y", integer_type_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2165
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2166 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2167 region_model model0;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2168 region_model model1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2169
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2170 constraint_manager *cm0 = model0.get_constraints ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2171 constraint_manager *cm1 = model1.get_constraints ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2172
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2173 ASSERT_EQ (cm0->hash (), cm1->hash ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2174 ASSERT_EQ (*cm0, *cm1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2175
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2176 ASSERT_EQ (model0.hash (), model1.hash ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2177 ASSERT_EQ (model0, model1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2178
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2179 ADD_SAT_CONSTRAINT (model1, x, EQ_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2180 ASSERT_NE (cm0->hash (), cm1->hash ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2181 ASSERT_NE (*cm0, *cm1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2182
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2183 ASSERT_NE (model0.hash (), model1.hash ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2184 ASSERT_NE (model0, model1);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2185
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2186 region_model model2;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2187 constraint_manager *cm2 = model2.get_constraints ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2188 /* Make the same change to cm2. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2189 ADD_SAT_CONSTRAINT (model2, x, EQ_EXPR, y);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2190 ASSERT_EQ (cm1->hash (), cm2->hash ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2191 ASSERT_EQ (*cm1, *cm2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2192
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2193 ASSERT_EQ (model1.hash (), model2.hash ());
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2194 ASSERT_EQ (model1, model2);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2195 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2196 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2197
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2198 /* Verify tracking inequality of a variable against many constants. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2199
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2200 static void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2201 test_many_constants ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2202 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2203 tree a = build_global_decl ("a", integer_type_node);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2204
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2205 region_model model;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2206 auto_vec<tree> constants;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2207 for (int i = 0; i < 20; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2208 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2209 tree constant = build_int_cst (integer_type_node, i);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2210 constants.safe_push (constant);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2211 ADD_SAT_CONSTRAINT (model, a, NE_EXPR, constant);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2212
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2213 /* Merge, and check the result. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2214 region_model other (model);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2215
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2216 region_model merged;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2217 ASSERT_TRUE (model.can_merge_with_p (other, &merged));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2218 model.canonicalize (NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2219 merged.canonicalize (NULL);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2220 ASSERT_EQ (model, merged);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2221
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2222 for (int j = 0; j <= i; j++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2223 ASSERT_CONDITION_TRUE (model, a, NE_EXPR, constants[j]);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2224 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2225 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2226
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2227 /* Run the selftests in this file, temporarily overriding
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2228 flag_analyzer_transitivity with TRANSITIVITY. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2229
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2230 static void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2231 run_constraint_manager_tests (bool transitivity)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2232 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2233 int saved_flag_analyzer_transitivity = flag_analyzer_transitivity;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2234 flag_analyzer_transitivity = transitivity;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2235
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2236 test_constraint_conditions ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2237 if (flag_analyzer_transitivity)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2238 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2239 /* These selftests assume transitivity. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2240 test_transitivity ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2241 test_constant_comparisons ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2242 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2243 test_constraint_impl ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2244 test_equality ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2245 test_many_constants ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2246
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2247 flag_analyzer_transitivity = saved_flag_analyzer_transitivity;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2248 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2249
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2250 /* Run all of the selftests within this file. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2251
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2252 void
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2253 analyzer_constraint_manager_cc_tests ()
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2254 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2255 /* Run the tests twice: with and without transitivity. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2256 run_constraint_manager_tests (true);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2257 run_constraint_manager_tests (false);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2258 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2259
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2260 } // namespace selftest
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2261
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2262 #endif /* CHECKING_P */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2263
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2264 } // namespace ana
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2265
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2266 #endif /* #if ENABLE_ANALYZER */