1 /* Interprocedural Identical Code Folding pass
2 Copyright (C) 2014-2015 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"
42 #include "ipa-icf-gimple.h"
44 namespace ipa_icf_gimple
{
46 /* Initialize internal structures for a given SOURCE_FUNC_DECL and
47 TARGET_FUNC_DECL. Strict polymorphic comparison is processed if
48 an option COMPARE_POLYMORPHIC is true. For special cases, one can
49 set IGNORE_LABELS to skip label comparison.
50 Similarly, IGNORE_SOURCE_DECLS and IGNORE_TARGET_DECLS are sets
51 of declarations that can be skipped. */
53 func_checker::func_checker (tree source_func_decl
, tree target_func_decl
,
54 bool compare_polymorphic
,
56 hash_set
<symtab_node
*> *ignored_source_nodes
,
57 hash_set
<symtab_node
*> *ignored_target_nodes
)
58 : m_source_func_decl (source_func_decl
), m_target_func_decl (target_func_decl
),
59 m_ignored_source_nodes (ignored_source_nodes
),
60 m_ignored_target_nodes (ignored_target_nodes
),
61 m_compare_polymorphic (compare_polymorphic
),
62 m_ignore_labels (ignore_labels
)
64 function
*source_func
= DECL_STRUCT_FUNCTION (source_func_decl
);
65 function
*target_func
= DECL_STRUCT_FUNCTION (target_func_decl
);
67 unsigned ssa_source
= SSANAMES (source_func
)->length ();
68 unsigned ssa_target
= SSANAMES (target_func
)->length ();
70 m_source_ssa_names
.create (ssa_source
);
71 m_target_ssa_names
.create (ssa_target
);
73 for (unsigned i
= 0; i
< ssa_source
; i
++)
74 m_source_ssa_names
.safe_push (-1);
76 for (unsigned i
= 0; i
< ssa_target
; i
++)
77 m_target_ssa_names
.safe_push (-1);
80 /* Memory release routine. */
82 func_checker::~func_checker ()
84 m_source_ssa_names
.release();
85 m_target_ssa_names
.release();
88 /* Verifies that trees T1 and T2 are equivalent from perspective of ICF. */
91 func_checker::compare_ssa_name (tree t1
, tree t2
)
93 gcc_assert (TREE_CODE (t1
) == SSA_NAME
);
94 gcc_assert (TREE_CODE (t2
) == SSA_NAME
);
96 unsigned i1
= SSA_NAME_VERSION (t1
);
97 unsigned i2
= SSA_NAME_VERSION (t2
);
99 if (m_source_ssa_names
[i1
] == -1)
100 m_source_ssa_names
[i1
] = i2
;
101 else if (m_source_ssa_names
[i1
] != (int) i2
)
104 if(m_target_ssa_names
[i2
] == -1)
105 m_target_ssa_names
[i2
] = i1
;
106 else if (m_target_ssa_names
[i2
] != (int) i1
)
109 if (SSA_NAME_IS_DEFAULT_DEF (t1
))
111 tree b1
= SSA_NAME_VAR (t1
);
112 tree b2
= SSA_NAME_VAR (t2
);
114 if (b1
== NULL
&& b2
== NULL
)
117 if (b1
== NULL
|| b2
== NULL
|| TREE_CODE (b1
) != TREE_CODE (b2
))
118 return return_false ();
120 return compare_cst_or_decl (b1
, b2
);
126 /* Verification function for edges E1 and E2. */
129 func_checker::compare_edge (edge e1
, edge e2
)
131 if (e1
->flags
!= e2
->flags
)
136 edge
&slot
= m_edge_map
.get_or_insert (e1
, &existed_p
);
138 return return_with_debug (slot
== e2
);
142 /* TODO: filter edge probabilities for profile feedback match. */
147 /* Verification function for declaration trees T1 and T2 that
148 come from functions FUNC1 and FUNC2. */
151 func_checker::compare_decl (tree t1
, tree t2
)
153 if (!auto_var_in_fn_p (t1
, m_source_func_decl
)
154 || !auto_var_in_fn_p (t2
, m_target_func_decl
))
155 return return_with_debug (t1
== t2
);
157 tree_code t
= TREE_CODE (t1
);
158 if ((t
== VAR_DECL
|| t
== PARM_DECL
|| t
== RESULT_DECL
)
159 && DECL_BY_REFERENCE (t1
) != DECL_BY_REFERENCE (t2
))
160 return return_false_with_msg ("DECL_BY_REFERENCE flags are different");
162 if (!compatible_types_p (TREE_TYPE (t1
), TREE_TYPE (t2
)))
163 return return_false ();
165 /* TODO: we are actually too strict here. We only need to compare if
166 T1 can be used in polymorphic call. */
167 if (TREE_ADDRESSABLE (t1
)
168 && m_compare_polymorphic
169 && !compatible_polymorphic_types_p (TREE_TYPE (t1
), TREE_TYPE (t2
),
171 return return_false ();
173 if ((t
== VAR_DECL
|| t
== PARM_DECL
|| t
== RESULT_DECL
)
174 && DECL_BY_REFERENCE (t1
)
175 && m_compare_polymorphic
176 && !compatible_polymorphic_types_p (TREE_TYPE (t1
), TREE_TYPE (t2
),
178 return return_false ();
182 tree
&slot
= m_decl_map
.get_or_insert (t1
, &existed_p
);
184 return return_with_debug (slot
== t2
);
191 /* Return true if T1 and T2 are same for purposes of ipa-polymorphic-call
192 analysis. COMPARE_PTR indicates if types of pointers needs to be
196 func_checker::compatible_polymorphic_types_p (tree t1
, tree t2
,
199 gcc_assert (TREE_CODE (t1
) != FUNCTION_TYPE
&& TREE_CODE (t1
) != METHOD_TYPE
);
201 /* Pointer types generally give no information. */
202 if (POINTER_TYPE_P (t1
))
206 return func_checker::compatible_polymorphic_types_p (TREE_TYPE (t1
),
211 /* If types contain a polymorphic types, match them. */
212 bool c1
= contains_polymorphic_type_p (t1
);
213 bool c2
= contains_polymorphic_type_p (t2
);
217 return return_false_with_msg ("one type is not polymorphic");
218 if (!types_must_be_same_for_odr (t1
, t2
))
219 return return_false_with_msg ("types are not same for ODR");
223 /* Return true if types are compatible from perspective of ICF. */
225 func_checker::compatible_types_p (tree t1
, tree t2
)
227 if (TREE_CODE (t1
) != TREE_CODE (t2
))
228 return return_false_with_msg ("different tree types");
230 if (TYPE_RESTRICT (t1
) != TYPE_RESTRICT (t2
))
231 return return_false_with_msg ("restrict flags are different");
233 if (!types_compatible_p (t1
, t2
))
234 return return_false_with_msg ("types are not compatible");
236 if (get_alias_set (t1
) != get_alias_set (t2
))
237 return return_false_with_msg ("alias sets are different");
242 /* Function compare for equality given memory operands T1 and T2. */
245 func_checker::compare_memory_operand (tree t1
, tree t2
)
253 ao_ref_init (&r1
, t1
);
254 ao_ref_init (&r2
, t2
);
256 tree b1
= ao_ref_base (&r1
);
257 tree b2
= ao_ref_base (&r2
);
259 bool source_is_memop
= DECL_P (b1
) || INDIRECT_REF_P (b1
)
260 || TREE_CODE (b1
) == MEM_REF
261 || TREE_CODE (b1
) == TARGET_MEM_REF
;
263 bool target_is_memop
= DECL_P (b2
) || INDIRECT_REF_P (b2
)
264 || TREE_CODE (b2
) == MEM_REF
265 || TREE_CODE (b2
) == TARGET_MEM_REF
;
267 /* Compare alias sets for memory operands. */
268 if (source_is_memop
&& target_is_memop
)
270 if (TREE_THIS_VOLATILE (t1
) != TREE_THIS_VOLATILE (t2
))
271 return return_false_with_msg ("different operand volatility");
273 if (ao_ref_alias_set (&r1
) != ao_ref_alias_set (&r2
)
274 || ao_ref_base_alias_set (&r1
) != ao_ref_base_alias_set (&r2
))
275 return return_false_with_msg ("ao alias sets are different");
277 /* We can't simply use get_object_alignment_1 on the full
278 reference as for accesses with variable indexes this reports
279 too conservative alignment. We also can't use the ao_ref_base
280 base objects as ao_ref_base happily strips MEM_REFs around
281 decls even though that may carry alignment info. */
283 while (handled_component_p (b1
))
284 b1
= TREE_OPERAND (b1
, 0);
286 while (handled_component_p (b2
))
287 b2
= TREE_OPERAND (b2
, 0);
288 unsigned int align1
, align2
;
289 unsigned HOST_WIDE_INT tem
;
290 get_object_alignment_1 (b1
, &align1
, &tem
);
291 get_object_alignment_1 (b2
, &align2
, &tem
);
292 if (align1
!= align2
)
293 return return_false_with_msg ("different access alignment");
295 /* Similarly we have to compare dependence info where equality
296 tells us we are safe (even some unequal values would be safe
297 but then we have to maintain a map of bases and cliques). */
298 unsigned short clique1
= 0, base1
= 0, clique2
= 0, base2
= 0;
299 if (TREE_CODE (b1
) == MEM_REF
)
301 clique1
= MR_DEPENDENCE_CLIQUE (b1
);
302 base1
= MR_DEPENDENCE_BASE (b1
);
304 if (TREE_CODE (b2
) == MEM_REF
)
306 clique2
= MR_DEPENDENCE_CLIQUE (b2
);
307 base2
= MR_DEPENDENCE_BASE (b2
);
309 if (clique1
!= clique2
|| base1
!= base2
)
310 return return_false_with_msg ("different dependence info");
313 return compare_operand (t1
, t2
);
316 /* Function compare for equality given trees T1 and T2 which
317 can be either a constant or a declaration type. */
320 func_checker::compare_cst_or_decl (tree t1
, tree t2
)
324 switch (TREE_CODE (t1
))
332 ret
= compatible_types_p (TREE_TYPE (t1
), TREE_TYPE (t2
))
333 && operand_equal_p (t1
, t2
, OEP_ONLY_CONST
);
334 return return_with_debug (ret
);
337 /* All function decls are in the symbol table and known to match
338 before we start comparing bodies. */
341 return return_with_debug (compare_variable_decl (t1
, t2
));
344 tree offset1
= DECL_FIELD_OFFSET (t1
);
345 tree offset2
= DECL_FIELD_OFFSET (t2
);
347 tree bit_offset1
= DECL_FIELD_BIT_OFFSET (t1
);
348 tree bit_offset2
= DECL_FIELD_BIT_OFFSET (t2
);
350 ret
= compare_operand (offset1
, offset2
)
351 && compare_operand (bit_offset1
, bit_offset2
);
353 return return_with_debug (ret
);
357 int *bb1
= m_label_bb_map
.get (t1
);
358 int *bb2
= m_label_bb_map
.get (t2
);
360 return return_with_debug (*bb1
== *bb2
);
366 ret
= compare_decl (t1
, t2
);
367 return return_with_debug (ret
);
374 /* Function responsible for comparison of various operands T1 and T2.
375 If these components, from functions FUNC1 and FUNC2, are equal, true
379 func_checker::compare_operand (tree t1
, tree t2
)
381 tree x1
, x2
, y1
, y2
, z1
, z2
;
389 tree tt1
= TREE_TYPE (t1
);
390 tree tt2
= TREE_TYPE (t2
);
392 if (!func_checker::compatible_types_p (tt1
, tt2
))
395 if (TREE_CODE (t1
) != TREE_CODE (t2
))
396 return return_false ();
398 switch (TREE_CODE (t1
))
402 unsigned length1
= vec_safe_length (CONSTRUCTOR_ELTS (t1
));
403 unsigned length2
= vec_safe_length (CONSTRUCTOR_ELTS (t2
));
405 if (length1
!= length2
)
406 return return_false ();
408 for (unsigned i
= 0; i
< length1
; i
++)
409 if (!compare_operand (CONSTRUCTOR_ELT (t1
, i
)->value
,
410 CONSTRUCTOR_ELT (t2
, i
)->value
))
411 return return_false();
416 case ARRAY_RANGE_REF
:
417 /* First argument is the array, second is the index. */
418 x1
= TREE_OPERAND (t1
, 0);
419 x2
= TREE_OPERAND (t2
, 0);
420 y1
= TREE_OPERAND (t1
, 1);
421 y2
= TREE_OPERAND (t2
, 1);
423 if (!compare_operand (array_ref_low_bound (t1
),
424 array_ref_low_bound (t2
)))
425 return return_false_with_msg ("");
426 if (!compare_operand (array_ref_element_size (t1
),
427 array_ref_element_size (t2
)))
428 return return_false_with_msg ("");
430 if (!compare_operand (x1
, x2
))
431 return return_false_with_msg ("");
432 return compare_operand (y1
, y2
);
435 x1
= TREE_OPERAND (t1
, 0);
436 x2
= TREE_OPERAND (t2
, 0);
437 y1
= TREE_OPERAND (t1
, 1);
438 y2
= TREE_OPERAND (t2
, 1);
440 /* See if operand is an memory access (the test originate from
443 In this case the alias set of the function being replaced must
444 be subset of the alias set of the other function. At the moment
445 we seek for equivalency classes, so simply require inclussion in
448 if (!func_checker::compatible_types_p (TREE_TYPE (x1
), TREE_TYPE (x2
)))
449 return return_false ();
451 if (!compare_operand (x1
, x2
))
452 return return_false_with_msg ("");
454 /* Type of the offset on MEM_REF does not matter. */
455 return wi::to_offset (y1
) == wi::to_offset (y2
);
459 x1
= TREE_OPERAND (t1
, 0);
460 x2
= TREE_OPERAND (t2
, 0);
461 y1
= TREE_OPERAND (t1
, 1);
462 y2
= TREE_OPERAND (t2
, 1);
464 ret
= compare_operand (x1
, x2
)
465 && compare_cst_or_decl (y1
, y2
);
467 return return_with_debug (ret
);
469 /* Virtual table call. */
472 if (!compare_ssa_name (OBJ_TYPE_REF_EXPR (t1
), OBJ_TYPE_REF_EXPR (t2
)))
473 return return_false ();
474 if (opt_for_fn (m_source_func_decl
, flag_devirtualize
)
475 && virtual_method_call_p (t1
))
477 if (tree_to_uhwi (OBJ_TYPE_REF_TOKEN (t1
))
478 != tree_to_uhwi (OBJ_TYPE_REF_TOKEN (t2
)))
479 return return_false_with_msg ("OBJ_TYPE_REF token mismatch");
480 if (!types_same_for_odr (obj_type_ref_class (t1
),
481 obj_type_ref_class (t2
)))
482 return return_false_with_msg ("OBJ_TYPE_REF OTR type mismatch");
483 if (!compare_operand (OBJ_TYPE_REF_OBJECT (t1
),
484 OBJ_TYPE_REF_OBJECT (t2
)))
485 return return_false_with_msg ("OBJ_TYPE_REF object mismatch");
488 return return_with_debug (true);
494 x1
= TREE_OPERAND (t1
, 0);
495 x2
= TREE_OPERAND (t2
, 0);
497 ret
= compare_operand (x1
, x2
);
498 return return_with_debug (ret
);
502 x1
= TREE_OPERAND (t1
, 0);
503 x2
= TREE_OPERAND (t2
, 0);
504 y1
= TREE_OPERAND (t1
, 1);
505 y2
= TREE_OPERAND (t2
, 1);
506 z1
= TREE_OPERAND (t1
, 2);
507 z2
= TREE_OPERAND (t2
, 2);
509 ret
= compare_operand (x1
, x2
)
510 && compare_cst_or_decl (y1
, y2
)
511 && compare_cst_or_decl (z1
, z2
);
513 return return_with_debug (ret
);
516 return compare_ssa_name (t1
, t2
);
529 return compare_cst_or_decl (t1
, t2
);
531 return return_false_with_msg ("Unknown TREE code reached");
535 /* Compares two tree list operands T1 and T2 and returns true if these
536 two trees are semantically equivalent. */
539 func_checker::compare_tree_list_operand (tree t1
, tree t2
)
541 gcc_assert (TREE_CODE (t1
) == TREE_LIST
);
542 gcc_assert (TREE_CODE (t2
) == TREE_LIST
);
544 for (; t1
; t1
= TREE_CHAIN (t1
))
549 if (!compare_operand (TREE_VALUE (t1
), TREE_VALUE (t2
)))
550 return return_false ();
552 t2
= TREE_CHAIN (t2
);
556 return return_false ();
561 /* Verifies that trees T1 and T2 do correspond. */
564 func_checker::compare_variable_decl (tree t1
, tree t2
)
571 if (DECL_ALIGN (t1
) != DECL_ALIGN (t2
))
572 return return_false_with_msg ("alignments are different");
574 if (DECL_HARD_REGISTER (t1
) != DECL_HARD_REGISTER (t2
))
575 return return_false_with_msg ("DECL_HARD_REGISTER are different");
577 if (DECL_HARD_REGISTER (t1
)
578 && DECL_ASSEMBLER_NAME (t1
) != DECL_ASSEMBLER_NAME (t2
))
579 return return_false_with_msg ("HARD REGISTERS are different");
581 /* Symbol table variables are known to match before we start comparing
583 if (decl_in_symtab_p (t1
))
584 return decl_in_symtab_p (t2
);
585 ret
= compare_decl (t1
, t2
);
587 return return_with_debug (ret
);
591 /* Function visits all gimple labels and creates corresponding
592 mapping between basic blocks and labels. */
595 func_checker::parse_labels (sem_bb
*bb
)
597 for (gimple_stmt_iterator gsi
= gsi_start_bb (bb
->bb
); !gsi_end_p (gsi
);
600 gimple
*stmt
= gsi_stmt (gsi
);
602 if (glabel
*label_stmt
= dyn_cast
<glabel
*> (stmt
))
604 tree t
= gimple_label_label (label_stmt
);
605 gcc_assert (TREE_CODE (t
) == LABEL_DECL
);
607 m_label_bb_map
.put (t
, bb
->bb
->index
);
612 /* Basic block equivalence comparison function that returns true if
613 basic blocks BB1 and BB2 (from functions FUNC1 and FUNC2) correspond.
615 In general, a collection of equivalence dictionaries is built for types
616 like SSA names, declarations (VAR_DECL, PARM_DECL, ..). This infrastructure
617 is utilized by every statement-by-statement comparison function. */
620 func_checker::compare_bb (sem_bb
*bb1
, sem_bb
*bb2
)
622 gimple_stmt_iterator gsi1
, gsi2
;
625 gsi1
= gsi_start_bb_nondebug (bb1
->bb
);
626 gsi2
= gsi_start_bb_nondebug (bb2
->bb
);
628 while (!gsi_end_p (gsi1
))
630 if (gsi_end_p (gsi2
))
631 return return_false ();
633 s1
= gsi_stmt (gsi1
);
634 s2
= gsi_stmt (gsi2
);
636 int eh1
= lookup_stmt_eh_lp_fn
637 (DECL_STRUCT_FUNCTION (m_source_func_decl
), s1
);
638 int eh2
= lookup_stmt_eh_lp_fn
639 (DECL_STRUCT_FUNCTION (m_target_func_decl
), s2
);
642 return return_false_with_msg ("EH regions are different");
644 if (gimple_code (s1
) != gimple_code (s2
))
645 return return_false_with_msg ("gimple codes are different");
647 switch (gimple_code (s1
))
650 if (!compare_gimple_call (as_a
<gcall
*> (s1
),
651 as_a
<gcall
*> (s2
)))
652 return return_different_stmts (s1
, s2
, "GIMPLE_CALL");
655 if (!compare_gimple_assign (s1
, s2
))
656 return return_different_stmts (s1
, s2
, "GIMPLE_ASSIGN");
659 if (!compare_gimple_cond (s1
, s2
))
660 return return_different_stmts (s1
, s2
, "GIMPLE_COND");
663 if (!compare_gimple_switch (as_a
<gswitch
*> (s1
),
664 as_a
<gswitch
*> (s2
)))
665 return return_different_stmts (s1
, s2
, "GIMPLE_SWITCH");
669 case GIMPLE_EH_DISPATCH
:
670 if (gimple_eh_dispatch_region (as_a
<geh_dispatch
*> (s1
))
671 != gimple_eh_dispatch_region (as_a
<geh_dispatch
*> (s2
)))
672 return return_different_stmts (s1
, s2
, "GIMPLE_EH_DISPATCH");
675 if (!compare_gimple_resx (as_a
<gresx
*> (s1
),
676 as_a
<gresx
*> (s2
)))
677 return return_different_stmts (s1
, s2
, "GIMPLE_RESX");
680 if (!compare_gimple_label (as_a
<glabel
*> (s1
),
681 as_a
<glabel
*> (s2
)))
682 return return_different_stmts (s1
, s2
, "GIMPLE_LABEL");
685 if (!compare_gimple_return (as_a
<greturn
*> (s1
),
686 as_a
<greturn
*> (s2
)))
687 return return_different_stmts (s1
, s2
, "GIMPLE_RETURN");
690 if (!compare_gimple_goto (s1
, s2
))
691 return return_different_stmts (s1
, s2
, "GIMPLE_GOTO");
694 if (!compare_gimple_asm (as_a
<gasm
*> (s1
),
696 return return_different_stmts (s1
, s2
, "GIMPLE_ASM");
702 return return_false_with_msg ("Unknown GIMPLE code reached");
705 gsi_next_nondebug (&gsi1
);
706 gsi_next_nondebug (&gsi2
);
709 if (!gsi_end_p (gsi2
))
710 return return_false ();
715 /* Verifies for given GIMPLEs S1 and S2 that
716 call statements are semantically equivalent. */
719 func_checker::compare_gimple_call (gcall
*s1
, gcall
*s2
)
724 if (gimple_call_num_args (s1
) != gimple_call_num_args (s2
))
727 t1
= gimple_call_fn (s1
);
728 t2
= gimple_call_fn (s2
);
729 if (!compare_operand (t1
, t2
))
730 return return_false ();
733 if (gimple_call_internal_p (s1
) != gimple_call_internal_p (s2
)
734 || gimple_call_ctrl_altering_p (s1
) != gimple_call_ctrl_altering_p (s2
)
735 || gimple_call_tail_p (s1
) != gimple_call_tail_p (s2
)
736 || gimple_call_return_slot_opt_p (s1
) != gimple_call_return_slot_opt_p (s2
)
737 || gimple_call_from_thunk_p (s1
) != gimple_call_from_thunk_p (s2
)
738 || gimple_call_va_arg_pack_p (s1
) != gimple_call_va_arg_pack_p (s2
)
739 || gimple_call_alloca_for_var_p (s1
) != gimple_call_alloca_for_var_p (s2
)
740 || gimple_call_with_bounds_p (s1
) != gimple_call_with_bounds_p (s2
))
743 if (gimple_call_internal_p (s1
)
744 && gimple_call_internal_fn (s1
) != gimple_call_internal_fn (s2
))
747 tree fntype1
= gimple_call_fntype (s1
);
748 tree fntype2
= gimple_call_fntype (s2
);
749 if ((fntype1
&& !fntype2
)
750 || (!fntype1
&& fntype2
)
751 || (fntype1
&& !types_compatible_p (fntype1
, fntype2
)))
752 return return_false_with_msg ("call function types are not compatible");
754 tree chain1
= gimple_call_chain (s1
);
755 tree chain2
= gimple_call_chain (s2
);
756 if ((chain1
&& !chain2
)
757 || (!chain1
&& chain2
)
758 || !compare_operand (chain1
, chain2
))
759 return return_false_with_msg ("static call chains are different");
761 /* Checking of argument. */
762 for (i
= 0; i
< gimple_call_num_args (s1
); ++i
)
764 t1
= gimple_call_arg (s1
, i
);
765 t2
= gimple_call_arg (s2
, i
);
767 if (!compare_memory_operand (t1
, t2
))
768 return return_false_with_msg ("memory operands are different");
771 /* Return value checking. */
772 t1
= gimple_get_lhs (s1
);
773 t2
= gimple_get_lhs (s2
);
775 return compare_memory_operand (t1
, t2
);
779 /* Verifies for given GIMPLEs S1 and S2 that
780 assignment statements are semantically equivalent. */
783 func_checker::compare_gimple_assign (gimple
*s1
, gimple
*s2
)
786 tree_code code1
, code2
;
789 code1
= gimple_expr_code (s1
);
790 code2
= gimple_expr_code (s2
);
795 code1
= gimple_assign_rhs_code (s1
);
796 code2
= gimple_assign_rhs_code (s2
);
801 for (i
= 0; i
< gimple_num_ops (s1
); i
++)
803 arg1
= gimple_op (s1
, i
);
804 arg2
= gimple_op (s2
, i
);
806 if (!compare_memory_operand (arg1
, arg2
))
807 return return_false_with_msg ("memory operands are different");
814 /* Verifies for given GIMPLEs S1 and S2 that
815 condition statements are semantically equivalent. */
818 func_checker::compare_gimple_cond (gimple
*s1
, gimple
*s2
)
821 tree_code code1
, code2
;
823 code1
= gimple_expr_code (s1
);
824 code2
= gimple_expr_code (s2
);
829 t1
= gimple_cond_lhs (s1
);
830 t2
= gimple_cond_lhs (s2
);
832 if (!compare_operand (t1
, t2
))
835 t1
= gimple_cond_rhs (s1
);
836 t2
= gimple_cond_rhs (s2
);
838 return compare_operand (t1
, t2
);
841 /* Verifies that tree labels T1 and T2 correspond in FUNC1 and FUNC2. */
844 func_checker::compare_tree_ssa_label (tree t1
, tree t2
)
846 return compare_operand (t1
, t2
);
849 /* Verifies for given GIMPLE_LABEL stmts S1 and S2 that
850 label statements are semantically equivalent. */
853 func_checker::compare_gimple_label (const glabel
*g1
, const glabel
*g2
)
858 tree t1
= gimple_label_label (g1
);
859 tree t2
= gimple_label_label (g2
);
861 if (FORCED_LABEL (t1
) || FORCED_LABEL (t2
))
862 return return_false_with_msg ("FORCED_LABEL");
864 /* As the pass build BB to label mapping, no further check is needed. */
868 /* Verifies for given GIMPLE_SWITCH stmts S1 and S2 that
869 switch statements are semantically equivalent. */
872 func_checker::compare_gimple_switch (const gswitch
*g1
, const gswitch
*g2
)
874 unsigned lsize1
, lsize2
, i
;
876 lsize1
= gimple_switch_num_labels (g1
);
877 lsize2
= gimple_switch_num_labels (g2
);
879 if (lsize1
!= lsize2
)
882 tree t1
= gimple_switch_index (g1
);
883 tree t2
= gimple_switch_index (g2
);
885 if (!compare_operand (t1
, t2
))
888 for (i
= 0; i
< lsize1
; i
++)
890 tree label1
= gimple_switch_label (g1
, i
);
891 tree label2
= gimple_switch_label (g2
, i
);
893 /* Label LOW and HIGH comparison. */
894 tree low1
= CASE_LOW (label1
);
895 tree low2
= CASE_LOW (label2
);
897 if (!tree_int_cst_equal (low1
, low2
))
898 return return_false_with_msg ("case low values are different");
900 tree high1
= CASE_HIGH (label1
);
901 tree high2
= CASE_HIGH (label2
);
903 if (!tree_int_cst_equal (high1
, high2
))
904 return return_false_with_msg ("case high values are different");
906 if (TREE_CODE (label1
) == CASE_LABEL_EXPR
907 && TREE_CODE (label2
) == CASE_LABEL_EXPR
)
909 label1
= CASE_LABEL (label1
);
910 label2
= CASE_LABEL (label2
);
912 if (!compare_operand (label1
, label2
))
913 return return_false_with_msg ("switch label_exprs are different");
915 else if (!tree_int_cst_equal (label1
, label2
))
916 return return_false_with_msg ("switch labels are different");
922 /* Verifies for given GIMPLE_RETURN stmts S1 and S2 that
923 return statements are semantically equivalent. */
926 func_checker::compare_gimple_return (const greturn
*g1
, const greturn
*g2
)
930 t1
= gimple_return_retval (g1
);
931 t2
= gimple_return_retval (g2
);
933 /* Void return type. */
934 if (t1
== NULL
&& t2
== NULL
)
937 return compare_operand (t1
, t2
);
940 /* Verifies for given GIMPLEs S1 and S2 that
941 goto statements are semantically equivalent. */
944 func_checker::compare_gimple_goto (gimple
*g1
, gimple
*g2
)
948 dest1
= gimple_goto_dest (g1
);
949 dest2
= gimple_goto_dest (g2
);
951 if (TREE_CODE (dest1
) != TREE_CODE (dest2
) || TREE_CODE (dest1
) != SSA_NAME
)
954 return compare_operand (dest1
, dest2
);
957 /* Verifies for given GIMPLE_RESX stmts S1 and S2 that
958 resx statements are semantically equivalent. */
961 func_checker::compare_gimple_resx (const gresx
*g1
, const gresx
*g2
)
963 return gimple_resx_region (g1
) == gimple_resx_region (g2
);
966 /* Verifies for given GIMPLEs S1 and S2 that ASM statements are equivalent.
967 For the beginning, the pass only supports equality for
968 '__asm__ __volatile__ ("", "", "", "memory")'. */
971 func_checker::compare_gimple_asm (const gasm
*g1
, const gasm
*g2
)
973 if (gimple_asm_volatile_p (g1
) != gimple_asm_volatile_p (g2
))
976 if (gimple_asm_ninputs (g1
) != gimple_asm_ninputs (g2
))
979 if (gimple_asm_noutputs (g1
) != gimple_asm_noutputs (g2
))
982 /* We do not suppport goto ASM statement comparison. */
983 if (gimple_asm_nlabels (g1
) || gimple_asm_nlabels (g2
))
986 if (gimple_asm_nclobbers (g1
) != gimple_asm_nclobbers (g2
))
989 if (strcmp (gimple_asm_string (g1
), gimple_asm_string (g2
)) != 0)
990 return return_false_with_msg ("ASM strings are different");
992 for (unsigned i
= 0; i
< gimple_asm_ninputs (g1
); i
++)
994 tree input1
= gimple_asm_input_op (g1
, i
);
995 tree input2
= gimple_asm_input_op (g2
, i
);
997 if (!compare_tree_list_operand (input1
, input2
))
998 return return_false_with_msg ("ASM input is different");
1001 for (unsigned i
= 0; i
< gimple_asm_noutputs (g1
); i
++)
1003 tree output1
= gimple_asm_output_op (g1
, i
);
1004 tree output2
= gimple_asm_output_op (g2
, i
);
1006 if (!compare_tree_list_operand (output1
, output2
))
1007 return return_false_with_msg ("ASM output is different");
1010 for (unsigned i
= 0; i
< gimple_asm_nclobbers (g1
); i
++)
1012 tree clobber1
= gimple_asm_clobber_op (g1
, i
);
1013 tree clobber2
= gimple_asm_clobber_op (g2
, i
);
1015 if (!operand_equal_p (TREE_VALUE (clobber1
), TREE_VALUE (clobber2
),
1017 return return_false_with_msg ("ASM clobber is different");
1023 } // ipa_icf_gimple namespace