annotate gcc/ipa-icf-gimple.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* Interprocedural Identical Code Folding pass
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 2014-2020 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
3
kono
parents:
diff changeset
4 Contributed by Jan Hubicka <hubicka@ucw.cz> and Martin Liska <mliska@suse.cz>
kono
parents:
diff changeset
5
kono
parents:
diff changeset
6 This file is part of GCC.
kono
parents:
diff changeset
7
kono
parents:
diff changeset
8 GCC is free software; you can redistribute it and/or modify it under
kono
parents:
diff changeset
9 the terms of the GNU General Public License as published by the Free
kono
parents:
diff changeset
10 Software Foundation; either version 3, or (at your option) any later
kono
parents:
diff changeset
11 version.
kono
parents:
diff changeset
12
kono
parents:
diff changeset
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
kono
parents:
diff changeset
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
kono
parents:
diff changeset
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
kono
parents:
diff changeset
16 for more details.
kono
parents:
diff changeset
17
kono
parents:
diff changeset
18 You should have received a copy of the GNU General Public License
kono
parents:
diff changeset
19 along with GCC; see the file COPYING3. If not see
kono
parents:
diff changeset
20 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
21
kono
parents:
diff changeset
22 #include "config.h"
kono
parents:
diff changeset
23 #include "system.h"
kono
parents:
diff changeset
24 #include "coretypes.h"
kono
parents:
diff changeset
25 #include "backend.h"
kono
parents:
diff changeset
26 #include "rtl.h"
kono
parents:
diff changeset
27 #include "tree.h"
kono
parents:
diff changeset
28 #include "gimple.h"
kono
parents:
diff changeset
29 #include "tree-pass.h"
kono
parents:
diff changeset
30 #include "ssa.h"
kono
parents:
diff changeset
31 #include "cgraph.h"
kono
parents:
diff changeset
32 #include "data-streamer.h"
kono
parents:
diff changeset
33 #include "gimple-pretty-print.h"
kono
parents:
diff changeset
34 #include "fold-const.h"
kono
parents:
diff changeset
35 #include "gimple-iterator.h"
kono
parents:
diff changeset
36 #include "ipa-utils.h"
kono
parents:
diff changeset
37 #include "tree-eh.h"
kono
parents:
diff changeset
38 #include "builtins.h"
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
39 #include "cfgloop.h"
111
kono
parents:
diff changeset
40
kono
parents:
diff changeset
41 #include "ipa-icf-gimple.h"
kono
parents:
diff changeset
42
kono
parents:
diff changeset
43 namespace ipa_icf_gimple {
kono
parents:
diff changeset
44
kono
parents:
diff changeset
45 /* Initialize internal structures for a given SOURCE_FUNC_DECL and
kono
parents:
diff changeset
46 TARGET_FUNC_DECL. Strict polymorphic comparison is processed if
kono
parents:
diff changeset
47 an option COMPARE_POLYMORPHIC is true. For special cases, one can
kono
parents:
diff changeset
48 set IGNORE_LABELS to skip label comparison.
kono
parents:
diff changeset
49 Similarly, IGNORE_SOURCE_DECLS and IGNORE_TARGET_DECLS are sets
kono
parents:
diff changeset
50 of declarations that can be skipped. */
kono
parents:
diff changeset
51
kono
parents:
diff changeset
52 func_checker::func_checker (tree source_func_decl, tree target_func_decl,
kono
parents:
diff changeset
53 bool ignore_labels,
kono
parents:
diff changeset
54 hash_set<symtab_node *> *ignored_source_nodes,
kono
parents:
diff changeset
55 hash_set<symtab_node *> *ignored_target_nodes)
kono
parents:
diff changeset
56 : m_source_func_decl (source_func_decl), m_target_func_decl (target_func_decl),
kono
parents:
diff changeset
57 m_ignored_source_nodes (ignored_source_nodes),
kono
parents:
diff changeset
58 m_ignored_target_nodes (ignored_target_nodes),
kono
parents:
diff changeset
59 m_ignore_labels (ignore_labels)
kono
parents:
diff changeset
60 {
kono
parents:
diff changeset
61 function *source_func = DECL_STRUCT_FUNCTION (source_func_decl);
kono
parents:
diff changeset
62 function *target_func = DECL_STRUCT_FUNCTION (target_func_decl);
kono
parents:
diff changeset
63
kono
parents:
diff changeset
64 unsigned ssa_source = SSANAMES (source_func)->length ();
kono
parents:
diff changeset
65 unsigned ssa_target = SSANAMES (target_func)->length ();
kono
parents:
diff changeset
66
kono
parents:
diff changeset
67 m_source_ssa_names.create (ssa_source);
kono
parents:
diff changeset
68 m_target_ssa_names.create (ssa_target);
kono
parents:
diff changeset
69
kono
parents:
diff changeset
70 for (unsigned i = 0; i < ssa_source; i++)
kono
parents:
diff changeset
71 m_source_ssa_names.safe_push (-1);
kono
parents:
diff changeset
72
kono
parents:
diff changeset
73 for (unsigned i = 0; i < ssa_target; i++)
kono
parents:
diff changeset
74 m_target_ssa_names.safe_push (-1);
kono
parents:
diff changeset
75 }
kono
parents:
diff changeset
76
kono
parents:
diff changeset
77 /* Memory release routine. */
kono
parents:
diff changeset
78
kono
parents:
diff changeset
79 func_checker::~func_checker ()
kono
parents:
diff changeset
80 {
kono
parents:
diff changeset
81 m_source_ssa_names.release();
kono
parents:
diff changeset
82 m_target_ssa_names.release();
kono
parents:
diff changeset
83 }
kono
parents:
diff changeset
84
kono
parents:
diff changeset
85 /* Verifies that trees T1 and T2 are equivalent from perspective of ICF. */
kono
parents:
diff changeset
86
kono
parents:
diff changeset
87 bool
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
88 func_checker::compare_ssa_name (const_tree t1, const_tree t2)
111
kono
parents:
diff changeset
89 {
kono
parents:
diff changeset
90 gcc_assert (TREE_CODE (t1) == SSA_NAME);
kono
parents:
diff changeset
91 gcc_assert (TREE_CODE (t2) == SSA_NAME);
kono
parents:
diff changeset
92
kono
parents:
diff changeset
93 unsigned i1 = SSA_NAME_VERSION (t1);
kono
parents:
diff changeset
94 unsigned i2 = SSA_NAME_VERSION (t2);
kono
parents:
diff changeset
95
kono
parents:
diff changeset
96 if (m_source_ssa_names[i1] == -1)
kono
parents:
diff changeset
97 m_source_ssa_names[i1] = i2;
kono
parents:
diff changeset
98 else if (m_source_ssa_names[i1] != (int) i2)
kono
parents:
diff changeset
99 return false;
kono
parents:
diff changeset
100
kono
parents:
diff changeset
101 if(m_target_ssa_names[i2] == -1)
kono
parents:
diff changeset
102 m_target_ssa_names[i2] = i1;
kono
parents:
diff changeset
103 else if (m_target_ssa_names[i2] != (int) i1)
kono
parents:
diff changeset
104 return false;
kono
parents:
diff changeset
105
kono
parents:
diff changeset
106 if (SSA_NAME_IS_DEFAULT_DEF (t1))
kono
parents:
diff changeset
107 {
kono
parents:
diff changeset
108 tree b1 = SSA_NAME_VAR (t1);
kono
parents:
diff changeset
109 tree b2 = SSA_NAME_VAR (t2);
kono
parents:
diff changeset
110
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
111 return compare_operand (b1, b2);
111
kono
parents:
diff changeset
112 }
kono
parents:
diff changeset
113
kono
parents:
diff changeset
114 return true;
kono
parents:
diff changeset
115 }
kono
parents:
diff changeset
116
kono
parents:
diff changeset
117 /* Verification function for edges E1 and E2. */
kono
parents:
diff changeset
118
kono
parents:
diff changeset
119 bool
kono
parents:
diff changeset
120 func_checker::compare_edge (edge e1, edge e2)
kono
parents:
diff changeset
121 {
kono
parents:
diff changeset
122 if (e1->flags != e2->flags)
kono
parents:
diff changeset
123 return false;
kono
parents:
diff changeset
124
kono
parents:
diff changeset
125 bool existed_p;
kono
parents:
diff changeset
126
kono
parents:
diff changeset
127 edge &slot = m_edge_map.get_or_insert (e1, &existed_p);
kono
parents:
diff changeset
128 if (existed_p)
kono
parents:
diff changeset
129 return return_with_debug (slot == e2);
kono
parents:
diff changeset
130 else
kono
parents:
diff changeset
131 slot = e2;
kono
parents:
diff changeset
132
kono
parents:
diff changeset
133 /* TODO: filter edge probabilities for profile feedback match. */
kono
parents:
diff changeset
134
kono
parents:
diff changeset
135 return true;
kono
parents:
diff changeset
136 }
kono
parents:
diff changeset
137
kono
parents:
diff changeset
138 /* Verification function for declaration trees T1 and T2 that
kono
parents:
diff changeset
139 come from functions FUNC1 and FUNC2. */
kono
parents:
diff changeset
140
kono
parents:
diff changeset
141 bool
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
142 func_checker::compare_decl (const_tree t1, const_tree t2)
111
kono
parents:
diff changeset
143 {
kono
parents:
diff changeset
144 if (!auto_var_in_fn_p (t1, m_source_func_decl)
kono
parents:
diff changeset
145 || !auto_var_in_fn_p (t2, m_target_func_decl))
kono
parents:
diff changeset
146 return return_with_debug (t1 == t2);
kono
parents:
diff changeset
147
kono
parents:
diff changeset
148 tree_code t = TREE_CODE (t1);
kono
parents:
diff changeset
149 if ((t == VAR_DECL || t == PARM_DECL || t == RESULT_DECL)
kono
parents:
diff changeset
150 && DECL_BY_REFERENCE (t1) != DECL_BY_REFERENCE (t2))
kono
parents:
diff changeset
151 return return_false_with_msg ("DECL_BY_REFERENCE flags are different");
kono
parents:
diff changeset
152
kono
parents:
diff changeset
153 if (!compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2)))
kono
parents:
diff changeset
154 return return_false ();
kono
parents:
diff changeset
155
kono
parents:
diff changeset
156 bool existed_p;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
157 const_tree &slot = m_decl_map.get_or_insert (t1, &existed_p);
111
kono
parents:
diff changeset
158 if (existed_p)
kono
parents:
diff changeset
159 return return_with_debug (slot == t2);
kono
parents:
diff changeset
160 else
kono
parents:
diff changeset
161 slot = t2;
kono
parents:
diff changeset
162
kono
parents:
diff changeset
163 return true;
kono
parents:
diff changeset
164 }
kono
parents:
diff changeset
165
kono
parents:
diff changeset
166 /* Return true if T1 and T2 are same for purposes of ipa-polymorphic-call
kono
parents:
diff changeset
167 analysis. COMPARE_PTR indicates if types of pointers needs to be
kono
parents:
diff changeset
168 considered. */
kono
parents:
diff changeset
169
kono
parents:
diff changeset
170 bool
kono
parents:
diff changeset
171 func_checker::compatible_polymorphic_types_p (tree t1, tree t2,
kono
parents:
diff changeset
172 bool compare_ptr)
kono
parents:
diff changeset
173 {
kono
parents:
diff changeset
174 gcc_assert (TREE_CODE (t1) != FUNCTION_TYPE && TREE_CODE (t1) != METHOD_TYPE);
kono
parents:
diff changeset
175
kono
parents:
diff changeset
176 /* Pointer types generally give no information. */
kono
parents:
diff changeset
177 if (POINTER_TYPE_P (t1))
kono
parents:
diff changeset
178 {
kono
parents:
diff changeset
179 if (!compare_ptr)
kono
parents:
diff changeset
180 return true;
kono
parents:
diff changeset
181 return func_checker::compatible_polymorphic_types_p (TREE_TYPE (t1),
kono
parents:
diff changeset
182 TREE_TYPE (t2),
kono
parents:
diff changeset
183 false);
kono
parents:
diff changeset
184 }
kono
parents:
diff changeset
185
kono
parents:
diff changeset
186 /* If types contain a polymorphic types, match them. */
kono
parents:
diff changeset
187 bool c1 = contains_polymorphic_type_p (t1);
kono
parents:
diff changeset
188 bool c2 = contains_polymorphic_type_p (t2);
kono
parents:
diff changeset
189 if (!c1 && !c2)
kono
parents:
diff changeset
190 return true;
kono
parents:
diff changeset
191 if (!c1 || !c2)
kono
parents:
diff changeset
192 return return_false_with_msg ("one type is not polymorphic");
kono
parents:
diff changeset
193 if (!types_must_be_same_for_odr (t1, t2))
kono
parents:
diff changeset
194 return return_false_with_msg ("types are not same for ODR");
kono
parents:
diff changeset
195 return true;
kono
parents:
diff changeset
196 }
kono
parents:
diff changeset
197
kono
parents:
diff changeset
198 /* Return true if types are compatible from perspective of ICF. */
kono
parents:
diff changeset
199 bool
kono
parents:
diff changeset
200 func_checker::compatible_types_p (tree t1, tree t2)
kono
parents:
diff changeset
201 {
kono
parents:
diff changeset
202 if (TREE_CODE (t1) != TREE_CODE (t2))
kono
parents:
diff changeset
203 return return_false_with_msg ("different tree types");
kono
parents:
diff changeset
204
kono
parents:
diff changeset
205 if (TYPE_RESTRICT (t1) != TYPE_RESTRICT (t2))
kono
parents:
diff changeset
206 return return_false_with_msg ("restrict flags are different");
kono
parents:
diff changeset
207
kono
parents:
diff changeset
208 if (!types_compatible_p (t1, t2))
kono
parents:
diff changeset
209 return return_false_with_msg ("types are not compatible");
kono
parents:
diff changeset
210
kono
parents:
diff changeset
211 return true;
kono
parents:
diff changeset
212 }
kono
parents:
diff changeset
213
kono
parents:
diff changeset
214 /* Function compare for equality given trees T1 and T2 which
kono
parents:
diff changeset
215 can be either a constant or a declaration type. */
kono
parents:
diff changeset
216
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
217 void
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
218 func_checker::hash_operand (const_tree arg, inchash::hash &hstate,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
219 unsigned int flags)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
220 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
221 if (arg == NULL_TREE)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
222 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
223 hstate.merge_hash (0);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
224 return;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
225 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
226
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
227 switch (TREE_CODE (arg))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
228 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
229 case FUNCTION_DECL:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
230 case VAR_DECL:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
231 case LABEL_DECL:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
232 case PARM_DECL:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
233 case RESULT_DECL:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
234 case CONST_DECL:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
235 case SSA_NAME:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
236 return;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
237 case FIELD_DECL:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
238 inchash::add_expr (DECL_FIELD_OFFSET (arg), hstate, flags);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
239 inchash::add_expr (DECL_FIELD_BIT_OFFSET (arg), hstate, flags);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
240 return;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
241 default:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
242 break;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
243 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
244
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
245 return operand_compare::hash_operand (arg, hstate, flags);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
246 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
247
111
kono
parents:
diff changeset
248 bool
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
249 func_checker::operand_equal_p (const_tree t1, const_tree t2,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
250 unsigned int flags)
111
kono
parents:
diff changeset
251 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
252 bool r;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
253 if (verify_hash_value (t1, t2, flags, &r))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
254 return r;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
255
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
256 if (t1 == t2)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
257 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
258 else if (!t1 || !t2)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
259 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
260
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
261 if (TREE_CODE (t1) != TREE_CODE (t2))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
262 return return_false ();
111
kono
parents:
diff changeset
263
kono
parents:
diff changeset
264 switch (TREE_CODE (t1))
kono
parents:
diff changeset
265 {
kono
parents:
diff changeset
266 case FUNCTION_DECL:
kono
parents:
diff changeset
267 /* All function decls are in the symbol table and known to match
kono
parents:
diff changeset
268 before we start comparing bodies. */
kono
parents:
diff changeset
269 return true;
kono
parents:
diff changeset
270 case VAR_DECL:
kono
parents:
diff changeset
271 return return_with_debug (compare_variable_decl (t1, t2));
kono
parents:
diff changeset
272 case LABEL_DECL:
kono
parents:
diff changeset
273 {
kono
parents:
diff changeset
274 int *bb1 = m_label_bb_map.get (t1);
kono
parents:
diff changeset
275 int *bb2 = m_label_bb_map.get (t2);
kono
parents:
diff changeset
276 /* Labels can point to another function (non-local GOTOs). */
kono
parents:
diff changeset
277 return return_with_debug (bb1 != NULL && bb2 != NULL && *bb1 == *bb2);
kono
parents:
diff changeset
278 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
279
111
kono
parents:
diff changeset
280 case PARM_DECL:
kono
parents:
diff changeset
281 case RESULT_DECL:
kono
parents:
diff changeset
282 case CONST_DECL:
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
283 return compare_decl (t1, t2);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
284 case SSA_NAME:
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
285 return compare_ssa_name (t1, t2);
111
kono
parents:
diff changeset
286 default:
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
287 break;
111
kono
parents:
diff changeset
288 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
289
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
290 return operand_compare::operand_equal_p (t1, t2, flags);
111
kono
parents:
diff changeset
291 }
kono
parents:
diff changeset
292
kono
parents:
diff changeset
293 /* Function responsible for comparison of various operands T1 and T2.
kono
parents:
diff changeset
294 If these components, from functions FUNC1 and FUNC2, are equal, true
kono
parents:
diff changeset
295 is returned. */
kono
parents:
diff changeset
296
kono
parents:
diff changeset
297 bool
kono
parents:
diff changeset
298 func_checker::compare_operand (tree t1, tree t2)
kono
parents:
diff changeset
299 {
kono
parents:
diff changeset
300 if (!t1 && !t2)
kono
parents:
diff changeset
301 return true;
kono
parents:
diff changeset
302 else if (!t1 || !t2)
kono
parents:
diff changeset
303 return false;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
304 if (operand_equal_p (t1, t2, OEP_MATCH_SIDE_EFFECTS))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
305 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
306 return return_false_with_msg ("operand_equal_p failed");
111
kono
parents:
diff changeset
307 }
kono
parents:
diff changeset
308
kono
parents:
diff changeset
309 bool
kono
parents:
diff changeset
310 func_checker::compare_asm_inputs_outputs (tree t1, tree t2)
kono
parents:
diff changeset
311 {
kono
parents:
diff changeset
312 gcc_assert (TREE_CODE (t1) == TREE_LIST);
kono
parents:
diff changeset
313 gcc_assert (TREE_CODE (t2) == TREE_LIST);
kono
parents:
diff changeset
314
kono
parents:
diff changeset
315 for (; t1; t1 = TREE_CHAIN (t1))
kono
parents:
diff changeset
316 {
kono
parents:
diff changeset
317 if (!t2)
kono
parents:
diff changeset
318 return false;
kono
parents:
diff changeset
319
kono
parents:
diff changeset
320 if (!compare_operand (TREE_VALUE (t1), TREE_VALUE (t2)))
kono
parents:
diff changeset
321 return return_false ();
kono
parents:
diff changeset
322
kono
parents:
diff changeset
323 tree p1 = TREE_PURPOSE (t1);
kono
parents:
diff changeset
324 tree p2 = TREE_PURPOSE (t2);
kono
parents:
diff changeset
325
kono
parents:
diff changeset
326 gcc_assert (TREE_CODE (p1) == TREE_LIST);
kono
parents:
diff changeset
327 gcc_assert (TREE_CODE (p2) == TREE_LIST);
kono
parents:
diff changeset
328
kono
parents:
diff changeset
329 if (strcmp (TREE_STRING_POINTER (TREE_VALUE (p1)),
kono
parents:
diff changeset
330 TREE_STRING_POINTER (TREE_VALUE (p2))) != 0)
kono
parents:
diff changeset
331 return return_false ();
kono
parents:
diff changeset
332
kono
parents:
diff changeset
333 t2 = TREE_CHAIN (t2);
kono
parents:
diff changeset
334 }
kono
parents:
diff changeset
335
kono
parents:
diff changeset
336 if (t2)
kono
parents:
diff changeset
337 return return_false ();
kono
parents:
diff changeset
338
kono
parents:
diff changeset
339 return true;
kono
parents:
diff changeset
340 }
kono
parents:
diff changeset
341
kono
parents:
diff changeset
342 /* Verifies that trees T1 and T2 do correspond. */
kono
parents:
diff changeset
343
kono
parents:
diff changeset
344 bool
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
345 func_checker::compare_variable_decl (const_tree t1, const_tree t2)
111
kono
parents:
diff changeset
346 {
kono
parents:
diff changeset
347 bool ret = false;
kono
parents:
diff changeset
348
kono
parents:
diff changeset
349 if (t1 == t2)
kono
parents:
diff changeset
350 return true;
kono
parents:
diff changeset
351
kono
parents:
diff changeset
352 if (DECL_ALIGN (t1) != DECL_ALIGN (t2))
kono
parents:
diff changeset
353 return return_false_with_msg ("alignments are different");
kono
parents:
diff changeset
354
kono
parents:
diff changeset
355 if (DECL_HARD_REGISTER (t1) != DECL_HARD_REGISTER (t2))
kono
parents:
diff changeset
356 return return_false_with_msg ("DECL_HARD_REGISTER are different");
kono
parents:
diff changeset
357
kono
parents:
diff changeset
358 if (DECL_HARD_REGISTER (t1)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
359 && DECL_ASSEMBLER_NAME_RAW (t1) != DECL_ASSEMBLER_NAME_RAW (t2))
111
kono
parents:
diff changeset
360 return return_false_with_msg ("HARD REGISTERS are different");
kono
parents:
diff changeset
361
kono
parents:
diff changeset
362 /* Symbol table variables are known to match before we start comparing
kono
parents:
diff changeset
363 bodies. */
kono
parents:
diff changeset
364 if (decl_in_symtab_p (t1))
kono
parents:
diff changeset
365 return decl_in_symtab_p (t2);
kono
parents:
diff changeset
366 ret = compare_decl (t1, t2);
kono
parents:
diff changeset
367
kono
parents:
diff changeset
368 return return_with_debug (ret);
kono
parents:
diff changeset
369 }
kono
parents:
diff changeset
370
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
371 /* Compare loop information for basic blocks BB1 and BB2. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
372
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
373 bool
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
374 func_checker::compare_loops (basic_block bb1, basic_block bb2)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
375 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
376 if ((bb1->loop_father == NULL) != (bb2->loop_father == NULL))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
377 return return_false ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
378
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
379 class loop *l1 = bb1->loop_father;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
380 class loop *l2 = bb2->loop_father;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
381 if (l1 == NULL)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
382 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
383
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
384 if ((bb1 == l1->header) != (bb2 == l2->header))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
385 return return_false_with_msg ("header");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
386 if ((bb1 == l1->latch) != (bb2 == l2->latch))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
387 return return_false_with_msg ("latch");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
388 if (l1->simdlen != l2->simdlen)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
389 return return_false_with_msg ("simdlen");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
390 if (l1->safelen != l2->safelen)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
391 return return_false_with_msg ("safelen");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
392 if (l1->can_be_parallel != l2->can_be_parallel)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
393 return return_false_with_msg ("can_be_parallel");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
394 if (l1->dont_vectorize != l2->dont_vectorize)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
395 return return_false_with_msg ("dont_vectorize");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
396 if (l1->force_vectorize != l2->force_vectorize)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
397 return return_false_with_msg ("force_vectorize");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
398 if (l1->unroll != l2->unroll)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
399 return return_false_with_msg ("unroll");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
400 if (!compare_variable_decl (l1->simduid, l2->simduid))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
401 return return_false_with_msg ("simduid");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
402
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
403 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
404 }
111
kono
parents:
diff changeset
405
kono
parents:
diff changeset
406 /* Function visits all gimple labels and creates corresponding
kono
parents:
diff changeset
407 mapping between basic blocks and labels. */
kono
parents:
diff changeset
408
kono
parents:
diff changeset
409 void
kono
parents:
diff changeset
410 func_checker::parse_labels (sem_bb *bb)
kono
parents:
diff changeset
411 {
kono
parents:
diff changeset
412 for (gimple_stmt_iterator gsi = gsi_start_bb (bb->bb); !gsi_end_p (gsi);
kono
parents:
diff changeset
413 gsi_next (&gsi))
kono
parents:
diff changeset
414 {
kono
parents:
diff changeset
415 gimple *stmt = gsi_stmt (gsi);
kono
parents:
diff changeset
416
kono
parents:
diff changeset
417 if (glabel *label_stmt = dyn_cast <glabel *> (stmt))
kono
parents:
diff changeset
418 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
419 const_tree t = gimple_label_label (label_stmt);
111
kono
parents:
diff changeset
420 gcc_assert (TREE_CODE (t) == LABEL_DECL);
kono
parents:
diff changeset
421
kono
parents:
diff changeset
422 m_label_bb_map.put (t, bb->bb->index);
kono
parents:
diff changeset
423 }
kono
parents:
diff changeset
424 }
kono
parents:
diff changeset
425 }
kono
parents:
diff changeset
426
kono
parents:
diff changeset
427 /* Basic block equivalence comparison function that returns true if
kono
parents:
diff changeset
428 basic blocks BB1 and BB2 (from functions FUNC1 and FUNC2) correspond.
kono
parents:
diff changeset
429
kono
parents:
diff changeset
430 In general, a collection of equivalence dictionaries is built for types
kono
parents:
diff changeset
431 like SSA names, declarations (VAR_DECL, PARM_DECL, ..). This infrastructure
kono
parents:
diff changeset
432 is utilized by every statement-by-statement comparison function. */
kono
parents:
diff changeset
433
kono
parents:
diff changeset
434 bool
kono
parents:
diff changeset
435 func_checker::compare_bb (sem_bb *bb1, sem_bb *bb2)
kono
parents:
diff changeset
436 {
kono
parents:
diff changeset
437 gimple_stmt_iterator gsi1, gsi2;
kono
parents:
diff changeset
438 gimple *s1, *s2;
kono
parents:
diff changeset
439
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
440 gsi1 = gsi_start_nondebug_bb (bb1->bb);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
441 gsi2 = gsi_start_nondebug_bb (bb2->bb);
111
kono
parents:
diff changeset
442
kono
parents:
diff changeset
443 while (!gsi_end_p (gsi1))
kono
parents:
diff changeset
444 {
kono
parents:
diff changeset
445 if (gsi_end_p (gsi2))
kono
parents:
diff changeset
446 return return_false ();
kono
parents:
diff changeset
447
kono
parents:
diff changeset
448 s1 = gsi_stmt (gsi1);
kono
parents:
diff changeset
449 s2 = gsi_stmt (gsi2);
kono
parents:
diff changeset
450
kono
parents:
diff changeset
451 int eh1 = lookup_stmt_eh_lp_fn
kono
parents:
diff changeset
452 (DECL_STRUCT_FUNCTION (m_source_func_decl), s1);
kono
parents:
diff changeset
453 int eh2 = lookup_stmt_eh_lp_fn
kono
parents:
diff changeset
454 (DECL_STRUCT_FUNCTION (m_target_func_decl), s2);
kono
parents:
diff changeset
455
kono
parents:
diff changeset
456 if (eh1 != eh2)
kono
parents:
diff changeset
457 return return_false_with_msg ("EH regions are different");
kono
parents:
diff changeset
458
kono
parents:
diff changeset
459 if (gimple_code (s1) != gimple_code (s2))
kono
parents:
diff changeset
460 return return_false_with_msg ("gimple codes are different");
kono
parents:
diff changeset
461
kono
parents:
diff changeset
462 switch (gimple_code (s1))
kono
parents:
diff changeset
463 {
kono
parents:
diff changeset
464 case GIMPLE_CALL:
kono
parents:
diff changeset
465 if (!compare_gimple_call (as_a <gcall *> (s1),
kono
parents:
diff changeset
466 as_a <gcall *> (s2)))
kono
parents:
diff changeset
467 return return_different_stmts (s1, s2, "GIMPLE_CALL");
kono
parents:
diff changeset
468 break;
kono
parents:
diff changeset
469 case GIMPLE_ASSIGN:
kono
parents:
diff changeset
470 if (!compare_gimple_assign (s1, s2))
kono
parents:
diff changeset
471 return return_different_stmts (s1, s2, "GIMPLE_ASSIGN");
kono
parents:
diff changeset
472 break;
kono
parents:
diff changeset
473 case GIMPLE_COND:
kono
parents:
diff changeset
474 if (!compare_gimple_cond (s1, s2))
kono
parents:
diff changeset
475 return return_different_stmts (s1, s2, "GIMPLE_COND");
kono
parents:
diff changeset
476 break;
kono
parents:
diff changeset
477 case GIMPLE_SWITCH:
kono
parents:
diff changeset
478 if (!compare_gimple_switch (as_a <gswitch *> (s1),
kono
parents:
diff changeset
479 as_a <gswitch *> (s2)))
kono
parents:
diff changeset
480 return return_different_stmts (s1, s2, "GIMPLE_SWITCH");
kono
parents:
diff changeset
481 break;
kono
parents:
diff changeset
482 case GIMPLE_DEBUG:
kono
parents:
diff changeset
483 break;
kono
parents:
diff changeset
484 case GIMPLE_EH_DISPATCH:
kono
parents:
diff changeset
485 if (gimple_eh_dispatch_region (as_a <geh_dispatch *> (s1))
kono
parents:
diff changeset
486 != gimple_eh_dispatch_region (as_a <geh_dispatch *> (s2)))
kono
parents:
diff changeset
487 return return_different_stmts (s1, s2, "GIMPLE_EH_DISPATCH");
kono
parents:
diff changeset
488 break;
kono
parents:
diff changeset
489 case GIMPLE_RESX:
kono
parents:
diff changeset
490 if (!compare_gimple_resx (as_a <gresx *> (s1),
kono
parents:
diff changeset
491 as_a <gresx *> (s2)))
kono
parents:
diff changeset
492 return return_different_stmts (s1, s2, "GIMPLE_RESX");
kono
parents:
diff changeset
493 break;
kono
parents:
diff changeset
494 case GIMPLE_LABEL:
kono
parents:
diff changeset
495 if (!compare_gimple_label (as_a <glabel *> (s1),
kono
parents:
diff changeset
496 as_a <glabel *> (s2)))
kono
parents:
diff changeset
497 return return_different_stmts (s1, s2, "GIMPLE_LABEL");
kono
parents:
diff changeset
498 break;
kono
parents:
diff changeset
499 case GIMPLE_RETURN:
kono
parents:
diff changeset
500 if (!compare_gimple_return (as_a <greturn *> (s1),
kono
parents:
diff changeset
501 as_a <greturn *> (s2)))
kono
parents:
diff changeset
502 return return_different_stmts (s1, s2, "GIMPLE_RETURN");
kono
parents:
diff changeset
503 break;
kono
parents:
diff changeset
504 case GIMPLE_GOTO:
kono
parents:
diff changeset
505 if (!compare_gimple_goto (s1, s2))
kono
parents:
diff changeset
506 return return_different_stmts (s1, s2, "GIMPLE_GOTO");
kono
parents:
diff changeset
507 break;
kono
parents:
diff changeset
508 case GIMPLE_ASM:
kono
parents:
diff changeset
509 if (!compare_gimple_asm (as_a <gasm *> (s1),
kono
parents:
diff changeset
510 as_a <gasm *> (s2)))
kono
parents:
diff changeset
511 return return_different_stmts (s1, s2, "GIMPLE_ASM");
kono
parents:
diff changeset
512 break;
kono
parents:
diff changeset
513 case GIMPLE_PREDICT:
kono
parents:
diff changeset
514 case GIMPLE_NOP:
kono
parents:
diff changeset
515 break;
kono
parents:
diff changeset
516 default:
kono
parents:
diff changeset
517 return return_false_with_msg ("Unknown GIMPLE code reached");
kono
parents:
diff changeset
518 }
kono
parents:
diff changeset
519
kono
parents:
diff changeset
520 gsi_next_nondebug (&gsi1);
kono
parents:
diff changeset
521 gsi_next_nondebug (&gsi2);
kono
parents:
diff changeset
522 }
kono
parents:
diff changeset
523
kono
parents:
diff changeset
524 if (!gsi_end_p (gsi2))
kono
parents:
diff changeset
525 return return_false ();
kono
parents:
diff changeset
526
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
527 if (!compare_loops (bb1->bb, bb2->bb))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
528 return return_false ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
529
111
kono
parents:
diff changeset
530 return true;
kono
parents:
diff changeset
531 }
kono
parents:
diff changeset
532
kono
parents:
diff changeset
533 /* Verifies for given GIMPLEs S1 and S2 that
kono
parents:
diff changeset
534 call statements are semantically equivalent. */
kono
parents:
diff changeset
535
kono
parents:
diff changeset
536 bool
kono
parents:
diff changeset
537 func_checker::compare_gimple_call (gcall *s1, gcall *s2)
kono
parents:
diff changeset
538 {
kono
parents:
diff changeset
539 unsigned i;
kono
parents:
diff changeset
540 tree t1, t2;
kono
parents:
diff changeset
541
kono
parents:
diff changeset
542 if (gimple_call_num_args (s1) != gimple_call_num_args (s2))
kono
parents:
diff changeset
543 return false;
kono
parents:
diff changeset
544
kono
parents:
diff changeset
545 t1 = gimple_call_fn (s1);
kono
parents:
diff changeset
546 t2 = gimple_call_fn (s2);
kono
parents:
diff changeset
547 if (!compare_operand (t1, t2))
kono
parents:
diff changeset
548 return return_false ();
kono
parents:
diff changeset
549
kono
parents:
diff changeset
550 /* Compare flags. */
kono
parents:
diff changeset
551 if (gimple_call_internal_p (s1) != gimple_call_internal_p (s2)
kono
parents:
diff changeset
552 || gimple_call_ctrl_altering_p (s1) != gimple_call_ctrl_altering_p (s2)
kono
parents:
diff changeset
553 || gimple_call_tail_p (s1) != gimple_call_tail_p (s2)
kono
parents:
diff changeset
554 || gimple_call_return_slot_opt_p (s1) != gimple_call_return_slot_opt_p (s2)
kono
parents:
diff changeset
555 || gimple_call_from_thunk_p (s1) != gimple_call_from_thunk_p (s2)
kono
parents:
diff changeset
556 || gimple_call_va_arg_pack_p (s1) != gimple_call_va_arg_pack_p (s2)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
557 || gimple_call_alloca_for_var_p (s1) != gimple_call_alloca_for_var_p (s2))
111
kono
parents:
diff changeset
558 return false;
kono
parents:
diff changeset
559
kono
parents:
diff changeset
560 if (gimple_call_internal_p (s1)
kono
parents:
diff changeset
561 && gimple_call_internal_fn (s1) != gimple_call_internal_fn (s2))
kono
parents:
diff changeset
562 return false;
kono
parents:
diff changeset
563
kono
parents:
diff changeset
564 tree fntype1 = gimple_call_fntype (s1);
kono
parents:
diff changeset
565 tree fntype2 = gimple_call_fntype (s2);
kono
parents:
diff changeset
566 if ((fntype1 && !fntype2)
kono
parents:
diff changeset
567 || (!fntype1 && fntype2)
kono
parents:
diff changeset
568 || (fntype1 && !types_compatible_p (fntype1, fntype2)))
kono
parents:
diff changeset
569 return return_false_with_msg ("call function types are not compatible");
kono
parents:
diff changeset
570
kono
parents:
diff changeset
571 tree chain1 = gimple_call_chain (s1);
kono
parents:
diff changeset
572 tree chain2 = gimple_call_chain (s2);
kono
parents:
diff changeset
573 if ((chain1 && !chain2)
kono
parents:
diff changeset
574 || (!chain1 && chain2)
kono
parents:
diff changeset
575 || !compare_operand (chain1, chain2))
kono
parents:
diff changeset
576 return return_false_with_msg ("static call chains are different");
kono
parents:
diff changeset
577
kono
parents:
diff changeset
578 /* Checking of argument. */
kono
parents:
diff changeset
579 for (i = 0; i < gimple_call_num_args (s1); ++i)
kono
parents:
diff changeset
580 {
kono
parents:
diff changeset
581 t1 = gimple_call_arg (s1, i);
kono
parents:
diff changeset
582 t2 = gimple_call_arg (s2, i);
kono
parents:
diff changeset
583
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
584 if (!compare_operand (t1, t2))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
585 return return_false_with_msg ("GIMPLE call operands are different");
111
kono
parents:
diff changeset
586 }
kono
parents:
diff changeset
587
kono
parents:
diff changeset
588 /* Return value checking. */
kono
parents:
diff changeset
589 t1 = gimple_get_lhs (s1);
kono
parents:
diff changeset
590 t2 = gimple_get_lhs (s2);
kono
parents:
diff changeset
591
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
592 return compare_operand (t1, t2);
111
kono
parents:
diff changeset
593 }
kono
parents:
diff changeset
594
kono
parents:
diff changeset
595
kono
parents:
diff changeset
596 /* Verifies for given GIMPLEs S1 and S2 that
kono
parents:
diff changeset
597 assignment statements are semantically equivalent. */
kono
parents:
diff changeset
598
kono
parents:
diff changeset
599 bool
kono
parents:
diff changeset
600 func_checker::compare_gimple_assign (gimple *s1, gimple *s2)
kono
parents:
diff changeset
601 {
kono
parents:
diff changeset
602 tree arg1, arg2;
kono
parents:
diff changeset
603 tree_code code1, code2;
kono
parents:
diff changeset
604 unsigned i;
kono
parents:
diff changeset
605
kono
parents:
diff changeset
606 code1 = gimple_expr_code (s1);
kono
parents:
diff changeset
607 code2 = gimple_expr_code (s2);
kono
parents:
diff changeset
608
kono
parents:
diff changeset
609 if (code1 != code2)
kono
parents:
diff changeset
610 return false;
kono
parents:
diff changeset
611
kono
parents:
diff changeset
612 code1 = gimple_assign_rhs_code (s1);
kono
parents:
diff changeset
613 code2 = gimple_assign_rhs_code (s2);
kono
parents:
diff changeset
614
kono
parents:
diff changeset
615 if (code1 != code2)
kono
parents:
diff changeset
616 return false;
kono
parents:
diff changeset
617
kono
parents:
diff changeset
618 for (i = 0; i < gimple_num_ops (s1); i++)
kono
parents:
diff changeset
619 {
kono
parents:
diff changeset
620 arg1 = gimple_op (s1, i);
kono
parents:
diff changeset
621 arg2 = gimple_op (s2, i);
kono
parents:
diff changeset
622
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
623 /* LHS types of NOP_EXPR must be compatible. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
624 if (CONVERT_EXPR_CODE_P (code1) && i == 0)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
625 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
626 if (!compatible_types_p (TREE_TYPE (arg1), TREE_TYPE (arg2)))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
627 return return_false_with_msg ("GIMPLE NOP LHS type mismatch");
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
628 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
629
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
630 if (!compare_operand (arg1, arg2))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
631 return return_false_with_msg ("GIMPLE assignment operands "
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
632 "are different");
111
kono
parents:
diff changeset
633 }
kono
parents:
diff changeset
634
kono
parents:
diff changeset
635
kono
parents:
diff changeset
636 return true;
kono
parents:
diff changeset
637 }
kono
parents:
diff changeset
638
kono
parents:
diff changeset
639 /* Verifies for given GIMPLEs S1 and S2 that
kono
parents:
diff changeset
640 condition statements are semantically equivalent. */
kono
parents:
diff changeset
641
kono
parents:
diff changeset
642 bool
kono
parents:
diff changeset
643 func_checker::compare_gimple_cond (gimple *s1, gimple *s2)
kono
parents:
diff changeset
644 {
kono
parents:
diff changeset
645 tree t1, t2;
kono
parents:
diff changeset
646 tree_code code1, code2;
kono
parents:
diff changeset
647
kono
parents:
diff changeset
648 code1 = gimple_expr_code (s1);
kono
parents:
diff changeset
649 code2 = gimple_expr_code (s2);
kono
parents:
diff changeset
650
kono
parents:
diff changeset
651 if (code1 != code2)
kono
parents:
diff changeset
652 return false;
kono
parents:
diff changeset
653
kono
parents:
diff changeset
654 t1 = gimple_cond_lhs (s1);
kono
parents:
diff changeset
655 t2 = gimple_cond_lhs (s2);
kono
parents:
diff changeset
656
kono
parents:
diff changeset
657 if (!compare_operand (t1, t2))
kono
parents:
diff changeset
658 return false;
kono
parents:
diff changeset
659
kono
parents:
diff changeset
660 t1 = gimple_cond_rhs (s1);
kono
parents:
diff changeset
661 t2 = gimple_cond_rhs (s2);
kono
parents:
diff changeset
662
kono
parents:
diff changeset
663 return compare_operand (t1, t2);
kono
parents:
diff changeset
664 }
kono
parents:
diff changeset
665
kono
parents:
diff changeset
666 /* Verifies for given GIMPLE_LABEL stmts S1 and S2 that
kono
parents:
diff changeset
667 label statements are semantically equivalent. */
kono
parents:
diff changeset
668
kono
parents:
diff changeset
669 bool
kono
parents:
diff changeset
670 func_checker::compare_gimple_label (const glabel *g1, const glabel *g2)
kono
parents:
diff changeset
671 {
kono
parents:
diff changeset
672 if (m_ignore_labels)
kono
parents:
diff changeset
673 return true;
kono
parents:
diff changeset
674
kono
parents:
diff changeset
675 tree t1 = gimple_label_label (g1);
kono
parents:
diff changeset
676 tree t2 = gimple_label_label (g2);
kono
parents:
diff changeset
677
kono
parents:
diff changeset
678 if (FORCED_LABEL (t1) || FORCED_LABEL (t2))
kono
parents:
diff changeset
679 return return_false_with_msg ("FORCED_LABEL");
kono
parents:
diff changeset
680
kono
parents:
diff changeset
681 /* As the pass build BB to label mapping, no further check is needed. */
kono
parents:
diff changeset
682 return true;
kono
parents:
diff changeset
683 }
kono
parents:
diff changeset
684
kono
parents:
diff changeset
685 /* Verifies for given GIMPLE_SWITCH stmts S1 and S2 that
kono
parents:
diff changeset
686 switch statements are semantically equivalent. */
kono
parents:
diff changeset
687
kono
parents:
diff changeset
688 bool
kono
parents:
diff changeset
689 func_checker::compare_gimple_switch (const gswitch *g1, const gswitch *g2)
kono
parents:
diff changeset
690 {
kono
parents:
diff changeset
691 unsigned lsize1, lsize2, i;
kono
parents:
diff changeset
692
kono
parents:
diff changeset
693 lsize1 = gimple_switch_num_labels (g1);
kono
parents:
diff changeset
694 lsize2 = gimple_switch_num_labels (g2);
kono
parents:
diff changeset
695
kono
parents:
diff changeset
696 if (lsize1 != lsize2)
kono
parents:
diff changeset
697 return false;
kono
parents:
diff changeset
698
kono
parents:
diff changeset
699 tree t1 = gimple_switch_index (g1);
kono
parents:
diff changeset
700 tree t2 = gimple_switch_index (g2);
kono
parents:
diff changeset
701
kono
parents:
diff changeset
702 if (!compare_operand (t1, t2))
kono
parents:
diff changeset
703 return false;
kono
parents:
diff changeset
704
kono
parents:
diff changeset
705 for (i = 0; i < lsize1; i++)
kono
parents:
diff changeset
706 {
kono
parents:
diff changeset
707 tree label1 = gimple_switch_label (g1, i);
kono
parents:
diff changeset
708 tree label2 = gimple_switch_label (g2, i);
kono
parents:
diff changeset
709
kono
parents:
diff changeset
710 /* Label LOW and HIGH comparison. */
kono
parents:
diff changeset
711 tree low1 = CASE_LOW (label1);
kono
parents:
diff changeset
712 tree low2 = CASE_LOW (label2);
kono
parents:
diff changeset
713
kono
parents:
diff changeset
714 if (!tree_int_cst_equal (low1, low2))
kono
parents:
diff changeset
715 return return_false_with_msg ("case low values are different");
kono
parents:
diff changeset
716
kono
parents:
diff changeset
717 tree high1 = CASE_HIGH (label1);
kono
parents:
diff changeset
718 tree high2 = CASE_HIGH (label2);
kono
parents:
diff changeset
719
kono
parents:
diff changeset
720 if (!tree_int_cst_equal (high1, high2))
kono
parents:
diff changeset
721 return return_false_with_msg ("case high values are different");
kono
parents:
diff changeset
722
kono
parents:
diff changeset
723 if (TREE_CODE (label1) == CASE_LABEL_EXPR
kono
parents:
diff changeset
724 && TREE_CODE (label2) == CASE_LABEL_EXPR)
kono
parents:
diff changeset
725 {
kono
parents:
diff changeset
726 label1 = CASE_LABEL (label1);
kono
parents:
diff changeset
727 label2 = CASE_LABEL (label2);
kono
parents:
diff changeset
728
kono
parents:
diff changeset
729 if (!compare_operand (label1, label2))
kono
parents:
diff changeset
730 return return_false_with_msg ("switch label_exprs are different");
kono
parents:
diff changeset
731 }
kono
parents:
diff changeset
732 else if (!tree_int_cst_equal (label1, label2))
kono
parents:
diff changeset
733 return return_false_with_msg ("switch labels are different");
kono
parents:
diff changeset
734 }
kono
parents:
diff changeset
735
kono
parents:
diff changeset
736 return true;
kono
parents:
diff changeset
737 }
kono
parents:
diff changeset
738
kono
parents:
diff changeset
739 /* Verifies for given GIMPLE_RETURN stmts S1 and S2 that
kono
parents:
diff changeset
740 return statements are semantically equivalent. */
kono
parents:
diff changeset
741
kono
parents:
diff changeset
742 bool
kono
parents:
diff changeset
743 func_checker::compare_gimple_return (const greturn *g1, const greturn *g2)
kono
parents:
diff changeset
744 {
kono
parents:
diff changeset
745 tree t1, t2;
kono
parents:
diff changeset
746
kono
parents:
diff changeset
747 t1 = gimple_return_retval (g1);
kono
parents:
diff changeset
748 t2 = gimple_return_retval (g2);
kono
parents:
diff changeset
749
kono
parents:
diff changeset
750 /* Void return type. */
kono
parents:
diff changeset
751 if (t1 == NULL && t2 == NULL)
kono
parents:
diff changeset
752 return true;
kono
parents:
diff changeset
753 else
kono
parents:
diff changeset
754 return compare_operand (t1, t2);
kono
parents:
diff changeset
755 }
kono
parents:
diff changeset
756
kono
parents:
diff changeset
757 /* Verifies for given GIMPLEs S1 and S2 that
kono
parents:
diff changeset
758 goto statements are semantically equivalent. */
kono
parents:
diff changeset
759
kono
parents:
diff changeset
760 bool
kono
parents:
diff changeset
761 func_checker::compare_gimple_goto (gimple *g1, gimple *g2)
kono
parents:
diff changeset
762 {
kono
parents:
diff changeset
763 tree dest1, dest2;
kono
parents:
diff changeset
764
kono
parents:
diff changeset
765 dest1 = gimple_goto_dest (g1);
kono
parents:
diff changeset
766 dest2 = gimple_goto_dest (g2);
kono
parents:
diff changeset
767
kono
parents:
diff changeset
768 if (TREE_CODE (dest1) != TREE_CODE (dest2) || TREE_CODE (dest1) != SSA_NAME)
kono
parents:
diff changeset
769 return false;
kono
parents:
diff changeset
770
kono
parents:
diff changeset
771 return compare_operand (dest1, dest2);
kono
parents:
diff changeset
772 }
kono
parents:
diff changeset
773
kono
parents:
diff changeset
774 /* Verifies for given GIMPLE_RESX stmts S1 and S2 that
kono
parents:
diff changeset
775 resx statements are semantically equivalent. */
kono
parents:
diff changeset
776
kono
parents:
diff changeset
777 bool
kono
parents:
diff changeset
778 func_checker::compare_gimple_resx (const gresx *g1, const gresx *g2)
kono
parents:
diff changeset
779 {
kono
parents:
diff changeset
780 return gimple_resx_region (g1) == gimple_resx_region (g2);
kono
parents:
diff changeset
781 }
kono
parents:
diff changeset
782
kono
parents:
diff changeset
783 /* Verifies for given GIMPLEs S1 and S2 that ASM statements are equivalent.
kono
parents:
diff changeset
784 For the beginning, the pass only supports equality for
kono
parents:
diff changeset
785 '__asm__ __volatile__ ("", "", "", "memory")'. */
kono
parents:
diff changeset
786
kono
parents:
diff changeset
787 bool
kono
parents:
diff changeset
788 func_checker::compare_gimple_asm (const gasm *g1, const gasm *g2)
kono
parents:
diff changeset
789 {
kono
parents:
diff changeset
790 if (gimple_asm_volatile_p (g1) != gimple_asm_volatile_p (g2))
kono
parents:
diff changeset
791 return false;
kono
parents:
diff changeset
792
kono
parents:
diff changeset
793 if (gimple_asm_input_p (g1) != gimple_asm_input_p (g2))
kono
parents:
diff changeset
794 return false;
kono
parents:
diff changeset
795
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
796 if (gimple_asm_inline_p (g1) != gimple_asm_inline_p (g2))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
797 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
798
111
kono
parents:
diff changeset
799 if (gimple_asm_ninputs (g1) != gimple_asm_ninputs (g2))
kono
parents:
diff changeset
800 return false;
kono
parents:
diff changeset
801
kono
parents:
diff changeset
802 if (gimple_asm_noutputs (g1) != gimple_asm_noutputs (g2))
kono
parents:
diff changeset
803 return false;
kono
parents:
diff changeset
804
kono
parents:
diff changeset
805 /* We do not suppport goto ASM statement comparison. */
kono
parents:
diff changeset
806 if (gimple_asm_nlabels (g1) || gimple_asm_nlabels (g2))
kono
parents:
diff changeset
807 return false;
kono
parents:
diff changeset
808
kono
parents:
diff changeset
809 if (gimple_asm_nclobbers (g1) != gimple_asm_nclobbers (g2))
kono
parents:
diff changeset
810 return false;
kono
parents:
diff changeset
811
kono
parents:
diff changeset
812 if (strcmp (gimple_asm_string (g1), gimple_asm_string (g2)) != 0)
kono
parents:
diff changeset
813 return return_false_with_msg ("ASM strings are different");
kono
parents:
diff changeset
814
kono
parents:
diff changeset
815 for (unsigned i = 0; i < gimple_asm_ninputs (g1); i++)
kono
parents:
diff changeset
816 {
kono
parents:
diff changeset
817 tree input1 = gimple_asm_input_op (g1, i);
kono
parents:
diff changeset
818 tree input2 = gimple_asm_input_op (g2, i);
kono
parents:
diff changeset
819
kono
parents:
diff changeset
820 if (!compare_asm_inputs_outputs (input1, input2))
kono
parents:
diff changeset
821 return return_false_with_msg ("ASM input is different");
kono
parents:
diff changeset
822 }
kono
parents:
diff changeset
823
kono
parents:
diff changeset
824 for (unsigned i = 0; i < gimple_asm_noutputs (g1); i++)
kono
parents:
diff changeset
825 {
kono
parents:
diff changeset
826 tree output1 = gimple_asm_output_op (g1, i);
kono
parents:
diff changeset
827 tree output2 = gimple_asm_output_op (g2, i);
kono
parents:
diff changeset
828
kono
parents:
diff changeset
829 if (!compare_asm_inputs_outputs (output1, output2))
kono
parents:
diff changeset
830 return return_false_with_msg ("ASM output is different");
kono
parents:
diff changeset
831 }
kono
parents:
diff changeset
832
kono
parents:
diff changeset
833 for (unsigned i = 0; i < gimple_asm_nclobbers (g1); i++)
kono
parents:
diff changeset
834 {
kono
parents:
diff changeset
835 tree clobber1 = gimple_asm_clobber_op (g1, i);
kono
parents:
diff changeset
836 tree clobber2 = gimple_asm_clobber_op (g2, i);
kono
parents:
diff changeset
837
kono
parents:
diff changeset
838 if (!operand_equal_p (TREE_VALUE (clobber1), TREE_VALUE (clobber2),
kono
parents:
diff changeset
839 OEP_ONLY_CONST))
kono
parents:
diff changeset
840 return return_false_with_msg ("ASM clobber is different");
kono
parents:
diff changeset
841 }
kono
parents:
diff changeset
842
kono
parents:
diff changeset
843 return true;
kono
parents:
diff changeset
844 }
kono
parents:
diff changeset
845
kono
parents:
diff changeset
846 } // ipa_icf_gimple namespace