1 /* Interprocedural Identical Code Folding pass
2 Copyright (C) 2014-2016 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
);
364 int *bb1
= m_label_bb_map
.get (t1
);
365 int *bb2
= m_label_bb_map
.get (t2
);
367 return return_with_debug (*bb1
== *bb2
);
373 ret
= compare_decl (t1
, t2
);
374 return return_with_debug (ret
);
381 /* Function responsible for comparison of various operands T1 and T2.
382 If these components, from functions FUNC1 and FUNC2, are equal, true
386 func_checker::compare_operand (tree t1
, tree t2
)
388 tree x1
, x2
, y1
, y2
, z1
, z2
;
396 tree tt1
= TREE_TYPE (t1
);
397 tree tt2
= TREE_TYPE (t2
);
399 if (!func_checker::compatible_types_p (tt1
, tt2
))
402 if (TREE_CODE (t1
) != TREE_CODE (t2
))
403 return return_false ();
405 switch (TREE_CODE (t1
))
409 unsigned length1
= vec_safe_length (CONSTRUCTOR_ELTS (t1
));
410 unsigned length2
= vec_safe_length (CONSTRUCTOR_ELTS (t2
));
412 if (length1
!= length2
)
413 return return_false ();
415 for (unsigned i
= 0; i
< length1
; i
++)
416 if (!compare_operand (CONSTRUCTOR_ELT (t1
, i
)->value
,
417 CONSTRUCTOR_ELT (t2
, i
)->value
))
418 return return_false();
423 case ARRAY_RANGE_REF
:
424 /* First argument is the array, second is the index. */
425 x1
= TREE_OPERAND (t1
, 0);
426 x2
= TREE_OPERAND (t2
, 0);
427 y1
= TREE_OPERAND (t1
, 1);
428 y2
= TREE_OPERAND (t2
, 1);
430 if (!compare_operand (array_ref_low_bound (t1
),
431 array_ref_low_bound (t2
)))
432 return return_false_with_msg ("");
433 if (!compare_operand (array_ref_element_size (t1
),
434 array_ref_element_size (t2
)))
435 return return_false_with_msg ("");
437 if (!compare_operand (x1
, x2
))
438 return return_false_with_msg ("");
439 return compare_operand (y1
, y2
);
442 x1
= TREE_OPERAND (t1
, 0);
443 x2
= TREE_OPERAND (t2
, 0);
444 y1
= TREE_OPERAND (t1
, 1);
445 y2
= TREE_OPERAND (t2
, 1);
447 /* See if operand is an memory access (the test originate from
450 In this case the alias set of the function being replaced must
451 be subset of the alias set of the other function. At the moment
452 we seek for equivalency classes, so simply require inclussion in
455 if (!func_checker::compatible_types_p (TREE_TYPE (x1
), TREE_TYPE (x2
)))
456 return return_false ();
458 if (!compare_operand (x1
, x2
))
459 return return_false_with_msg ("");
461 /* Type of the offset on MEM_REF does not matter. */
462 return wi::to_offset (y1
) == wi::to_offset (y2
);
466 x1
= TREE_OPERAND (t1
, 0);
467 x2
= TREE_OPERAND (t2
, 0);
468 y1
= TREE_OPERAND (t1
, 1);
469 y2
= TREE_OPERAND (t2
, 1);
471 ret
= compare_operand (x1
, x2
)
472 && compare_cst_or_decl (y1
, y2
);
474 return return_with_debug (ret
);
476 /* Virtual table call. */
479 if (!compare_ssa_name (OBJ_TYPE_REF_EXPR (t1
), OBJ_TYPE_REF_EXPR (t2
)))
480 return return_false ();
481 if (opt_for_fn (m_source_func_decl
, flag_devirtualize
)
482 && virtual_method_call_p (t1
))
484 if (tree_to_uhwi (OBJ_TYPE_REF_TOKEN (t1
))
485 != tree_to_uhwi (OBJ_TYPE_REF_TOKEN (t2
)))
486 return return_false_with_msg ("OBJ_TYPE_REF token mismatch");
487 if (!types_same_for_odr (obj_type_ref_class (t1
),
488 obj_type_ref_class (t2
)))
489 return return_false_with_msg ("OBJ_TYPE_REF OTR type mismatch");
490 if (!compare_operand (OBJ_TYPE_REF_OBJECT (t1
),
491 OBJ_TYPE_REF_OBJECT (t2
)))
492 return return_false_with_msg ("OBJ_TYPE_REF object mismatch");
495 return return_with_debug (true);
501 x1
= TREE_OPERAND (t1
, 0);
502 x2
= TREE_OPERAND (t2
, 0);
504 ret
= compare_operand (x1
, x2
);
505 return return_with_debug (ret
);
509 x1
= TREE_OPERAND (t1
, 0);
510 x2
= TREE_OPERAND (t2
, 0);
511 y1
= TREE_OPERAND (t1
, 1);
512 y2
= TREE_OPERAND (t2
, 1);
513 z1
= TREE_OPERAND (t1
, 2);
514 z2
= TREE_OPERAND (t2
, 2);
516 ret
= compare_operand (x1
, x2
)
517 && compare_cst_or_decl (y1
, y2
)
518 && compare_cst_or_decl (z1
, z2
);
520 return return_with_debug (ret
);
523 return compare_ssa_name (t1
, t2
);
536 return compare_cst_or_decl (t1
, t2
);
538 return return_false_with_msg ("Unknown TREE code reached");
542 /* Compares two tree list operands T1 and T2 and returns true if these
543 two trees are semantically equivalent. */
546 func_checker::compare_tree_list_operand (tree t1
, tree t2
)
548 gcc_assert (TREE_CODE (t1
) == TREE_LIST
);
549 gcc_assert (TREE_CODE (t2
) == TREE_LIST
);
551 for (; t1
; t1
= TREE_CHAIN (t1
))
556 if (!compare_operand (TREE_VALUE (t1
), TREE_VALUE (t2
)))
557 return return_false ();
559 t2
= TREE_CHAIN (t2
);
563 return return_false ();
568 /* Verifies that trees T1 and T2 do correspond. */
571 func_checker::compare_variable_decl (tree t1
, tree t2
)
578 if (DECL_ALIGN (t1
) != DECL_ALIGN (t2
))
579 return return_false_with_msg ("alignments are different");
581 if (DECL_HARD_REGISTER (t1
) != DECL_HARD_REGISTER (t2
))
582 return return_false_with_msg ("DECL_HARD_REGISTER are different");
584 if (DECL_HARD_REGISTER (t1
)
585 && DECL_ASSEMBLER_NAME (t1
) != DECL_ASSEMBLER_NAME (t2
))
586 return return_false_with_msg ("HARD REGISTERS are different");
588 /* Symbol table variables are known to match before we start comparing
590 if (decl_in_symtab_p (t1
))
591 return decl_in_symtab_p (t2
);
592 ret
= compare_decl (t1
, t2
);
594 return return_with_debug (ret
);
598 /* Function visits all gimple labels and creates corresponding
599 mapping between basic blocks and labels. */
602 func_checker::parse_labels (sem_bb
*bb
)
604 for (gimple_stmt_iterator gsi
= gsi_start_bb (bb
->bb
); !gsi_end_p (gsi
);
607 gimple
*stmt
= gsi_stmt (gsi
);
609 if (glabel
*label_stmt
= dyn_cast
<glabel
*> (stmt
))
611 tree t
= gimple_label_label (label_stmt
);
612 gcc_assert (TREE_CODE (t
) == LABEL_DECL
);
614 m_label_bb_map
.put (t
, bb
->bb
->index
);
619 /* Basic block equivalence comparison function that returns true if
620 basic blocks BB1 and BB2 (from functions FUNC1 and FUNC2) correspond.
622 In general, a collection of equivalence dictionaries is built for types
623 like SSA names, declarations (VAR_DECL, PARM_DECL, ..). This infrastructure
624 is utilized by every statement-by-statement comparison function. */
627 func_checker::compare_bb (sem_bb
*bb1
, sem_bb
*bb2
)
629 gimple_stmt_iterator gsi1
, gsi2
;
632 gsi1
= gsi_start_bb_nondebug (bb1
->bb
);
633 gsi2
= gsi_start_bb_nondebug (bb2
->bb
);
635 while (!gsi_end_p (gsi1
))
637 if (gsi_end_p (gsi2
))
638 return return_false ();
640 s1
= gsi_stmt (gsi1
);
641 s2
= gsi_stmt (gsi2
);
643 int eh1
= lookup_stmt_eh_lp_fn
644 (DECL_STRUCT_FUNCTION (m_source_func_decl
), s1
);
645 int eh2
= lookup_stmt_eh_lp_fn
646 (DECL_STRUCT_FUNCTION (m_target_func_decl
), s2
);
649 return return_false_with_msg ("EH regions are different");
651 if (gimple_code (s1
) != gimple_code (s2
))
652 return return_false_with_msg ("gimple codes are different");
654 switch (gimple_code (s1
))
657 if (!compare_gimple_call (as_a
<gcall
*> (s1
),
658 as_a
<gcall
*> (s2
)))
659 return return_different_stmts (s1
, s2
, "GIMPLE_CALL");
662 if (!compare_gimple_assign (s1
, s2
))
663 return return_different_stmts (s1
, s2
, "GIMPLE_ASSIGN");
666 if (!compare_gimple_cond (s1
, s2
))
667 return return_different_stmts (s1
, s2
, "GIMPLE_COND");
670 if (!compare_gimple_switch (as_a
<gswitch
*> (s1
),
671 as_a
<gswitch
*> (s2
)))
672 return return_different_stmts (s1
, s2
, "GIMPLE_SWITCH");
676 case GIMPLE_EH_DISPATCH
:
677 if (gimple_eh_dispatch_region (as_a
<geh_dispatch
*> (s1
))
678 != gimple_eh_dispatch_region (as_a
<geh_dispatch
*> (s2
)))
679 return return_different_stmts (s1
, s2
, "GIMPLE_EH_DISPATCH");
682 if (!compare_gimple_resx (as_a
<gresx
*> (s1
),
683 as_a
<gresx
*> (s2
)))
684 return return_different_stmts (s1
, s2
, "GIMPLE_RESX");
687 if (!compare_gimple_label (as_a
<glabel
*> (s1
),
688 as_a
<glabel
*> (s2
)))
689 return return_different_stmts (s1
, s2
, "GIMPLE_LABEL");
692 if (!compare_gimple_return (as_a
<greturn
*> (s1
),
693 as_a
<greturn
*> (s2
)))
694 return return_different_stmts (s1
, s2
, "GIMPLE_RETURN");
697 if (!compare_gimple_goto (s1
, s2
))
698 return return_different_stmts (s1
, s2
, "GIMPLE_GOTO");
701 if (!compare_gimple_asm (as_a
<gasm
*> (s1
),
703 return return_different_stmts (s1
, s2
, "GIMPLE_ASM");
709 return return_false_with_msg ("Unknown GIMPLE code reached");
712 gsi_next_nondebug (&gsi1
);
713 gsi_next_nondebug (&gsi2
);
716 if (!gsi_end_p (gsi2
))
717 return return_false ();
722 /* Verifies for given GIMPLEs S1 and S2 that
723 call statements are semantically equivalent. */
726 func_checker::compare_gimple_call (gcall
*s1
, gcall
*s2
)
731 if (gimple_call_num_args (s1
) != gimple_call_num_args (s2
))
734 t1
= gimple_call_fn (s1
);
735 t2
= gimple_call_fn (s2
);
736 if (!compare_operand (t1
, t2
))
737 return return_false ();
740 if (gimple_call_internal_p (s1
) != gimple_call_internal_p (s2
)
741 || gimple_call_ctrl_altering_p (s1
) != gimple_call_ctrl_altering_p (s2
)
742 || gimple_call_tail_p (s1
) != gimple_call_tail_p (s2
)
743 || gimple_call_return_slot_opt_p (s1
) != gimple_call_return_slot_opt_p (s2
)
744 || gimple_call_from_thunk_p (s1
) != gimple_call_from_thunk_p (s2
)
745 || gimple_call_va_arg_pack_p (s1
) != gimple_call_va_arg_pack_p (s2
)
746 || gimple_call_alloca_for_var_p (s1
) != gimple_call_alloca_for_var_p (s2
)
747 || gimple_call_with_bounds_p (s1
) != gimple_call_with_bounds_p (s2
))
750 if (gimple_call_internal_p (s1
)
751 && gimple_call_internal_fn (s1
) != gimple_call_internal_fn (s2
))
754 tree fntype1
= gimple_call_fntype (s1
);
755 tree fntype2
= gimple_call_fntype (s2
);
756 if ((fntype1
&& !fntype2
)
757 || (!fntype1
&& fntype2
)
758 || (fntype1
&& !types_compatible_p (fntype1
, fntype2
)))
759 return return_false_with_msg ("call function types are not compatible");
761 tree chain1
= gimple_call_chain (s1
);
762 tree chain2
= gimple_call_chain (s2
);
763 if ((chain1
&& !chain2
)
764 || (!chain1
&& chain2
)
765 || !compare_operand (chain1
, chain2
))
766 return return_false_with_msg ("static call chains are different");
768 /* Checking of argument. */
769 for (i
= 0; i
< gimple_call_num_args (s1
); ++i
)
771 t1
= gimple_call_arg (s1
, i
);
772 t2
= gimple_call_arg (s2
, i
);
774 if (!compare_memory_operand (t1
, t2
))
775 return return_false_with_msg ("memory operands are different");
778 /* Return value checking. */
779 t1
= gimple_get_lhs (s1
);
780 t2
= gimple_get_lhs (s2
);
782 return compare_memory_operand (t1
, t2
);
786 /* Verifies for given GIMPLEs S1 and S2 that
787 assignment statements are semantically equivalent. */
790 func_checker::compare_gimple_assign (gimple
*s1
, gimple
*s2
)
793 tree_code code1
, code2
;
796 code1
= gimple_expr_code (s1
);
797 code2
= gimple_expr_code (s2
);
802 code1
= gimple_assign_rhs_code (s1
);
803 code2
= gimple_assign_rhs_code (s2
);
808 for (i
= 0; i
< gimple_num_ops (s1
); i
++)
810 arg1
= gimple_op (s1
, i
);
811 arg2
= gimple_op (s2
, i
);
813 if (!compare_memory_operand (arg1
, arg2
))
814 return return_false_with_msg ("memory operands are different");
821 /* Verifies for given GIMPLEs S1 and S2 that
822 condition statements are semantically equivalent. */
825 func_checker::compare_gimple_cond (gimple
*s1
, gimple
*s2
)
828 tree_code code1
, code2
;
830 code1
= gimple_expr_code (s1
);
831 code2
= gimple_expr_code (s2
);
836 t1
= gimple_cond_lhs (s1
);
837 t2
= gimple_cond_lhs (s2
);
839 if (!compare_operand (t1
, t2
))
842 t1
= gimple_cond_rhs (s1
);
843 t2
= gimple_cond_rhs (s2
);
845 return compare_operand (t1
, t2
);
848 /* Verifies that tree labels T1 and T2 correspond in FUNC1 and FUNC2. */
851 func_checker::compare_tree_ssa_label (tree t1
, tree t2
)
853 return compare_operand (t1
, t2
);
856 /* Verifies for given GIMPLE_LABEL stmts S1 and S2 that
857 label statements are semantically equivalent. */
860 func_checker::compare_gimple_label (const glabel
*g1
, const glabel
*g2
)
865 tree t1
= gimple_label_label (g1
);
866 tree t2
= gimple_label_label (g2
);
868 if (FORCED_LABEL (t1
) || FORCED_LABEL (t2
))
869 return return_false_with_msg ("FORCED_LABEL");
871 /* As the pass build BB to label mapping, no further check is needed. */
875 /* Verifies for given GIMPLE_SWITCH stmts S1 and S2 that
876 switch statements are semantically equivalent. */
879 func_checker::compare_gimple_switch (const gswitch
*g1
, const gswitch
*g2
)
881 unsigned lsize1
, lsize2
, i
;
883 lsize1
= gimple_switch_num_labels (g1
);
884 lsize2
= gimple_switch_num_labels (g2
);
886 if (lsize1
!= lsize2
)
889 tree t1
= gimple_switch_index (g1
);
890 tree t2
= gimple_switch_index (g2
);
892 if (!compare_operand (t1
, t2
))
895 for (i
= 0; i
< lsize1
; i
++)
897 tree label1
= gimple_switch_label (g1
, i
);
898 tree label2
= gimple_switch_label (g2
, i
);
900 /* Label LOW and HIGH comparison. */
901 tree low1
= CASE_LOW (label1
);
902 tree low2
= CASE_LOW (label2
);
904 if (!tree_int_cst_equal (low1
, low2
))
905 return return_false_with_msg ("case low values are different");
907 tree high1
= CASE_HIGH (label1
);
908 tree high2
= CASE_HIGH (label2
);
910 if (!tree_int_cst_equal (high1
, high2
))
911 return return_false_with_msg ("case high values are different");
913 if (TREE_CODE (label1
) == CASE_LABEL_EXPR
914 && TREE_CODE (label2
) == CASE_LABEL_EXPR
)
916 label1
= CASE_LABEL (label1
);
917 label2
= CASE_LABEL (label2
);
919 if (!compare_operand (label1
, label2
))
920 return return_false_with_msg ("switch label_exprs are different");
922 else if (!tree_int_cst_equal (label1
, label2
))
923 return return_false_with_msg ("switch labels are different");
929 /* Verifies for given GIMPLE_RETURN stmts S1 and S2 that
930 return statements are semantically equivalent. */
933 func_checker::compare_gimple_return (const greturn
*g1
, const greturn
*g2
)
937 t1
= gimple_return_retval (g1
);
938 t2
= gimple_return_retval (g2
);
940 /* Void return type. */
941 if (t1
== NULL
&& t2
== NULL
)
944 return compare_operand (t1
, t2
);
947 /* Verifies for given GIMPLEs S1 and S2 that
948 goto statements are semantically equivalent. */
951 func_checker::compare_gimple_goto (gimple
*g1
, gimple
*g2
)
955 dest1
= gimple_goto_dest (g1
);
956 dest2
= gimple_goto_dest (g2
);
958 if (TREE_CODE (dest1
) != TREE_CODE (dest2
) || TREE_CODE (dest1
) != SSA_NAME
)
961 return compare_operand (dest1
, dest2
);
964 /* Verifies for given GIMPLE_RESX stmts S1 and S2 that
965 resx statements are semantically equivalent. */
968 func_checker::compare_gimple_resx (const gresx
*g1
, const gresx
*g2
)
970 return gimple_resx_region (g1
) == gimple_resx_region (g2
);
973 /* Verifies for given GIMPLEs S1 and S2 that ASM statements are equivalent.
974 For the beginning, the pass only supports equality for
975 '__asm__ __volatile__ ("", "", "", "memory")'. */
978 func_checker::compare_gimple_asm (const gasm
*g1
, const gasm
*g2
)
980 if (gimple_asm_volatile_p (g1
) != gimple_asm_volatile_p (g2
))
983 if (gimple_asm_input_p (g1
) != gimple_asm_input_p (g2
))
986 if (gimple_asm_ninputs (g1
) != gimple_asm_ninputs (g2
))
989 if (gimple_asm_noutputs (g1
) != gimple_asm_noutputs (g2
))
992 /* We do not suppport goto ASM statement comparison. */
993 if (gimple_asm_nlabels (g1
) || gimple_asm_nlabels (g2
))
996 if (gimple_asm_nclobbers (g1
) != gimple_asm_nclobbers (g2
))
999 if (strcmp (gimple_asm_string (g1
), gimple_asm_string (g2
)) != 0)
1000 return return_false_with_msg ("ASM strings are different");
1002 for (unsigned i
= 0; i
< gimple_asm_ninputs (g1
); i
++)
1004 tree input1
= gimple_asm_input_op (g1
, i
);
1005 tree input2
= gimple_asm_input_op (g2
, i
);
1007 if (!compare_tree_list_operand (input1
, input2
))
1008 return return_false_with_msg ("ASM input is different");
1011 for (unsigned i
= 0; i
< gimple_asm_noutputs (g1
); i
++)
1013 tree output1
= gimple_asm_output_op (g1
, i
);
1014 tree output2
= gimple_asm_output_op (g2
, i
);
1016 if (!compare_tree_list_operand (output1
, output2
))
1017 return return_false_with_msg ("ASM output is different");
1020 for (unsigned i
= 0; i
< gimple_asm_nclobbers (g1
); i
++)
1022 tree clobber1
= gimple_asm_clobber_op (g1
, i
);
1023 tree clobber2
= gimple_asm_clobber_op (g2
, i
);
1025 if (!operand_equal_p (TREE_VALUE (clobber1
), TREE_VALUE (clobber2
),
1027 return return_false_with_msg ("ASM clobber is different");
1033 } // ipa_icf_gimple namespace