]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ipa-icf-gimple.cc
inter-procedural value range propagation
[thirdparty/gcc.git] / gcc / ipa-icf-gimple.cc
CommitLineData
b84d4347 1/* Interprocedural Identical Code Folding pass
aeee4812 2 Copyright (C) 2014-2023 Free Software Foundation, Inc.
b84d4347
ML
3
4 Contributed by Jan Hubicka <hubicka@ucw.cz> and Martin Liska <mliska@suse.cz>
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 3, or (at your option) any later
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
21
22#include "config.h"
23#include "system.h"
24#include "coretypes.h"
c7131fb2 25#include "backend.h"
957060b5 26#include "rtl.h"
40e23961 27#include "tree.h"
b84d4347 28#include "gimple.h"
957060b5 29#include "tree-pass.h"
c7131fb2 30#include "ssa.h"
957060b5
AM
31#include "cgraph.h"
32#include "data-streamer.h"
33#include "gimple-pretty-print.h"
c7131fb2 34#include "fold-const.h"
b84d4347 35#include "gimple-iterator.h"
b84d4347 36#include "ipa-utils.h"
b84d4347 37#include "tree-eh.h"
d366a1a7 38#include "builtins.h"
8d2a3107 39#include "cfgloop.h"
55a73802 40#include "attribs.h"
a1fdc16d 41#include "gimple-walk.h"
b84d4347 42
602c6cfc 43#include "tree-ssa-alias-compare.h"
b84d4347 44#include "ipa-icf-gimple.h"
b84d4347
ML
45
46namespace ipa_icf_gimple {
47
48/* Initialize internal structures for a given SOURCE_FUNC_DECL and
49 TARGET_FUNC_DECL. Strict polymorphic comparison is processed if
50 an option COMPARE_POLYMORPHIC is true. For special cases, one can
51 set IGNORE_LABELS to skip label comparison.
52 Similarly, IGNORE_SOURCE_DECLS and IGNORE_TARGET_DECLS are sets
53 of declarations that can be skipped. */
54
55func_checker::func_checker (tree source_func_decl, tree target_func_decl,
602c6cfc 56 bool ignore_labels, bool tbaa,
b84d4347
ML
57 hash_set<symtab_node *> *ignored_source_nodes,
58 hash_set<symtab_node *> *ignored_target_nodes)
59 : m_source_func_decl (source_func_decl), m_target_func_decl (target_func_decl),
60 m_ignored_source_nodes (ignored_source_nodes),
61 m_ignored_target_nodes (ignored_target_nodes),
602c6cfc 62 m_ignore_labels (ignore_labels), m_tbaa (tbaa)
b84d4347
ML
63{
64 function *source_func = DECL_STRUCT_FUNCTION (source_func_decl);
65 function *target_func = DECL_STRUCT_FUNCTION (target_func_decl);
66
67 unsigned ssa_source = SSANAMES (source_func)->length ();
68 unsigned ssa_target = SSANAMES (target_func)->length ();
69
70 m_source_ssa_names.create (ssa_source);
71 m_target_ssa_names.create (ssa_target);
72
73 for (unsigned i = 0; i < ssa_source; i++)
74 m_source_ssa_names.safe_push (-1);
75
76 for (unsigned i = 0; i < ssa_target; i++)
77 m_target_ssa_names.safe_push (-1);
78}
79
80/* Memory release routine. */
81
82func_checker::~func_checker ()
83{
84 m_source_ssa_names.release();
85 m_target_ssa_names.release();
86}
87
88/* Verifies that trees T1 and T2 are equivalent from perspective of ICF. */
89
90bool
3f85ff83 91func_checker::compare_ssa_name (const_tree t1, const_tree t2)
b84d4347 92{
520b3022
ML
93 gcc_assert (TREE_CODE (t1) == SSA_NAME);
94 gcc_assert (TREE_CODE (t2) == SSA_NAME);
95
b84d4347
ML
96 unsigned i1 = SSA_NAME_VERSION (t1);
97 unsigned i2 = SSA_NAME_VERSION (t2);
98
b0de3ad2
ML
99 if (SSA_NAME_IS_DEFAULT_DEF (t1) != SSA_NAME_IS_DEFAULT_DEF (t2))
100 return false;
101
b84d4347
ML
102 if (m_source_ssa_names[i1] == -1)
103 m_source_ssa_names[i1] = i2;
104 else if (m_source_ssa_names[i1] != (int) i2)
105 return false;
106
107 if(m_target_ssa_names[i2] == -1)
108 m_target_ssa_names[i2] = i1;
109 else if (m_target_ssa_names[i2] != (int) i1)
110 return false;
111
520b3022
ML
112 if (SSA_NAME_IS_DEFAULT_DEF (t1))
113 {
114 tree b1 = SSA_NAME_VAR (t1);
115 tree b2 = SSA_NAME_VAR (t2);
116
a1fdc16d 117 return compare_operand (b1, b2, OP_NORMAL);
520b3022
ML
118 }
119
b84d4347
ML
120 return true;
121}
122
123/* Verification function for edges E1 and E2. */
124
125bool
126func_checker::compare_edge (edge e1, edge e2)
127{
128 if (e1->flags != e2->flags)
129 return false;
130
131 bool existed_p;
132
133 edge &slot = m_edge_map.get_or_insert (e1, &existed_p);
134 if (existed_p)
135 return return_with_debug (slot == e2);
136 else
137 slot = e2;
138
139 /* TODO: filter edge probabilities for profile feedback match. */
140
141 return true;
142}
143
144/* Verification function for declaration trees T1 and T2 that
145 come from functions FUNC1 and FUNC2. */
146
147bool
3f85ff83 148func_checker::compare_decl (const_tree t1, const_tree t2)
b84d4347
ML
149{
150 if (!auto_var_in_fn_p (t1, m_source_func_decl)
151 || !auto_var_in_fn_p (t2, m_target_func_decl))
152 return return_with_debug (t1 == t2);
153
154 tree_code t = TREE_CODE (t1);
155 if ((t == VAR_DECL || t == PARM_DECL || t == RESULT_DECL)
156 && DECL_BY_REFERENCE (t1) != DECL_BY_REFERENCE (t2))
157 return return_false_with_msg ("DECL_BY_REFERENCE flags are different");
158
4c3b16f3
JH
159 /* We do not really need to check types of variables, since they are just
160 blocks of memory and we verify types of the accesses to them.
161 However do compare types of other kinds of decls
162 (parm decls and result decl types may affect ABI convetions). */
163 if (t != VAR_DECL)
164 {
165 if (!compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2)))
166 return return_false ();
167 }
168 else
169 {
170 if (!operand_equal_p (DECL_SIZE (t1), DECL_SIZE (t2),
171 OEP_MATCH_SIDE_EFFECTS))
172 return return_false_with_msg ("DECL_SIZEs are different");
173 }
060cfff4 174
b84d4347 175 bool existed_p;
3f85ff83 176 const_tree &slot = m_decl_map.get_or_insert (t1, &existed_p);
b84d4347
ML
177 if (existed_p)
178 return return_with_debug (slot == t2);
179 else
180 slot = t2;
181
182 return true;
183}
184
060cfff4
JH
185/* Return true if T1 and T2 are same for purposes of ipa-polymorphic-call
186 analysis. COMPARE_PTR indicates if types of pointers needs to be
187 considered. */
188
189bool
190func_checker::compatible_polymorphic_types_p (tree t1, tree t2,
191 bool compare_ptr)
192{
193 gcc_assert (TREE_CODE (t1) != FUNCTION_TYPE && TREE_CODE (t1) != METHOD_TYPE);
194
195 /* Pointer types generally give no information. */
196 if (POINTER_TYPE_P (t1))
197 {
198 if (!compare_ptr)
199 return true;
200 return func_checker::compatible_polymorphic_types_p (TREE_TYPE (t1),
201 TREE_TYPE (t2),
202 false);
203 }
204
205 /* If types contain a polymorphic types, match them. */
206 bool c1 = contains_polymorphic_type_p (t1);
207 bool c2 = contains_polymorphic_type_p (t2);
208 if (!c1 && !c2)
209 return true;
210 if (!c1 || !c2)
211 return return_false_with_msg ("one type is not polymorphic");
212 if (!types_must_be_same_for_odr (t1, t2))
213 return return_false_with_msg ("types are not same for ODR");
214 return true;
215}
216
b84d4347 217/* Return true if types are compatible from perspective of ICF. */
520b3022 218bool
060cfff4 219func_checker::compatible_types_p (tree t1, tree t2)
b84d4347
ML
220{
221 if (TREE_CODE (t1) != TREE_CODE (t2))
222 return return_false_with_msg ("different tree types");
223
34b42fb0
ML
224 if (TYPE_RESTRICT (t1) != TYPE_RESTRICT (t2))
225 return return_false_with_msg ("restrict flags are different");
226
b84d4347
ML
227 if (!types_compatible_p (t1, t2))
228 return return_false_with_msg ("types are not compatible");
229
b84d4347
ML
230 return true;
231}
232
a1fdc16d
JH
233/* Add hash of ARG to HSTATE. FLAGS have same meaning
234 as for operand_equal_p. Works only if operand acces type is OP_NORMAL. */
520b3022 235
8a319aa3
ML
236void
237func_checker::hash_operand (const_tree arg, inchash::hash &hstate,
238 unsigned int flags)
239{
240 if (arg == NULL_TREE)
241 {
242 hstate.merge_hash (0);
243 return;
244 }
245
246 switch (TREE_CODE (arg))
247 {
d1081010
JH
248 case PARM_DECL:
249 {
250 unsigned int index = 0;
251 if (DECL_CONTEXT (arg))
252 for (tree p = DECL_ARGUMENTS (DECL_CONTEXT (arg));
253 p && index < 32; p = DECL_CHAIN (p), index++)
254 if (p == arg)
255 break;
256 hstate.add_int (PARM_DECL);
257 hstate.add_int (index);
258 }
259 return;
8a319aa3
ML
260 case FUNCTION_DECL:
261 case VAR_DECL:
262 case LABEL_DECL:
8a319aa3
ML
263 case RESULT_DECL:
264 case CONST_DECL:
d1081010
JH
265 hstate.add_int (TREE_CODE (arg));
266 return;
8a319aa3 267 case SSA_NAME:
d1081010
JH
268 hstate.add_int (SSA_NAME);
269 if (SSA_NAME_IS_DEFAULT_DEF (arg))
270 hash_operand (SSA_NAME_VAR (arg), hstate, flags);
8a319aa3 271 return;
7edcaa0b
ML
272 case FIELD_DECL:
273 inchash::add_expr (DECL_FIELD_OFFSET (arg), hstate, flags);
274 inchash::add_expr (DECL_FIELD_BIT_OFFSET (arg), hstate, flags);
275 return;
8a319aa3
ML
276 default:
277 break;
278 }
279
8e394101
JH
280 /* In gimple all clobbers can be considered equal: while comparaing two
281 gimple clobbers we match the left hand memory accesses. */
282 if (TREE_CLOBBER_P (arg))
283 {
284 hstate.add_int (0xc10bbe5);
285 return;
286 }
d1081010
JH
287 gcc_assert (!DECL_P (arg));
288 gcc_assert (!TYPE_P (arg));
8e394101 289
8a319aa3
ML
290 return operand_compare::hash_operand (arg, hstate, flags);
291}
292
a1fdc16d
JH
293/* Add hash of ARG accesses according to ACCESS to HSTATE.
294 FLAGS have same meaning as for operand_equal_p. */
295
296void
297func_checker::hash_operand (const_tree arg, inchash::hash &hstate,
602c6cfc 298 unsigned int flags, operand_access_type access)
a1fdc16d 299{
602c6cfc
JH
300 if (access == OP_MEMORY)
301 {
302 ao_ref ref;
303 ao_ref_init (&ref, const_cast <tree> (arg));
304 return hash_ao_ref (&ref, lto_streaming_expected_p (), m_tbaa, hstate);
305 }
306 else
307 return hash_operand (arg, hstate, flags);
a1fdc16d
JH
308}
309
b84d4347 310bool
8a319aa3
ML
311func_checker::operand_equal_p (const_tree t1, const_tree t2,
312 unsigned int flags)
b84d4347 313{
8a319aa3
ML
314 bool r;
315 if (verify_hash_value (t1, t2, flags, &r))
316 return r;
b84d4347 317
8a319aa3 318 if (t1 == t2)
b84d4347
ML
319 return true;
320 else if (!t1 || !t2)
321 return false;
322
b84d4347
ML
323 if (TREE_CODE (t1) != TREE_CODE (t2))
324 return return_false ();
325
326 switch (TREE_CODE (t1))
327 {
8a319aa3
ML
328 case FUNCTION_DECL:
329 /* All function decls are in the symbol table and known to match
330 before we start comparing bodies. */
331 return true;
332 case VAR_DECL:
3f85ff83 333 return return_with_debug (compare_variable_decl (t1, t2));
8a319aa3 334 case LABEL_DECL:
6d244704 335 {
3f85ff83
ML
336 int *bb1 = m_label_bb_map.get (t1);
337 int *bb2 = m_label_bb_map.get (t2);
8a319aa3
ML
338 /* Labels can point to another function (non-local GOTOs). */
339 return return_with_debug (bb1 != NULL && bb2 != NULL && *bb1 == *bb2);
6d244704 340 }
b84d4347 341
8a319aa3
ML
342 case PARM_DECL:
343 case RESULT_DECL:
344 case CONST_DECL:
3f85ff83 345 return compare_decl (t1, t2);
8a319aa3 346 case SSA_NAME:
3f85ff83 347 return compare_ssa_name (t1, t2);
8a319aa3
ML
348 default:
349 break;
350 }
cd287abe 351 /* In gimple all clobbers can be considered equal. We match the left hand
8e394101
JH
352 memory accesses. */
353 if (TREE_CLOBBER_P (t1) || TREE_CLOBBER_P (t2))
354 return TREE_CLOBBER_P (t1) == TREE_CLOBBER_P (t2);
b84d4347 355
8a319aa3
ML
356 return operand_compare::operand_equal_p (t1, t2, flags);
357}
217c08c5 358
a1fdc16d
JH
359/* Function responsible for comparison of various operands T1 and T2
360 which are accessed as ACCESS.
8a319aa3
ML
361 If these components, from functions FUNC1 and FUNC2, are equal, true
362 is returned. */
217c08c5 363
8a319aa3 364bool
a1fdc16d 365func_checker::compare_operand (tree t1, tree t2, operand_access_type access)
8a319aa3
ML
366{
367 if (!t1 && !t2)
368 return true;
369 else if (!t1 || !t2)
370 return false;
602c6cfc 371 if (access == OP_MEMORY)
a1fdc16d 372 {
602c6cfc
JH
373 ao_ref ref1, ref2;
374 ao_ref_init (&ref1, const_cast <tree> (t1));
375 ao_ref_init (&ref2, const_cast <tree> (t2));
376 int flags = compare_ao_refs (&ref1, &ref2,
377 lto_streaming_expected_p (), m_tbaa);
378
379 if (!flags)
380 return true;
381 if (flags & SEMANTICS)
382 return return_false_with_msg
383 ("compare_ao_refs failed (semantic difference)");
384 if (flags & BASE_ALIAS_SET)
385 return return_false_with_msg
386 ("compare_ao_refs failed (base alias set difference)");
387 if (flags & REF_ALIAS_SET)
388 return return_false_with_msg
389 ("compare_ao_refs failed (ref alias set difference)");
390 if (flags & ACCESS_PATH)
391 return return_false_with_msg
392 ("compare_ao_refs failed (access path difference)");
393 if (flags & DEPENDENCE_CLIQUE)
394 return return_false_with_msg
395 ("compare_ao_refs failed (dependence clique difference)");
396 gcc_unreachable ();
397 }
398 else
399 {
400 if (operand_equal_p (t1, t2, OEP_MATCH_SIDE_EFFECTS))
401 return true;
a1fdc16d 402 return return_false_with_msg
602c6cfc 403 ("operand_equal_p failed");
a1fdc16d 404 }
b84d4347
ML
405}
406
b84d4347 407bool
a1fdc16d
JH
408func_checker::compare_asm_inputs_outputs (tree t1, tree t2,
409 operand_access_type_map *map)
b84d4347
ML
410{
411 gcc_assert (TREE_CODE (t1) == TREE_LIST);
412 gcc_assert (TREE_CODE (t2) == TREE_LIST);
413
414 for (; t1; t1 = TREE_CHAIN (t1))
415 {
416 if (!t2)
417 return false;
418
a1fdc16d
JH
419 if (!compare_operand (TREE_VALUE (t1), TREE_VALUE (t2),
420 get_operand_access_type (map, t1)))
b84d4347
ML
421 return return_false ();
422
6cc30cb4
ML
423 tree p1 = TREE_PURPOSE (t1);
424 tree p2 = TREE_PURPOSE (t2);
425
426 gcc_assert (TREE_CODE (p1) == TREE_LIST);
427 gcc_assert (TREE_CODE (p2) == TREE_LIST);
428
429 if (strcmp (TREE_STRING_POINTER (TREE_VALUE (p1)),
430 TREE_STRING_POINTER (TREE_VALUE (p2))) != 0)
431 return return_false ();
432
b84d4347
ML
433 t2 = TREE_CHAIN (t2);
434 }
435
436 if (t2)
437 return return_false ();
438
439 return true;
440}
441
b84d4347
ML
442/* Verifies that trees T1 and T2 do correspond. */
443
444bool
3f85ff83 445func_checker::compare_variable_decl (const_tree t1, const_tree t2)
b84d4347
ML
446{
447 bool ret = false;
448
449 if (t1 == t2)
450 return true;
451
e8fb91a8
ML
452 if (DECL_ALIGN (t1) != DECL_ALIGN (t2))
453 return return_false_with_msg ("alignments are different");
454
b4f26d91
ML
455 if (DECL_HARD_REGISTER (t1) != DECL_HARD_REGISTER (t2))
456 return return_false_with_msg ("DECL_HARD_REGISTER are different");
457
458 if (DECL_HARD_REGISTER (t1)
3f85ff83 459 && DECL_ASSEMBLER_NAME_RAW (t1) != DECL_ASSEMBLER_NAME_RAW (t2))
b4f26d91
ML
460 return return_false_with_msg ("HARD REGISTERS are different");
461
b6cddc7f
ML
462 /* Symbol table variables are known to match before we start comparing
463 bodies. */
464 if (decl_in_symtab_p (t1))
465 return decl_in_symtab_p (t2);
b84d4347
ML
466 ret = compare_decl (t1, t2);
467
468 return return_with_debug (ret);
469}
470
8d2a3107
ML
471/* Compare loop information for basic blocks BB1 and BB2. */
472
473bool
474func_checker::compare_loops (basic_block bb1, basic_block bb2)
475{
476 if ((bb1->loop_father == NULL) != (bb2->loop_father == NULL))
477 return return_false ();
478
99b1c316
MS
479 class loop *l1 = bb1->loop_father;
480 class loop *l2 = bb2->loop_father;
8d2a3107
ML
481 if (l1 == NULL)
482 return true;
483
484 if ((bb1 == l1->header) != (bb2 == l2->header))
485 return return_false_with_msg ("header");
486 if ((bb1 == l1->latch) != (bb2 == l2->latch))
487 return return_false_with_msg ("latch");
488 if (l1->simdlen != l2->simdlen)
489 return return_false_with_msg ("simdlen");
490 if (l1->safelen != l2->safelen)
491 return return_false_with_msg ("safelen");
492 if (l1->can_be_parallel != l2->can_be_parallel)
493 return return_false_with_msg ("can_be_parallel");
494 if (l1->dont_vectorize != l2->dont_vectorize)
495 return return_false_with_msg ("dont_vectorize");
496 if (l1->force_vectorize != l2->force_vectorize)
497 return return_false_with_msg ("force_vectorize");
75efe9cb
RB
498 if (l1->finite_p != l2->finite_p)
499 return return_false_with_msg ("finite_p");
8d2a3107
ML
500 if (l1->unroll != l2->unroll)
501 return return_false_with_msg ("unroll");
502 if (!compare_variable_decl (l1->simduid, l2->simduid))
503 return return_false_with_msg ("simduid");
504
505 return true;
506}
47a668cd
ML
507
508/* Function visits all gimple labels and creates corresponding
509 mapping between basic blocks and labels. */
510
b84d4347
ML
511void
512func_checker::parse_labels (sem_bb *bb)
513{
514 for (gimple_stmt_iterator gsi = gsi_start_bb (bb->bb); !gsi_end_p (gsi);
515 gsi_next (&gsi))
516 {
355fe088 517 gimple *stmt = gsi_stmt (gsi);
b84d4347 518
538dd0b7 519 if (glabel *label_stmt = dyn_cast <glabel *> (stmt))
b84d4347 520 {
3f85ff83 521 const_tree t = gimple_label_label (label_stmt);
b84d4347
ML
522 gcc_assert (TREE_CODE (t) == LABEL_DECL);
523
524 m_label_bb_map.put (t, bb->bb->index);
525 }
526 }
527}
528
529/* Basic block equivalence comparison function that returns true if
530 basic blocks BB1 and BB2 (from functions FUNC1 and FUNC2) correspond.
531
532 In general, a collection of equivalence dictionaries is built for types
533 like SSA names, declarations (VAR_DECL, PARM_DECL, ..). This infrastructure
b607f49b 534 is utilized by every statement-by-statement comparison function. */
b84d4347
ML
535
536bool
537func_checker::compare_bb (sem_bb *bb1, sem_bb *bb2)
538{
b84d4347 539 gimple_stmt_iterator gsi1, gsi2;
355fe088 540 gimple *s1, *s2;
b84d4347 541
65f4b875
AO
542 gsi1 = gsi_start_nondebug_bb (bb1->bb);
543 gsi2 = gsi_start_nondebug_bb (bb2->bb);
b84d4347 544
42c0b54d 545 while (!gsi_end_p (gsi1))
b84d4347 546 {
42c0b54d
ML
547 if (gsi_end_p (gsi2))
548 return return_false ();
b84d4347
ML
549
550 s1 = gsi_stmt (gsi1);
551 s2 = gsi_stmt (gsi2);
552
553 int eh1 = lookup_stmt_eh_lp_fn
554 (DECL_STRUCT_FUNCTION (m_source_func_decl), s1);
555 int eh2 = lookup_stmt_eh_lp_fn
556 (DECL_STRUCT_FUNCTION (m_target_func_decl), s2);
557
558 if (eh1 != eh2)
559 return return_false_with_msg ("EH regions are different");
560
561 if (gimple_code (s1) != gimple_code (s2))
562 return return_false_with_msg ("gimple codes are different");
563
564 switch (gimple_code (s1))
565 {
566 case GIMPLE_CALL:
538dd0b7
DM
567 if (!compare_gimple_call (as_a <gcall *> (s1),
568 as_a <gcall *> (s2)))
b84d4347
ML
569 return return_different_stmts (s1, s2, "GIMPLE_CALL");
570 break;
571 case GIMPLE_ASSIGN:
572 if (!compare_gimple_assign (s1, s2))
573 return return_different_stmts (s1, s2, "GIMPLE_ASSIGN");
574 break;
575 case GIMPLE_COND:
576 if (!compare_gimple_cond (s1, s2))
577 return return_different_stmts (s1, s2, "GIMPLE_COND");
578 break;
579 case GIMPLE_SWITCH:
538dd0b7
DM
580 if (!compare_gimple_switch (as_a <gswitch *> (s1),
581 as_a <gswitch *> (s2)))
b84d4347
ML
582 return return_different_stmts (s1, s2, "GIMPLE_SWITCH");
583 break;
584 case GIMPLE_DEBUG:
366ee94b 585 break;
b84d4347 586 case GIMPLE_EH_DISPATCH:
366ee94b
JJ
587 if (gimple_eh_dispatch_region (as_a <geh_dispatch *> (s1))
588 != gimple_eh_dispatch_region (as_a <geh_dispatch *> (s2)))
589 return return_different_stmts (s1, s2, "GIMPLE_EH_DISPATCH");
b84d4347
ML
590 break;
591 case GIMPLE_RESX:
538dd0b7
DM
592 if (!compare_gimple_resx (as_a <gresx *> (s1),
593 as_a <gresx *> (s2)))
b84d4347
ML
594 return return_different_stmts (s1, s2, "GIMPLE_RESX");
595 break;
596 case GIMPLE_LABEL:
538dd0b7
DM
597 if (!compare_gimple_label (as_a <glabel *> (s1),
598 as_a <glabel *> (s2)))
b84d4347
ML
599 return return_different_stmts (s1, s2, "GIMPLE_LABEL");
600 break;
601 case GIMPLE_RETURN:
538dd0b7
DM
602 if (!compare_gimple_return (as_a <greturn *> (s1),
603 as_a <greturn *> (s2)))
b84d4347
ML
604 return return_different_stmts (s1, s2, "GIMPLE_RETURN");
605 break;
606 case GIMPLE_GOTO:
607 if (!compare_gimple_goto (s1, s2))
608 return return_different_stmts (s1, s2, "GIMPLE_GOTO");
609 break;
610 case GIMPLE_ASM:
538dd0b7
DM
611 if (!compare_gimple_asm (as_a <gasm *> (s1),
612 as_a <gasm *> (s2)))
b84d4347
ML
613 return return_different_stmts (s1, s2, "GIMPLE_ASM");
614 break;
615 case GIMPLE_PREDICT:
616 case GIMPLE_NOP:
366ee94b 617 break;
b84d4347
ML
618 default:
619 return return_false_with_msg ("Unknown GIMPLE code reached");
620 }
621
42c0b54d
ML
622 gsi_next_nondebug (&gsi1);
623 gsi_next_nondebug (&gsi2);
b84d4347
ML
624 }
625
42c0b54d
ML
626 if (!gsi_end_p (gsi2))
627 return return_false ();
628
8d2a3107
ML
629 if (!compare_loops (bb1->bb, bb2->bb))
630 return return_false ();
631
b84d4347
ML
632 return true;
633}
634
635/* Verifies for given GIMPLEs S1 and S2 that
636 call statements are semantically equivalent. */
637
638bool
538dd0b7 639func_checker::compare_gimple_call (gcall *s1, gcall *s2)
b84d4347
ML
640{
641 unsigned i;
642 tree t1, t2;
643
644 if (gimple_call_num_args (s1) != gimple_call_num_args (s2))
645 return false;
646
a1fdc16d
JH
647 operand_access_type_map map (5);
648 classify_operands (s1, &map);
649
b607f49b
JJ
650 t1 = gimple_call_fn (s1);
651 t2 = gimple_call_fn (s2);
a1fdc16d 652 if (!compare_operand (t1, t2, get_operand_access_type (&map, t1)))
b607f49b
JJ
653 return return_false ();
654
655 /* Compare flags. */
656 if (gimple_call_internal_p (s1) != gimple_call_internal_p (s2)
657 || gimple_call_ctrl_altering_p (s1) != gimple_call_ctrl_altering_p (s2)
658 || gimple_call_tail_p (s1) != gimple_call_tail_p (s2)
659 || gimple_call_return_slot_opt_p (s1) != gimple_call_return_slot_opt_p (s2)
660 || gimple_call_from_thunk_p (s1) != gimple_call_from_thunk_p (s2)
0b945f95 661 || gimple_call_from_new_or_delete (s1) != gimple_call_from_new_or_delete (s2)
b607f49b 662 || gimple_call_va_arg_pack_p (s1) != gimple_call_va_arg_pack_p (s2)
31db0fe0 663 || gimple_call_alloca_for_var_p (s1) != gimple_call_alloca_for_var_p (s2))
b607f49b
JJ
664 return false;
665
666 if (gimple_call_internal_p (s1)
667 && gimple_call_internal_fn (s1) != gimple_call_internal_fn (s2))
668 return false;
669
670 tree fntype1 = gimple_call_fntype (s1);
671 tree fntype2 = gimple_call_fntype (s2);
602c6cfc 672
070ab283 673 /* For direct calls we verify that types are compatible so if we matched
602c6cfc
JH
674 callees, callers must match, too. For indirect calls however verify
675 function type. */
676 if (!gimple_call_fndecl (s1))
677 {
678 if ((fntype1 && !fntype2)
679 || (!fntype1 && fntype2)
680 || (fntype1 && !types_compatible_p (fntype1, fntype2)))
681 return return_false_with_msg ("call function types are not compatible");
682 }
b607f49b 683
55a73802
ML
684 if (fntype1 && fntype2 && comp_type_attributes (fntype1, fntype2) != 1)
685 return return_false_with_msg ("different fntype attributes");
686
b607f49b
JJ
687 tree chain1 = gimple_call_chain (s1);
688 tree chain2 = gimple_call_chain (s2);
689 if ((chain1 && !chain2)
690 || (!chain1 && chain2)
a1fdc16d
JH
691 || !compare_operand (chain1, chain2,
692 get_operand_access_type (&map, chain1)))
b607f49b 693 return return_false_with_msg ("static call chains are different");
b84d4347
ML
694
695 /* Checking of argument. */
696 for (i = 0; i < gimple_call_num_args (s1); ++i)
697 {
698 t1 = gimple_call_arg (s1, i);
699 t2 = gimple_call_arg (s2, i);
700
a1fdc16d 701 if (!compare_operand (t1, t2, get_operand_access_type (&map, t1)))
5d0152bf 702 return return_false_with_msg ("GIMPLE call operands are different");
b84d4347
ML
703 }
704
705 /* Return value checking. */
706 t1 = gimple_get_lhs (s1);
707 t2 = gimple_get_lhs (s2);
708
070ab283
JJ
709 /* For internal calls, lhs types need to be verified, as neither fntype nor
710 callee comparisons can catch that. */
711 if (gimple_call_internal_p (s1)
712 && t1
713 && t2
714 && !compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2)))
715 return return_false_with_msg ("GIMPLE internal call LHS type mismatch");
716
a1fdc16d 717 return compare_operand (t1, t2, get_operand_access_type (&map, t1));
b84d4347
ML
718}
719
720
721/* Verifies for given GIMPLEs S1 and S2 that
722 assignment statements are semantically equivalent. */
723
724bool
355fe088 725func_checker::compare_gimple_assign (gimple *s1, gimple *s2)
b84d4347
ML
726{
727 tree arg1, arg2;
728 tree_code code1, code2;
729 unsigned i;
730
b84d4347
ML
731 code1 = gimple_assign_rhs_code (s1);
732 code2 = gimple_assign_rhs_code (s2);
733
734 if (code1 != code2)
735 return false;
736
a1fdc16d
JH
737 operand_access_type_map map (5);
738 classify_operands (s1, &map);
739
b84d4347
ML
740 for (i = 0; i < gimple_num_ops (s1); i++)
741 {
742 arg1 = gimple_op (s1, i);
743 arg2 = gimple_op (s2, i);
744
08afe87b 745 /* Compare types for LHS. */
602c6cfc 746 if (i == 0 && !gimple_store_p (s1))
44609614
ML
747 {
748 if (!compatible_types_p (TREE_TYPE (arg1), TREE_TYPE (arg2)))
602c6cfc 749 return return_false_with_msg ("GIMPLE LHS type mismatch");
44609614
ML
750 }
751
a1fdc16d 752 if (!compare_operand (arg1, arg2, get_operand_access_type (&map, arg1)))
5d0152bf
ML
753 return return_false_with_msg ("GIMPLE assignment operands "
754 "are different");
b84d4347
ML
755 }
756
757
758 return true;
759}
760
761/* Verifies for given GIMPLEs S1 and S2 that
762 condition statements are semantically equivalent. */
763
764bool
355fe088 765func_checker::compare_gimple_cond (gimple *s1, gimple *s2)
b84d4347
ML
766{
767 tree t1, t2;
768 tree_code code1, code2;
769
4852c326
RB
770 code1 = gimple_cond_code (s1);
771 code2 = gimple_cond_code (s2);
b84d4347
ML
772
773 if (code1 != code2)
774 return false;
775
776 t1 = gimple_cond_lhs (s1);
777 t2 = gimple_cond_lhs (s2);
778
a1fdc16d 779 if (!compare_operand (t1, t2, OP_NORMAL))
b84d4347
ML
780 return false;
781
782 t1 = gimple_cond_rhs (s1);
783 t2 = gimple_cond_rhs (s2);
784
a1fdc16d 785 return compare_operand (t1, t2, OP_NORMAL);
b84d4347
ML
786}
787
538dd0b7 788/* Verifies for given GIMPLE_LABEL stmts S1 and S2 that
b84d4347
ML
789 label statements are semantically equivalent. */
790
791bool
538dd0b7 792func_checker::compare_gimple_label (const glabel *g1, const glabel *g2)
b84d4347
ML
793{
794 if (m_ignore_labels)
795 return true;
796
797 tree t1 = gimple_label_label (g1);
798 tree t2 = gimple_label_label (g2);
799
800 if (FORCED_LABEL (t1) || FORCED_LABEL (t2))
801 return return_false_with_msg ("FORCED_LABEL");
802
47a668cd
ML
803 /* As the pass build BB to label mapping, no further check is needed. */
804 return true;
b84d4347
ML
805}
806
538dd0b7 807/* Verifies for given GIMPLE_SWITCH stmts S1 and S2 that
b84d4347
ML
808 switch statements are semantically equivalent. */
809
810bool
538dd0b7 811func_checker::compare_gimple_switch (const gswitch *g1, const gswitch *g2)
b84d4347
ML
812{
813 unsigned lsize1, lsize2, i;
814
815 lsize1 = gimple_switch_num_labels (g1);
816 lsize2 = gimple_switch_num_labels (g2);
817
818 if (lsize1 != lsize2)
819 return false;
820
821 tree t1 = gimple_switch_index (g1);
822 tree t2 = gimple_switch_index (g2);
823
a1fdc16d 824 if (!compare_operand (t1, t2, OP_NORMAL))
b84d4347
ML
825 return false;
826
827 for (i = 0; i < lsize1; i++)
828 {
829 tree label1 = gimple_switch_label (g1, i);
830 tree label2 = gimple_switch_label (g2, i);
831
fdaaeea1
ML
832 /* Label LOW and HIGH comparison. */
833 tree low1 = CASE_LOW (label1);
834 tree low2 = CASE_LOW (label2);
835
836 if (!tree_int_cst_equal (low1, low2))
837 return return_false_with_msg ("case low values are different");
838
839 tree high1 = CASE_HIGH (label1);
840 tree high2 = CASE_HIGH (label2);
841
842 if (!tree_int_cst_equal (high1, high2))
843 return return_false_with_msg ("case high values are different");
844
b84d4347
ML
845 if (TREE_CODE (label1) == CASE_LABEL_EXPR
846 && TREE_CODE (label2) == CASE_LABEL_EXPR)
847 {
848 label1 = CASE_LABEL (label1);
849 label2 = CASE_LABEL (label2);
850
a1fdc16d 851 if (!compare_operand (label1, label2, OP_NORMAL))
b84d4347
ML
852 return return_false_with_msg ("switch label_exprs are different");
853 }
854 else if (!tree_int_cst_equal (label1, label2))
855 return return_false_with_msg ("switch labels are different");
856 }
857
858 return true;
859}
860
538dd0b7 861/* Verifies for given GIMPLE_RETURN stmts S1 and S2 that
b84d4347
ML
862 return statements are semantically equivalent. */
863
864bool
538dd0b7 865func_checker::compare_gimple_return (const greturn *g1, const greturn *g2)
b84d4347
ML
866{
867 tree t1, t2;
868
869 t1 = gimple_return_retval (g1);
870 t2 = gimple_return_retval (g2);
871
872 /* Void return type. */
873 if (t1 == NULL && t2 == NULL)
874 return true;
875 else
a1fdc16d
JH
876 {
877 operand_access_type_map map (3);
878 return compare_operand (t1, t2, get_operand_access_type (&map, t1));
879 }
b84d4347
ML
880}
881
882/* Verifies for given GIMPLEs S1 and S2 that
883 goto statements are semantically equivalent. */
884
885bool
355fe088 886func_checker::compare_gimple_goto (gimple *g1, gimple *g2)
b84d4347
ML
887{
888 tree dest1, dest2;
889
890 dest1 = gimple_goto_dest (g1);
891 dest2 = gimple_goto_dest (g2);
892
893 if (TREE_CODE (dest1) != TREE_CODE (dest2) || TREE_CODE (dest1) != SSA_NAME)
894 return false;
895
a1fdc16d 896 return compare_operand (dest1, dest2, OP_NORMAL);
b84d4347
ML
897}
898
538dd0b7 899/* Verifies for given GIMPLE_RESX stmts S1 and S2 that
b84d4347
ML
900 resx statements are semantically equivalent. */
901
902bool
538dd0b7 903func_checker::compare_gimple_resx (const gresx *g1, const gresx *g2)
b84d4347
ML
904{
905 return gimple_resx_region (g1) == gimple_resx_region (g2);
906}
907
908/* Verifies for given GIMPLEs S1 and S2 that ASM statements are equivalent.
909 For the beginning, the pass only supports equality for
910 '__asm__ __volatile__ ("", "", "", "memory")'. */
911
912bool
538dd0b7 913func_checker::compare_gimple_asm (const gasm *g1, const gasm *g2)
b84d4347
ML
914{
915 if (gimple_asm_volatile_p (g1) != gimple_asm_volatile_p (g2))
916 return false;
917
a20b6691
BE
918 if (gimple_asm_input_p (g1) != gimple_asm_input_p (g2))
919 return false;
920
5b76e75f
SB
921 if (gimple_asm_inline_p (g1) != gimple_asm_inline_p (g2))
922 return false;
923
b84d4347
ML
924 if (gimple_asm_ninputs (g1) != gimple_asm_ninputs (g2))
925 return false;
926
927 if (gimple_asm_noutputs (g1) != gimple_asm_noutputs (g2))
928 return false;
929
930 /* We do not suppport goto ASM statement comparison. */
931 if (gimple_asm_nlabels (g1) || gimple_asm_nlabels (g2))
932 return false;
933
934 if (gimple_asm_nclobbers (g1) != gimple_asm_nclobbers (g2))
935 return false;
936
13f659d4
ML
937 if (strcmp (gimple_asm_string (g1), gimple_asm_string (g2)) != 0)
938 return return_false_with_msg ("ASM strings are different");
939
a1fdc16d
JH
940 operand_access_type_map map (5);
941 classify_operands (g1, &map);
942
b84d4347
ML
943 for (unsigned i = 0; i < gimple_asm_ninputs (g1); i++)
944 {
945 tree input1 = gimple_asm_input_op (g1, i);
946 tree input2 = gimple_asm_input_op (g2, i);
947
a1fdc16d 948 if (!compare_asm_inputs_outputs (input1, input2, &map))
b84d4347
ML
949 return return_false_with_msg ("ASM input is different");
950 }
951
952 for (unsigned i = 0; i < gimple_asm_noutputs (g1); i++)
953 {
954 tree output1 = gimple_asm_output_op (g1, i);
955 tree output2 = gimple_asm_output_op (g2, i);
956
a1fdc16d 957 if (!compare_asm_inputs_outputs (output1, output2, &map))
b84d4347
ML
958 return return_false_with_msg ("ASM output is different");
959 }
960
961 for (unsigned i = 0; i < gimple_asm_nclobbers (g1); i++)
962 {
963 tree clobber1 = gimple_asm_clobber_op (g1, i);
964 tree clobber2 = gimple_asm_clobber_op (g2, i);
965
966 if (!operand_equal_p (TREE_VALUE (clobber1), TREE_VALUE (clobber2),
967 OEP_ONLY_CONST))
968 return return_false_with_msg ("ASM clobber is different");
969 }
970
971 return true;
972}
973
a1fdc16d
JH
974/* Helper for func_checker::classify_operands. Record that T is a load. */
975
976static bool
977visit_load_store (gimple *, tree, tree t, void *data)
978{
979 func_checker::operand_access_type_map *map =
980 (func_checker::operand_access_type_map *) data;
981 map->add (t);
982 return false;
983}
984
985/* Compute hash map determining access types of operands. */
986
987void
988func_checker::classify_operands (const gimple *stmt,
989 operand_access_type_map *map)
990{
991 walk_stmt_load_store_ops (const_cast <gimple *> (stmt),
992 (void *)map, visit_load_store, visit_load_store);
993}
994
995/* Return access type of a given operand. */
996
997func_checker::operand_access_type
998func_checker::get_operand_access_type (operand_access_type_map *map, tree t)
999{
1000 if (map->contains (t))
1001 return OP_MEMORY;
1002 return OP_NORMAL;
1003}
1004
b84d4347 1005} // ipa_icf_gimple namespace