1 /* Interprocedural Identical Code Folding pass
2 Copyright (C) 2014-2018 Free Software Foundation, Inc.
4 Contributed by Jan Hubicka <hubicka@ucw.cz> and Martin Liska <mliska@suse.cz>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
24 #include "coretypes.h"
29 #include "tree-pass.h"
32 #include "data-streamer.h"
33 #include "gimple-pretty-print.h"
35 #include "fold-const.h"
36 #include "gimple-iterator.h"
37 #include "ipa-utils.h"
41 #include "ipa-icf-gimple.h"
43 namespace ipa_icf_gimple
{
45 /* Initialize internal structures for a given SOURCE_FUNC_DECL and
46 TARGET_FUNC_DECL. Strict polymorphic comparison is processed if
47 an option COMPARE_POLYMORPHIC is true. For special cases, one can
48 set IGNORE_LABELS to skip label comparison.
49 Similarly, IGNORE_SOURCE_DECLS and IGNORE_TARGET_DECLS are sets
50 of declarations that can be skipped. */
52 func_checker::func_checker (tree source_func_decl
, tree target_func_decl
,
53 bool compare_polymorphic
,
55 hash_set
<symtab_node
*> *ignored_source_nodes
,
56 hash_set
<symtab_node
*> *ignored_target_nodes
)
57 : m_source_func_decl (source_func_decl
), m_target_func_decl (target_func_decl
),
58 m_ignored_source_nodes (ignored_source_nodes
),
59 m_ignored_target_nodes (ignored_target_nodes
),
60 m_compare_polymorphic (compare_polymorphic
),
61 m_ignore_labels (ignore_labels
)
63 function
*source_func
= DECL_STRUCT_FUNCTION (source_func_decl
);
64 function
*target_func
= DECL_STRUCT_FUNCTION (target_func_decl
);
66 unsigned ssa_source
= SSANAMES (source_func
)->length ();
67 unsigned ssa_target
= SSANAMES (target_func
)->length ();
69 m_source_ssa_names
.create (ssa_source
);
70 m_target_ssa_names
.create (ssa_target
);
72 for (unsigned i
= 0; i
< ssa_source
; i
++)
73 m_source_ssa_names
.safe_push (-1);
75 for (unsigned i
= 0; i
< ssa_target
; i
++)
76 m_target_ssa_names
.safe_push (-1);
79 /* Memory release routine. */
81 func_checker::~func_checker ()
83 m_source_ssa_names
.release();
84 m_target_ssa_names
.release();
87 /* Verifies that trees T1 and T2 are equivalent from perspective of ICF. */
90 func_checker::compare_ssa_name (tree t1
, tree t2
)
92 gcc_assert (TREE_CODE (t1
) == SSA_NAME
);
93 gcc_assert (TREE_CODE (t2
) == SSA_NAME
);
95 unsigned i1
= SSA_NAME_VERSION (t1
);
96 unsigned i2
= SSA_NAME_VERSION (t2
);
98 if (m_source_ssa_names
[i1
] == -1)
99 m_source_ssa_names
[i1
] = i2
;
100 else if (m_source_ssa_names
[i1
] != (int) i2
)
103 if(m_target_ssa_names
[i2
] == -1)
104 m_target_ssa_names
[i2
] = i1
;
105 else if (m_target_ssa_names
[i2
] != (int) i1
)
108 if (SSA_NAME_IS_DEFAULT_DEF (t1
))
110 tree b1
= SSA_NAME_VAR (t1
);
111 tree b2
= SSA_NAME_VAR (t2
);
113 if (b1
== NULL
&& b2
== NULL
)
116 if (b1
== NULL
|| b2
== NULL
|| TREE_CODE (b1
) != TREE_CODE (b2
))
117 return return_false ();
119 return compare_cst_or_decl (b1
, b2
);
125 /* Verification function for edges E1 and E2. */
128 func_checker::compare_edge (edge e1
, edge e2
)
130 if (e1
->flags
!= e2
->flags
)
135 edge
&slot
= m_edge_map
.get_or_insert (e1
, &existed_p
);
137 return return_with_debug (slot
== e2
);
141 /* TODO: filter edge probabilities for profile feedback match. */
146 /* Verification function for declaration trees T1 and T2 that
147 come from functions FUNC1 and FUNC2. */
150 func_checker::compare_decl (tree t1
, tree t2
)
152 if (!auto_var_in_fn_p (t1
, m_source_func_decl
)
153 || !auto_var_in_fn_p (t2
, m_target_func_decl
))
154 return return_with_debug (t1
== t2
);
156 tree_code t
= TREE_CODE (t1
);
157 if ((t
== VAR_DECL
|| t
== PARM_DECL
|| t
== RESULT_DECL
)
158 && DECL_BY_REFERENCE (t1
) != DECL_BY_REFERENCE (t2
))
159 return return_false_with_msg ("DECL_BY_REFERENCE flags are different");
161 if (!compatible_types_p (TREE_TYPE (t1
), TREE_TYPE (t2
)))
162 return return_false ();
164 /* TODO: we are actually too strict here. We only need to compare if
165 T1 can be used in polymorphic call. */
166 if (TREE_ADDRESSABLE (t1
)
167 && m_compare_polymorphic
168 && !compatible_polymorphic_types_p (TREE_TYPE (t1
), TREE_TYPE (t2
),
170 return return_false ();
172 if ((t
== VAR_DECL
|| t
== PARM_DECL
|| t
== RESULT_DECL
)
173 && DECL_BY_REFERENCE (t1
)
174 && m_compare_polymorphic
175 && !compatible_polymorphic_types_p (TREE_TYPE (t1
), TREE_TYPE (t2
),
177 return return_false ();
181 tree
&slot
= m_decl_map
.get_or_insert (t1
, &existed_p
);
183 return return_with_debug (slot
== t2
);
190 /* Return true if T1 and T2 are same for purposes of ipa-polymorphic-call
191 analysis. COMPARE_PTR indicates if types of pointers needs to be
195 func_checker::compatible_polymorphic_types_p (tree t1
, tree t2
,
198 gcc_assert (TREE_CODE (t1
) != FUNCTION_TYPE
&& TREE_CODE (t1
) != METHOD_TYPE
);
200 /* Pointer types generally give no information. */
201 if (POINTER_TYPE_P (t1
))
205 return func_checker::compatible_polymorphic_types_p (TREE_TYPE (t1
),
210 /* If types contain a polymorphic types, match them. */
211 bool c1
= contains_polymorphic_type_p (t1
);
212 bool c2
= contains_polymorphic_type_p (t2
);
216 return return_false_with_msg ("one type is not polymorphic");
217 if (!types_must_be_same_for_odr (t1
, t2
))
218 return return_false_with_msg ("types are not same for ODR");
222 /* Return true if types are compatible from perspective of ICF. */
224 func_checker::compatible_types_p (tree t1
, tree t2
)
226 if (TREE_CODE (t1
) != TREE_CODE (t2
))
227 return return_false_with_msg ("different tree types");
229 if (TYPE_RESTRICT (t1
) != TYPE_RESTRICT (t2
))
230 return return_false_with_msg ("restrict flags are different");
232 if (!types_compatible_p (t1
, t2
))
233 return return_false_with_msg ("types are not compatible");
235 /* We do a lot of unnecesary matching of types that are not being
236 accessed and thus do not need to be compatible. In longer term we should
237 remove these checks on all types which are not accessed as memory
240 For time being just avoid calling get_alias_set on types that are not
241 having alias sets defined at all. */
242 if (type_with_alias_set_p (t1
) && type_with_alias_set_p (t2
)
243 && get_alias_set (t1
) != get_alias_set (t2
))
244 return return_false_with_msg ("alias sets are different");
249 /* Function compare for equality given memory operands T1 and T2. */
252 func_checker::compare_memory_operand (tree t1
, tree t2
)
260 ao_ref_init (&r1
, t1
);
261 ao_ref_init (&r2
, t2
);
263 tree b1
= ao_ref_base (&r1
);
264 tree b2
= ao_ref_base (&r2
);
266 bool source_is_memop
= DECL_P (b1
) || INDIRECT_REF_P (b1
)
267 || TREE_CODE (b1
) == MEM_REF
268 || TREE_CODE (b1
) == TARGET_MEM_REF
;
270 bool target_is_memop
= DECL_P (b2
) || INDIRECT_REF_P (b2
)
271 || TREE_CODE (b2
) == MEM_REF
272 || TREE_CODE (b2
) == TARGET_MEM_REF
;
274 /* Compare alias sets for memory operands. */
275 if (source_is_memop
&& target_is_memop
)
277 if (TREE_THIS_VOLATILE (t1
) != TREE_THIS_VOLATILE (t2
))
278 return return_false_with_msg ("different operand volatility");
280 if (ao_ref_alias_set (&r1
) != ao_ref_alias_set (&r2
)
281 || ao_ref_base_alias_set (&r1
) != ao_ref_base_alias_set (&r2
))
282 return return_false_with_msg ("ao alias sets are different");
284 /* We can't simply use get_object_alignment_1 on the full
285 reference as for accesses with variable indexes this reports
286 too conservative alignment. We also can't use the ao_ref_base
287 base objects as ao_ref_base happily strips MEM_REFs around
288 decls even though that may carry alignment info. */
290 while (handled_component_p (b1
))
291 b1
= TREE_OPERAND (b1
, 0);
293 while (handled_component_p (b2
))
294 b2
= TREE_OPERAND (b2
, 0);
295 unsigned int align1
, align2
;
296 unsigned HOST_WIDE_INT tem
;
297 get_object_alignment_1 (b1
, &align1
, &tem
);
298 get_object_alignment_1 (b2
, &align2
, &tem
);
299 if (align1
!= align2
)
300 return return_false_with_msg ("different access alignment");
302 /* Similarly we have to compare dependence info where equality
303 tells us we are safe (even some unequal values would be safe
304 but then we have to maintain a map of bases and cliques). */
305 unsigned short clique1
= 0, base1
= 0, clique2
= 0, base2
= 0;
306 if (TREE_CODE (b1
) == MEM_REF
)
308 clique1
= MR_DEPENDENCE_CLIQUE (b1
);
309 base1
= MR_DEPENDENCE_BASE (b1
);
311 if (TREE_CODE (b2
) == MEM_REF
)
313 clique2
= MR_DEPENDENCE_CLIQUE (b2
);
314 base2
= MR_DEPENDENCE_BASE (b2
);
316 if (clique1
!= clique2
|| base1
!= base2
)
317 return return_false_with_msg ("different dependence info");
320 return compare_operand (t1
, t2
);
323 /* Function compare for equality given trees T1 and T2 which
324 can be either a constant or a declaration type. */
327 func_checker::compare_cst_or_decl (tree t1
, tree t2
)
331 switch (TREE_CODE (t1
))
339 ret
= compatible_types_p (TREE_TYPE (t1
), TREE_TYPE (t2
))
340 && operand_equal_p (t1
, t2
, OEP_ONLY_CONST
);
341 return return_with_debug (ret
);
344 /* All function decls are in the symbol table and known to match
345 before we start comparing bodies. */
348 return return_with_debug (compare_variable_decl (t1
, t2
));
351 tree offset1
= DECL_FIELD_OFFSET (t1
);
352 tree offset2
= DECL_FIELD_OFFSET (t2
);
354 tree bit_offset1
= DECL_FIELD_BIT_OFFSET (t1
);
355 tree bit_offset2
= DECL_FIELD_BIT_OFFSET (t2
);
357 ret
= compare_operand (offset1
, offset2
)
358 && compare_operand (bit_offset1
, bit_offset2
);
360 return return_with_debug (ret
);
367 int *bb1
= m_label_bb_map
.get (t1
);
368 int *bb2
= m_label_bb_map
.get (t2
);
370 /* Labels can point to another function (non-local GOTOs). */
371 return return_with_debug (bb1
!= NULL
&& bb2
!= NULL
&& *bb1
== *bb2
);
377 ret
= compare_decl (t1
, t2
);
378 return return_with_debug (ret
);
385 /* Function responsible for comparison of various operands T1 and T2.
386 If these components, from functions FUNC1 and FUNC2, are equal, true
390 func_checker::compare_operand (tree t1
, tree t2
)
392 tree x1
, x2
, y1
, y2
, z1
, z2
;
400 tree tt1
= TREE_TYPE (t1
);
401 tree tt2
= TREE_TYPE (t2
);
403 if (!func_checker::compatible_types_p (tt1
, tt2
))
406 if (TREE_CODE (t1
) != TREE_CODE (t2
))
407 return return_false ();
409 switch (TREE_CODE (t1
))
413 unsigned length1
= CONSTRUCTOR_NELTS (t1
);
414 unsigned length2
= CONSTRUCTOR_NELTS (t2
);
416 if (length1
!= length2
)
417 return return_false ();
419 for (unsigned i
= 0; i
< length1
; i
++)
420 if (!compare_operand (CONSTRUCTOR_ELT (t1
, i
)->value
,
421 CONSTRUCTOR_ELT (t2
, i
)->value
))
422 return return_false();
427 case ARRAY_RANGE_REF
:
428 /* First argument is the array, second is the index. */
429 x1
= TREE_OPERAND (t1
, 0);
430 x2
= TREE_OPERAND (t2
, 0);
431 y1
= TREE_OPERAND (t1
, 1);
432 y2
= TREE_OPERAND (t2
, 1);
434 if (!compare_operand (array_ref_low_bound (t1
),
435 array_ref_low_bound (t2
)))
436 return return_false_with_msg ("");
437 if (!compare_operand (array_ref_element_size (t1
),
438 array_ref_element_size (t2
)))
439 return return_false_with_msg ("");
441 if (!compare_operand (x1
, x2
))
442 return return_false_with_msg ("");
443 return compare_operand (y1
, y2
);
446 x1
= TREE_OPERAND (t1
, 0);
447 x2
= TREE_OPERAND (t2
, 0);
448 y1
= TREE_OPERAND (t1
, 1);
449 y2
= TREE_OPERAND (t2
, 1);
451 /* See if operand is an memory access (the test originate from
454 In this case the alias set of the function being replaced must
455 be subset of the alias set of the other function. At the moment
456 we seek for equivalency classes, so simply require inclussion in
459 if (!func_checker::compatible_types_p (TREE_TYPE (x1
), TREE_TYPE (x2
)))
460 return return_false ();
462 if (!compare_operand (x1
, x2
))
463 return return_false_with_msg ("");
465 /* Type of the offset on MEM_REF does not matter. */
466 return wi::to_offset (y1
) == wi::to_offset (y2
);
470 x1
= TREE_OPERAND (t1
, 0);
471 x2
= TREE_OPERAND (t2
, 0);
472 y1
= TREE_OPERAND (t1
, 1);
473 y2
= TREE_OPERAND (t2
, 1);
475 ret
= compare_operand (x1
, x2
)
476 && compare_cst_or_decl (y1
, y2
);
478 return return_with_debug (ret
);
480 /* Virtual table call. */
483 if (!compare_ssa_name (OBJ_TYPE_REF_EXPR (t1
), OBJ_TYPE_REF_EXPR (t2
)))
484 return return_false ();
485 if (opt_for_fn (m_source_func_decl
, flag_devirtualize
)
486 && virtual_method_call_p (t1
))
488 if (tree_to_uhwi (OBJ_TYPE_REF_TOKEN (t1
))
489 != tree_to_uhwi (OBJ_TYPE_REF_TOKEN (t2
)))
490 return return_false_with_msg ("OBJ_TYPE_REF token mismatch");
491 if (!types_same_for_odr (obj_type_ref_class (t1
),
492 obj_type_ref_class (t2
)))
493 return return_false_with_msg ("OBJ_TYPE_REF OTR type mismatch");
494 if (!compare_operand (OBJ_TYPE_REF_OBJECT (t1
),
495 OBJ_TYPE_REF_OBJECT (t2
)))
496 return return_false_with_msg ("OBJ_TYPE_REF object mismatch");
499 return return_with_debug (true);
505 x1
= TREE_OPERAND (t1
, 0);
506 x2
= TREE_OPERAND (t2
, 0);
508 ret
= compare_operand (x1
, x2
);
509 return return_with_debug (ret
);
513 x1
= TREE_OPERAND (t1
, 0);
514 x2
= TREE_OPERAND (t2
, 0);
515 y1
= TREE_OPERAND (t1
, 1);
516 y2
= TREE_OPERAND (t2
, 1);
517 z1
= TREE_OPERAND (t1
, 2);
518 z2
= TREE_OPERAND (t2
, 2);
520 ret
= compare_operand (x1
, x2
)
521 && compare_cst_or_decl (y1
, y2
)
522 && compare_cst_or_decl (z1
, z2
);
524 return return_with_debug (ret
);
527 return compare_ssa_name (t1
, t2
);
540 return compare_cst_or_decl (t1
, t2
);
542 return return_false_with_msg ("Unknown TREE code reached");
547 func_checker::compare_asm_inputs_outputs (tree t1
, tree t2
)
549 gcc_assert (TREE_CODE (t1
) == TREE_LIST
);
550 gcc_assert (TREE_CODE (t2
) == TREE_LIST
);
552 for (; t1
; t1
= TREE_CHAIN (t1
))
557 if (!compare_operand (TREE_VALUE (t1
), TREE_VALUE (t2
)))
558 return return_false ();
560 tree p1
= TREE_PURPOSE (t1
);
561 tree p2
= TREE_PURPOSE (t2
);
563 gcc_assert (TREE_CODE (p1
) == TREE_LIST
);
564 gcc_assert (TREE_CODE (p2
) == TREE_LIST
);
566 if (strcmp (TREE_STRING_POINTER (TREE_VALUE (p1
)),
567 TREE_STRING_POINTER (TREE_VALUE (p2
))) != 0)
568 return return_false ();
570 t2
= TREE_CHAIN (t2
);
574 return return_false ();
579 /* Verifies that trees T1 and T2 do correspond. */
582 func_checker::compare_variable_decl (tree t1
, tree t2
)
589 if (DECL_ALIGN (t1
) != DECL_ALIGN (t2
))
590 return return_false_with_msg ("alignments are different");
592 if (DECL_HARD_REGISTER (t1
) != DECL_HARD_REGISTER (t2
))
593 return return_false_with_msg ("DECL_HARD_REGISTER are different");
595 if (DECL_HARD_REGISTER (t1
)
596 && DECL_ASSEMBLER_NAME (t1
) != DECL_ASSEMBLER_NAME (t2
))
597 return return_false_with_msg ("HARD REGISTERS are different");
599 /* Symbol table variables are known to match before we start comparing
601 if (decl_in_symtab_p (t1
))
602 return decl_in_symtab_p (t2
);
603 ret
= compare_decl (t1
, t2
);
605 return return_with_debug (ret
);
609 /* Function visits all gimple labels and creates corresponding
610 mapping between basic blocks and labels. */
613 func_checker::parse_labels (sem_bb
*bb
)
615 for (gimple_stmt_iterator gsi
= gsi_start_bb (bb
->bb
); !gsi_end_p (gsi
);
618 gimple
*stmt
= gsi_stmt (gsi
);
620 if (glabel
*label_stmt
= dyn_cast
<glabel
*> (stmt
))
622 tree t
= gimple_label_label (label_stmt
);
623 gcc_assert (TREE_CODE (t
) == LABEL_DECL
);
625 m_label_bb_map
.put (t
, bb
->bb
->index
);
630 /* Basic block equivalence comparison function that returns true if
631 basic blocks BB1 and BB2 (from functions FUNC1 and FUNC2) correspond.
633 In general, a collection of equivalence dictionaries is built for types
634 like SSA names, declarations (VAR_DECL, PARM_DECL, ..). This infrastructure
635 is utilized by every statement-by-statement comparison function. */
638 func_checker::compare_bb (sem_bb
*bb1
, sem_bb
*bb2
)
640 gimple_stmt_iterator gsi1
, gsi2
;
643 gsi1
= gsi_start_nondebug_bb (bb1
->bb
);
644 gsi2
= gsi_start_nondebug_bb (bb2
->bb
);
646 while (!gsi_end_p (gsi1
))
648 if (gsi_end_p (gsi2
))
649 return return_false ();
651 s1
= gsi_stmt (gsi1
);
652 s2
= gsi_stmt (gsi2
);
654 int eh1
= lookup_stmt_eh_lp_fn
655 (DECL_STRUCT_FUNCTION (m_source_func_decl
), s1
);
656 int eh2
= lookup_stmt_eh_lp_fn
657 (DECL_STRUCT_FUNCTION (m_target_func_decl
), s2
);
660 return return_false_with_msg ("EH regions are different");
662 if (gimple_code (s1
) != gimple_code (s2
))
663 return return_false_with_msg ("gimple codes are different");
665 switch (gimple_code (s1
))
668 if (!compare_gimple_call (as_a
<gcall
*> (s1
),
669 as_a
<gcall
*> (s2
)))
670 return return_different_stmts (s1
, s2
, "GIMPLE_CALL");
673 if (!compare_gimple_assign (s1
, s2
))
674 return return_different_stmts (s1
, s2
, "GIMPLE_ASSIGN");
677 if (!compare_gimple_cond (s1
, s2
))
678 return return_different_stmts (s1
, s2
, "GIMPLE_COND");
681 if (!compare_gimple_switch (as_a
<gswitch
*> (s1
),
682 as_a
<gswitch
*> (s2
)))
683 return return_different_stmts (s1
, s2
, "GIMPLE_SWITCH");
687 case GIMPLE_EH_DISPATCH
:
688 if (gimple_eh_dispatch_region (as_a
<geh_dispatch
*> (s1
))
689 != gimple_eh_dispatch_region (as_a
<geh_dispatch
*> (s2
)))
690 return return_different_stmts (s1
, s2
, "GIMPLE_EH_DISPATCH");
693 if (!compare_gimple_resx (as_a
<gresx
*> (s1
),
694 as_a
<gresx
*> (s2
)))
695 return return_different_stmts (s1
, s2
, "GIMPLE_RESX");
698 if (!compare_gimple_label (as_a
<glabel
*> (s1
),
699 as_a
<glabel
*> (s2
)))
700 return return_different_stmts (s1
, s2
, "GIMPLE_LABEL");
703 if (!compare_gimple_return (as_a
<greturn
*> (s1
),
704 as_a
<greturn
*> (s2
)))
705 return return_different_stmts (s1
, s2
, "GIMPLE_RETURN");
708 if (!compare_gimple_goto (s1
, s2
))
709 return return_different_stmts (s1
, s2
, "GIMPLE_GOTO");
712 if (!compare_gimple_asm (as_a
<gasm
*> (s1
),
714 return return_different_stmts (s1
, s2
, "GIMPLE_ASM");
720 return return_false_with_msg ("Unknown GIMPLE code reached");
723 gsi_next_nondebug (&gsi1
);
724 gsi_next_nondebug (&gsi2
);
727 if (!gsi_end_p (gsi2
))
728 return return_false ();
733 /* Verifies for given GIMPLEs S1 and S2 that
734 call statements are semantically equivalent. */
737 func_checker::compare_gimple_call (gcall
*s1
, gcall
*s2
)
742 if (gimple_call_num_args (s1
) != gimple_call_num_args (s2
))
745 t1
= gimple_call_fn (s1
);
746 t2
= gimple_call_fn (s2
);
747 if (!compare_operand (t1
, t2
))
748 return return_false ();
751 if (gimple_call_internal_p (s1
) != gimple_call_internal_p (s2
)
752 || gimple_call_ctrl_altering_p (s1
) != gimple_call_ctrl_altering_p (s2
)
753 || gimple_call_tail_p (s1
) != gimple_call_tail_p (s2
)
754 || gimple_call_return_slot_opt_p (s1
) != gimple_call_return_slot_opt_p (s2
)
755 || gimple_call_from_thunk_p (s1
) != gimple_call_from_thunk_p (s2
)
756 || gimple_call_va_arg_pack_p (s1
) != gimple_call_va_arg_pack_p (s2
)
757 || gimple_call_alloca_for_var_p (s1
) != gimple_call_alloca_for_var_p (s2
)
758 || gimple_call_with_bounds_p (s1
) != gimple_call_with_bounds_p (s2
))
761 if (gimple_call_internal_p (s1
)
762 && gimple_call_internal_fn (s1
) != gimple_call_internal_fn (s2
))
765 tree fntype1
= gimple_call_fntype (s1
);
766 tree fntype2
= gimple_call_fntype (s2
);
767 if ((fntype1
&& !fntype2
)
768 || (!fntype1
&& fntype2
)
769 || (fntype1
&& !types_compatible_p (fntype1
, fntype2
)))
770 return return_false_with_msg ("call function types are not compatible");
772 tree chain1
= gimple_call_chain (s1
);
773 tree chain2
= gimple_call_chain (s2
);
774 if ((chain1
&& !chain2
)
775 || (!chain1
&& chain2
)
776 || !compare_operand (chain1
, chain2
))
777 return return_false_with_msg ("static call chains are different");
779 /* Checking of argument. */
780 for (i
= 0; i
< gimple_call_num_args (s1
); ++i
)
782 t1
= gimple_call_arg (s1
, i
);
783 t2
= gimple_call_arg (s2
, i
);
785 if (!compare_memory_operand (t1
, t2
))
786 return return_false_with_msg ("memory operands are different");
789 /* Return value checking. */
790 t1
= gimple_get_lhs (s1
);
791 t2
= gimple_get_lhs (s2
);
793 return compare_memory_operand (t1
, t2
);
797 /* Verifies for given GIMPLEs S1 and S2 that
798 assignment statements are semantically equivalent. */
801 func_checker::compare_gimple_assign (gimple
*s1
, gimple
*s2
)
804 tree_code code1
, code2
;
807 code1
= gimple_expr_code (s1
);
808 code2
= gimple_expr_code (s2
);
813 code1
= gimple_assign_rhs_code (s1
);
814 code2
= gimple_assign_rhs_code (s2
);
819 for (i
= 0; i
< gimple_num_ops (s1
); i
++)
821 arg1
= gimple_op (s1
, i
);
822 arg2
= gimple_op (s2
, i
);
824 if (!compare_memory_operand (arg1
, arg2
))
825 return return_false_with_msg ("memory operands are different");
832 /* Verifies for given GIMPLEs S1 and S2 that
833 condition statements are semantically equivalent. */
836 func_checker::compare_gimple_cond (gimple
*s1
, gimple
*s2
)
839 tree_code code1
, code2
;
841 code1
= gimple_expr_code (s1
);
842 code2
= gimple_expr_code (s2
);
847 t1
= gimple_cond_lhs (s1
);
848 t2
= gimple_cond_lhs (s2
);
850 if (!compare_operand (t1
, t2
))
853 t1
= gimple_cond_rhs (s1
);
854 t2
= gimple_cond_rhs (s2
);
856 return compare_operand (t1
, t2
);
859 /* Verifies that tree labels T1 and T2 correspond in FUNC1 and FUNC2. */
862 func_checker::compare_tree_ssa_label (tree t1
, tree t2
)
864 return compare_operand (t1
, t2
);
867 /* Verifies for given GIMPLE_LABEL stmts S1 and S2 that
868 label statements are semantically equivalent. */
871 func_checker::compare_gimple_label (const glabel
*g1
, const glabel
*g2
)
876 tree t1
= gimple_label_label (g1
);
877 tree t2
= gimple_label_label (g2
);
879 if (FORCED_LABEL (t1
) || FORCED_LABEL (t2
))
880 return return_false_with_msg ("FORCED_LABEL");
882 /* As the pass build BB to label mapping, no further check is needed. */
886 /* Verifies for given GIMPLE_SWITCH stmts S1 and S2 that
887 switch statements are semantically equivalent. */
890 func_checker::compare_gimple_switch (const gswitch
*g1
, const gswitch
*g2
)
892 unsigned lsize1
, lsize2
, i
;
894 lsize1
= gimple_switch_num_labels (g1
);
895 lsize2
= gimple_switch_num_labels (g2
);
897 if (lsize1
!= lsize2
)
900 tree t1
= gimple_switch_index (g1
);
901 tree t2
= gimple_switch_index (g2
);
903 if (!compare_operand (t1
, t2
))
906 for (i
= 0; i
< lsize1
; i
++)
908 tree label1
= gimple_switch_label (g1
, i
);
909 tree label2
= gimple_switch_label (g2
, i
);
911 /* Label LOW and HIGH comparison. */
912 tree low1
= CASE_LOW (label1
);
913 tree low2
= CASE_LOW (label2
);
915 if (!tree_int_cst_equal (low1
, low2
))
916 return return_false_with_msg ("case low values are different");
918 tree high1
= CASE_HIGH (label1
);
919 tree high2
= CASE_HIGH (label2
);
921 if (!tree_int_cst_equal (high1
, high2
))
922 return return_false_with_msg ("case high values are different");
924 if (TREE_CODE (label1
) == CASE_LABEL_EXPR
925 && TREE_CODE (label2
) == CASE_LABEL_EXPR
)
927 label1
= CASE_LABEL (label1
);
928 label2
= CASE_LABEL (label2
);
930 if (!compare_operand (label1
, label2
))
931 return return_false_with_msg ("switch label_exprs are different");
933 else if (!tree_int_cst_equal (label1
, label2
))
934 return return_false_with_msg ("switch labels are different");
940 /* Verifies for given GIMPLE_RETURN stmts S1 and S2 that
941 return statements are semantically equivalent. */
944 func_checker::compare_gimple_return (const greturn
*g1
, const greturn
*g2
)
948 t1
= gimple_return_retval (g1
);
949 t2
= gimple_return_retval (g2
);
951 /* Void return type. */
952 if (t1
== NULL
&& t2
== NULL
)
955 return compare_operand (t1
, t2
);
958 /* Verifies for given GIMPLEs S1 and S2 that
959 goto statements are semantically equivalent. */
962 func_checker::compare_gimple_goto (gimple
*g1
, gimple
*g2
)
966 dest1
= gimple_goto_dest (g1
);
967 dest2
= gimple_goto_dest (g2
);
969 if (TREE_CODE (dest1
) != TREE_CODE (dest2
) || TREE_CODE (dest1
) != SSA_NAME
)
972 return compare_operand (dest1
, dest2
);
975 /* Verifies for given GIMPLE_RESX stmts S1 and S2 that
976 resx statements are semantically equivalent. */
979 func_checker::compare_gimple_resx (const gresx
*g1
, const gresx
*g2
)
981 return gimple_resx_region (g1
) == gimple_resx_region (g2
);
984 /* Verifies for given GIMPLEs S1 and S2 that ASM statements are equivalent.
985 For the beginning, the pass only supports equality for
986 '__asm__ __volatile__ ("", "", "", "memory")'. */
989 func_checker::compare_gimple_asm (const gasm
*g1
, const gasm
*g2
)
991 if (gimple_asm_volatile_p (g1
) != gimple_asm_volatile_p (g2
))
994 if (gimple_asm_input_p (g1
) != gimple_asm_input_p (g2
))
997 if (gimple_asm_ninputs (g1
) != gimple_asm_ninputs (g2
))
1000 if (gimple_asm_noutputs (g1
) != gimple_asm_noutputs (g2
))
1003 /* We do not suppport goto ASM statement comparison. */
1004 if (gimple_asm_nlabels (g1
) || gimple_asm_nlabels (g2
))
1007 if (gimple_asm_nclobbers (g1
) != gimple_asm_nclobbers (g2
))
1010 if (strcmp (gimple_asm_string (g1
), gimple_asm_string (g2
)) != 0)
1011 return return_false_with_msg ("ASM strings are different");
1013 for (unsigned i
= 0; i
< gimple_asm_ninputs (g1
); i
++)
1015 tree input1
= gimple_asm_input_op (g1
, i
);
1016 tree input2
= gimple_asm_input_op (g2
, i
);
1018 if (!compare_asm_inputs_outputs (input1
, input2
))
1019 return return_false_with_msg ("ASM input is different");
1022 for (unsigned i
= 0; i
< gimple_asm_noutputs (g1
); i
++)
1024 tree output1
= gimple_asm_output_op (g1
, i
);
1025 tree output2
= gimple_asm_output_op (g2
, i
);
1027 if (!compare_asm_inputs_outputs (output1
, output2
))
1028 return return_false_with_msg ("ASM output is different");
1031 for (unsigned i
= 0; i
< gimple_asm_nclobbers (g1
); i
++)
1033 tree clobber1
= gimple_asm_clobber_op (g1
, i
);
1034 tree clobber2
= gimple_asm_clobber_op (g2
, i
);
1036 if (!operand_equal_p (TREE_VALUE (clobber1
), TREE_VALUE (clobber2
),
1038 return return_false_with_msg ("ASM clobber is different");
1044 } // ipa_icf_gimple namespace