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"
28 #include "double-int.h"
36 #include "fold-const.h"
39 #include "hard-reg-set.h"
41 #include "basic-block.h"
42 #include "tree-ssa-alias.h"
43 #include "internal-fn.h"
44 #include "gimple-expr.h"
50 #include "statistics.h"
52 #include "fixed-value.h"
53 #include "insn-config.h"
62 #include "gimple-iterator.h"
63 #include "gimple-ssa.h"
65 #include "stringpool.h"
67 #include "tree-pass.h"
68 #include "gimple-pretty-print.h"
72 #include "plugin-api.h"
75 #include "data-streamer.h"
76 #include "ipa-utils.h"
78 #include "tree-ssanames.h"
82 #include "ipa-icf-gimple.h"
85 namespace ipa_icf_gimple
{
87 /* Initialize internal structures for a given SOURCE_FUNC_DECL and
88 TARGET_FUNC_DECL. Strict polymorphic comparison is processed if
89 an option COMPARE_POLYMORPHIC is true. For special cases, one can
90 set IGNORE_LABELS to skip label comparison.
91 Similarly, IGNORE_SOURCE_DECLS and IGNORE_TARGET_DECLS are sets
92 of declarations that can be skipped. */
94 func_checker::func_checker (tree source_func_decl
, tree target_func_decl
,
95 bool compare_polymorphic
,
97 hash_set
<symtab_node
*> *ignored_source_nodes
,
98 hash_set
<symtab_node
*> *ignored_target_nodes
)
99 : m_source_func_decl (source_func_decl
), m_target_func_decl (target_func_decl
),
100 m_ignored_source_nodes (ignored_source_nodes
),
101 m_ignored_target_nodes (ignored_target_nodes
),
102 m_compare_polymorphic (compare_polymorphic
),
103 m_ignore_labels (ignore_labels
)
105 function
*source_func
= DECL_STRUCT_FUNCTION (source_func_decl
);
106 function
*target_func
= DECL_STRUCT_FUNCTION (target_func_decl
);
108 unsigned ssa_source
= SSANAMES (source_func
)->length ();
109 unsigned ssa_target
= SSANAMES (target_func
)->length ();
111 m_source_ssa_names
.create (ssa_source
);
112 m_target_ssa_names
.create (ssa_target
);
114 for (unsigned i
= 0; i
< ssa_source
; i
++)
115 m_source_ssa_names
.safe_push (-1);
117 for (unsigned i
= 0; i
< ssa_target
; i
++)
118 m_target_ssa_names
.safe_push (-1);
121 /* Memory release routine. */
123 func_checker::~func_checker ()
125 m_source_ssa_names
.release();
126 m_target_ssa_names
.release();
129 /* Verifies that trees T1 and T2 are equivalent from perspective of ICF. */
132 func_checker::compare_ssa_name (tree t1
, tree t2
)
134 gcc_assert (TREE_CODE (t1
) == SSA_NAME
);
135 gcc_assert (TREE_CODE (t2
) == SSA_NAME
);
137 unsigned i1
= SSA_NAME_VERSION (t1
);
138 unsigned i2
= SSA_NAME_VERSION (t2
);
140 if (m_source_ssa_names
[i1
] == -1)
141 m_source_ssa_names
[i1
] = i2
;
142 else if (m_source_ssa_names
[i1
] != (int) i2
)
145 if(m_target_ssa_names
[i2
] == -1)
146 m_target_ssa_names
[i2
] = i1
;
147 else if (m_target_ssa_names
[i2
] != (int) i1
)
150 if (SSA_NAME_IS_DEFAULT_DEF (t1
))
152 tree b1
= SSA_NAME_VAR (t1
);
153 tree b2
= SSA_NAME_VAR (t2
);
155 if (b1
== NULL
&& b2
== NULL
)
158 if (b1
== NULL
|| b2
== NULL
|| TREE_CODE (b1
) != TREE_CODE (b2
))
159 return return_false ();
161 return compare_cst_or_decl (b1
, b2
);
167 /* Verification function for edges E1 and E2. */
170 func_checker::compare_edge (edge e1
, edge e2
)
172 if (e1
->flags
!= e2
->flags
)
177 edge
&slot
= m_edge_map
.get_or_insert (e1
, &existed_p
);
179 return return_with_debug (slot
== e2
);
183 /* TODO: filter edge probabilities for profile feedback match. */
188 /* Verification function for declaration trees T1 and T2 that
189 come from functions FUNC1 and FUNC2. */
192 func_checker::compare_decl (tree t1
, tree t2
)
194 if (!auto_var_in_fn_p (t1
, m_source_func_decl
)
195 || !auto_var_in_fn_p (t2
, m_target_func_decl
))
196 return return_with_debug (t1
== t2
);
198 tree_code t
= TREE_CODE (t1
);
199 if ((t
== VAR_DECL
|| t
== PARM_DECL
|| t
== RESULT_DECL
)
200 && DECL_BY_REFERENCE (t1
) != DECL_BY_REFERENCE (t2
))
201 return return_false_with_msg ("DECL_BY_REFERENCE flags are different");
203 if (!compatible_types_p (TREE_TYPE (t1
), TREE_TYPE (t2
)))
204 return return_false ();
206 /* TODO: we are actually too strict here. We only need to compare if
207 T1 can be used in polymorphic call. */
208 if (TREE_ADDRESSABLE (t1
)
209 && m_compare_polymorphic
210 && !compatible_polymorphic_types_p (TREE_TYPE (t1
), TREE_TYPE (t2
),
212 return return_false ();
214 if ((t
== VAR_DECL
|| t
== PARM_DECL
|| t
== RESULT_DECL
)
215 && DECL_BY_REFERENCE (t1
)
216 && m_compare_polymorphic
217 && !compatible_polymorphic_types_p (TREE_TYPE (t1
), TREE_TYPE (t2
),
219 return return_false ();
223 tree
&slot
= m_decl_map
.get_or_insert (t1
, &existed_p
);
225 return return_with_debug (slot
== t2
);
232 /* Return true if T1 and T2 are same for purposes of ipa-polymorphic-call
233 analysis. COMPARE_PTR indicates if types of pointers needs to be
237 func_checker::compatible_polymorphic_types_p (tree t1
, tree t2
,
240 gcc_assert (TREE_CODE (t1
) != FUNCTION_TYPE
&& TREE_CODE (t1
) != METHOD_TYPE
);
242 /* Pointer types generally give no information. */
243 if (POINTER_TYPE_P (t1
))
247 return func_checker::compatible_polymorphic_types_p (TREE_TYPE (t1
),
252 /* If types contain a polymorphic types, match them. */
253 bool c1
= contains_polymorphic_type_p (t1
);
254 bool c2
= contains_polymorphic_type_p (t2
);
258 return return_false_with_msg ("one type is not polymorphic");
259 if (!types_must_be_same_for_odr (t1
, t2
))
260 return return_false_with_msg ("types are not same for ODR");
264 /* Return true if types are compatible from perspective of ICF. */
266 func_checker::compatible_types_p (tree t1
, tree t2
)
268 if (TREE_CODE (t1
) != TREE_CODE (t2
))
269 return return_false_with_msg ("different tree types");
271 if (TYPE_RESTRICT (t1
) != TYPE_RESTRICT (t2
))
272 return return_false_with_msg ("restrict flags are different");
274 if (!types_compatible_p (t1
, t2
))
275 return return_false_with_msg ("types are not compatible");
277 if (get_alias_set (t1
) != get_alias_set (t2
))
278 return return_false_with_msg ("alias sets are different");
283 /* Function compare for equality given memory operands T1 and T2. */
286 func_checker::compare_memory_operand (tree t1
, tree t2
)
294 ao_ref_init (&r1
, t1
);
295 ao_ref_init (&r2
, t2
);
297 tree b1
= ao_ref_base (&r1
);
298 tree b2
= ao_ref_base (&r2
);
300 bool source_is_memop
= DECL_P (b1
) || INDIRECT_REF_P (b1
)
301 || TREE_CODE (b1
) == MEM_REF
302 || TREE_CODE (b1
) == TARGET_MEM_REF
;
304 bool target_is_memop
= DECL_P (b2
) || INDIRECT_REF_P (b2
)
305 || TREE_CODE (b2
) == MEM_REF
306 || TREE_CODE (b2
) == TARGET_MEM_REF
;
308 /* Compare alias sets for memory operands. */
309 if (source_is_memop
&& target_is_memop
)
311 if (TREE_THIS_VOLATILE (t1
) != TREE_THIS_VOLATILE (t2
))
312 return return_false_with_msg ("different operand volatility");
314 if (ao_ref_alias_set (&r1
) != ao_ref_alias_set (&r2
)
315 || ao_ref_base_alias_set (&r1
) != ao_ref_base_alias_set (&r2
))
316 return return_false_with_msg ("ao alias sets are different");
318 /* We can't simply use get_object_alignment_1 on the full
319 reference as for accesses with variable indexes this reports
320 too conservative alignment. We also can't use the ao_ref_base
321 base objects as ao_ref_base happily strips MEM_REFs around
322 decls even though that may carry alignment info. */
324 while (handled_component_p (b1
))
325 b1
= TREE_OPERAND (b1
, 0);
327 while (handled_component_p (b2
))
328 b2
= TREE_OPERAND (b2
, 0);
329 unsigned int align1
, align2
;
330 unsigned HOST_WIDE_INT tem
;
331 get_object_alignment_1 (b1
, &align1
, &tem
);
332 get_object_alignment_1 (b2
, &align2
, &tem
);
333 if (align1
!= align2
)
334 return return_false_with_msg ("different access alignment");
336 /* Similarly we have to compare dependence info where equality
337 tells us we are safe (even some unequal values would be safe
338 but then we have to maintain a map of bases and cliques). */
339 unsigned short clique1
= 0, base1
= 0, clique2
= 0, base2
= 0;
340 if (TREE_CODE (b1
) == MEM_REF
)
342 clique1
= MR_DEPENDENCE_CLIQUE (b1
);
343 base1
= MR_DEPENDENCE_BASE (b1
);
345 if (TREE_CODE (b2
) == MEM_REF
)
347 clique2
= MR_DEPENDENCE_CLIQUE (b2
);
348 base2
= MR_DEPENDENCE_BASE (b2
);
350 if (clique1
!= clique2
|| base1
!= base2
)
351 return return_false_with_msg ("different dependence info");
354 return compare_operand (t1
, t2
);
357 /* Function compare for equality given trees T1 and T2 which
358 can be either a constant or a declaration type. */
361 func_checker::compare_cst_or_decl (tree t1
, tree t2
)
365 switch (TREE_CODE (t1
))
373 ret
= compatible_types_p (TREE_TYPE (t1
), TREE_TYPE (t2
))
374 && operand_equal_p (t1
, t2
, OEP_ONLY_CONST
);
375 return return_with_debug (ret
);
378 /* All function decls are in the symbol table and known to match
379 before we start comparing bodies. */
382 return return_with_debug (compare_variable_decl (t1
, t2
));
385 tree offset1
= DECL_FIELD_OFFSET (t1
);
386 tree offset2
= DECL_FIELD_OFFSET (t2
);
388 tree bit_offset1
= DECL_FIELD_BIT_OFFSET (t1
);
389 tree bit_offset2
= DECL_FIELD_BIT_OFFSET (t2
);
391 ret
= compare_operand (offset1
, offset2
)
392 && compare_operand (bit_offset1
, bit_offset2
);
394 return return_with_debug (ret
);
398 int *bb1
= m_label_bb_map
.get (t1
);
399 int *bb2
= m_label_bb_map
.get (t2
);
401 return return_with_debug (*bb1
== *bb2
);
407 ret
= compare_decl (t1
, t2
);
408 return return_with_debug (ret
);
415 /* Function responsible for comparison of various operands T1 and T2.
416 If these components, from functions FUNC1 and FUNC2, are equal, true
420 func_checker::compare_operand (tree t1
, tree t2
)
422 tree x1
, x2
, y1
, y2
, z1
, z2
;
430 tree tt1
= TREE_TYPE (t1
);
431 tree tt2
= TREE_TYPE (t2
);
433 if (!func_checker::compatible_types_p (tt1
, tt2
))
436 if (TREE_CODE (t1
) != TREE_CODE (t2
))
437 return return_false ();
439 switch (TREE_CODE (t1
))
443 unsigned length1
= vec_safe_length (CONSTRUCTOR_ELTS (t1
));
444 unsigned length2
= vec_safe_length (CONSTRUCTOR_ELTS (t2
));
446 if (length1
!= length2
)
447 return return_false ();
449 for (unsigned i
= 0; i
< length1
; i
++)
450 if (!compare_operand (CONSTRUCTOR_ELT (t1
, i
)->value
,
451 CONSTRUCTOR_ELT (t2
, i
)->value
))
452 return return_false();
457 case ARRAY_RANGE_REF
:
458 /* First argument is the array, second is the index. */
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 if (!compare_operand (array_ref_low_bound (t1
),
465 array_ref_low_bound (t2
)))
466 return return_false_with_msg ("");
467 if (!compare_operand (array_ref_element_size (t1
),
468 array_ref_element_size (t2
)))
469 return return_false_with_msg ("");
471 if (!compare_operand (x1
, x2
))
472 return return_false_with_msg ("");
473 return compare_operand (y1
, y2
);
476 x1
= TREE_OPERAND (t1
, 0);
477 x2
= TREE_OPERAND (t2
, 0);
478 y1
= TREE_OPERAND (t1
, 1);
479 y2
= TREE_OPERAND (t2
, 1);
481 /* See if operand is an memory access (the test originate from
484 In this case the alias set of the function being replaced must
485 be subset of the alias set of the other function. At the moment
486 we seek for equivalency classes, so simply require inclussion in
489 if (!func_checker::compatible_types_p (TREE_TYPE (x1
), TREE_TYPE (x2
)))
490 return return_false ();
492 if (!compare_operand (x1
, x2
))
493 return return_false_with_msg ("");
495 /* Type of the offset on MEM_REF does not matter. */
496 return wi::to_offset (y1
) == wi::to_offset (y2
);
500 x1
= TREE_OPERAND (t1
, 0);
501 x2
= TREE_OPERAND (t2
, 0);
502 y1
= TREE_OPERAND (t1
, 1);
503 y2
= TREE_OPERAND (t2
, 1);
505 ret
= compare_operand (x1
, x2
)
506 && compare_cst_or_decl (y1
, y2
);
508 return return_with_debug (ret
);
510 /* Virtual table call. */
513 if (!compare_ssa_name (OBJ_TYPE_REF_EXPR (t1
), OBJ_TYPE_REF_EXPR (t2
)))
514 return return_false ();
515 if (opt_for_fn (m_source_func_decl
, flag_devirtualize
)
516 && virtual_method_call_p (t1
))
518 if (tree_to_uhwi (OBJ_TYPE_REF_TOKEN (t1
))
519 != tree_to_uhwi (OBJ_TYPE_REF_TOKEN (t2
)))
520 return return_false_with_msg ("OBJ_TYPE_REF token mismatch");
521 if (!types_same_for_odr (obj_type_ref_class (t1
),
522 obj_type_ref_class (t2
)))
523 return return_false_with_msg ("OBJ_TYPE_REF OTR type mismatch");
524 if (!compare_operand (OBJ_TYPE_REF_OBJECT (t1
),
525 OBJ_TYPE_REF_OBJECT (t2
)))
526 return return_false_with_msg ("OBJ_TYPE_REF object mismatch");
529 return return_with_debug (true);
535 x1
= TREE_OPERAND (t1
, 0);
536 x2
= TREE_OPERAND (t2
, 0);
538 ret
= compare_operand (x1
, x2
);
539 return return_with_debug (ret
);
543 x1
= TREE_OPERAND (t1
, 0);
544 x2
= TREE_OPERAND (t2
, 0);
545 y1
= TREE_OPERAND (t1
, 1);
546 y2
= TREE_OPERAND (t2
, 1);
547 z1
= TREE_OPERAND (t1
, 2);
548 z2
= TREE_OPERAND (t2
, 2);
550 ret
= compare_operand (x1
, x2
)
551 && compare_cst_or_decl (y1
, y2
)
552 && compare_cst_or_decl (z1
, z2
);
554 return return_with_debug (ret
);
557 return compare_ssa_name (t1
, t2
);
570 return compare_cst_or_decl (t1
, t2
);
572 return return_false_with_msg ("Unknown TREE code reached");
576 /* Compares two tree list operands T1 and T2 and returns true if these
577 two trees are semantically equivalent. */
580 func_checker::compare_tree_list_operand (tree t1
, tree t2
)
582 gcc_assert (TREE_CODE (t1
) == TREE_LIST
);
583 gcc_assert (TREE_CODE (t2
) == TREE_LIST
);
585 for (; t1
; t1
= TREE_CHAIN (t1
))
590 if (!compare_operand (TREE_VALUE (t1
), TREE_VALUE (t2
)))
591 return return_false ();
593 t2
= TREE_CHAIN (t2
);
597 return return_false ();
602 /* Verifies that trees T1 and T2 do correspond. */
605 func_checker::compare_variable_decl (tree t1
, tree t2
)
612 if (DECL_ALIGN (t1
) != DECL_ALIGN (t2
))
613 return return_false_with_msg ("alignments are different");
615 if (DECL_HARD_REGISTER (t1
) != DECL_HARD_REGISTER (t2
))
616 return return_false_with_msg ("DECL_HARD_REGISTER are different");
618 if (DECL_HARD_REGISTER (t1
)
619 && DECL_ASSEMBLER_NAME (t1
) != DECL_ASSEMBLER_NAME (t2
))
620 return return_false_with_msg ("HARD REGISTERS are different");
622 /* Symbol table variables are known to match before we start comparing
624 if (decl_in_symtab_p (t1
))
625 return decl_in_symtab_p (t2
);
626 ret
= compare_decl (t1
, t2
);
628 return return_with_debug (ret
);
632 /* Function visits all gimple labels and creates corresponding
633 mapping between basic blocks and labels. */
636 func_checker::parse_labels (sem_bb
*bb
)
638 for (gimple_stmt_iterator gsi
= gsi_start_bb (bb
->bb
); !gsi_end_p (gsi
);
641 gimple stmt
= gsi_stmt (gsi
);
643 if (glabel
*label_stmt
= dyn_cast
<glabel
*> (stmt
))
645 tree t
= gimple_label_label (label_stmt
);
646 gcc_assert (TREE_CODE (t
) == LABEL_DECL
);
648 m_label_bb_map
.put (t
, bb
->bb
->index
);
653 /* Basic block equivalence comparison function that returns true if
654 basic blocks BB1 and BB2 (from functions FUNC1 and FUNC2) correspond.
656 In general, a collection of equivalence dictionaries is built for types
657 like SSA names, declarations (VAR_DECL, PARM_DECL, ..). This infrastructure
658 is utilized by every statement-by-statement comparison function. */
661 func_checker::compare_bb (sem_bb
*bb1
, sem_bb
*bb2
)
663 gimple_stmt_iterator gsi1
, gsi2
;
666 gsi1
= gsi_start_bb_nondebug (bb1
->bb
);
667 gsi2
= gsi_start_bb_nondebug (bb2
->bb
);
669 while (!gsi_end_p (gsi1
))
671 if (gsi_end_p (gsi2
))
672 return return_false ();
674 s1
= gsi_stmt (gsi1
);
675 s2
= gsi_stmt (gsi2
);
677 int eh1
= lookup_stmt_eh_lp_fn
678 (DECL_STRUCT_FUNCTION (m_source_func_decl
), s1
);
679 int eh2
= lookup_stmt_eh_lp_fn
680 (DECL_STRUCT_FUNCTION (m_target_func_decl
), s2
);
683 return return_false_with_msg ("EH regions are different");
685 if (gimple_code (s1
) != gimple_code (s2
))
686 return return_false_with_msg ("gimple codes are different");
688 switch (gimple_code (s1
))
691 if (!compare_gimple_call (as_a
<gcall
*> (s1
),
692 as_a
<gcall
*> (s2
)))
693 return return_different_stmts (s1
, s2
, "GIMPLE_CALL");
696 if (!compare_gimple_assign (s1
, s2
))
697 return return_different_stmts (s1
, s2
, "GIMPLE_ASSIGN");
700 if (!compare_gimple_cond (s1
, s2
))
701 return return_different_stmts (s1
, s2
, "GIMPLE_COND");
704 if (!compare_gimple_switch (as_a
<gswitch
*> (s1
),
705 as_a
<gswitch
*> (s2
)))
706 return return_different_stmts (s1
, s2
, "GIMPLE_SWITCH");
710 case GIMPLE_EH_DISPATCH
:
711 if (gimple_eh_dispatch_region (as_a
<geh_dispatch
*> (s1
))
712 != gimple_eh_dispatch_region (as_a
<geh_dispatch
*> (s2
)))
713 return return_different_stmts (s1
, s2
, "GIMPLE_EH_DISPATCH");
716 if (!compare_gimple_resx (as_a
<gresx
*> (s1
),
717 as_a
<gresx
*> (s2
)))
718 return return_different_stmts (s1
, s2
, "GIMPLE_RESX");
721 if (!compare_gimple_label (as_a
<glabel
*> (s1
),
722 as_a
<glabel
*> (s2
)))
723 return return_different_stmts (s1
, s2
, "GIMPLE_LABEL");
726 if (!compare_gimple_return (as_a
<greturn
*> (s1
),
727 as_a
<greturn
*> (s2
)))
728 return return_different_stmts (s1
, s2
, "GIMPLE_RETURN");
731 if (!compare_gimple_goto (s1
, s2
))
732 return return_different_stmts (s1
, s2
, "GIMPLE_GOTO");
735 if (!compare_gimple_asm (as_a
<gasm
*> (s1
),
737 return return_different_stmts (s1
, s2
, "GIMPLE_ASM");
743 return return_false_with_msg ("Unknown GIMPLE code reached");
746 gsi_next_nondebug (&gsi1
);
747 gsi_next_nondebug (&gsi2
);
750 if (!gsi_end_p (gsi2
))
751 return return_false ();
756 /* Verifies for given GIMPLEs S1 and S2 that
757 call statements are semantically equivalent. */
760 func_checker::compare_gimple_call (gcall
*s1
, gcall
*s2
)
765 if (gimple_call_num_args (s1
) != gimple_call_num_args (s2
))
768 t1
= gimple_call_fn (s1
);
769 t2
= gimple_call_fn (s2
);
770 if (!compare_operand (t1
, t2
))
771 return return_false ();
774 if (gimple_call_internal_p (s1
) != gimple_call_internal_p (s2
)
775 || gimple_call_ctrl_altering_p (s1
) != gimple_call_ctrl_altering_p (s2
)
776 || gimple_call_tail_p (s1
) != gimple_call_tail_p (s2
)
777 || gimple_call_return_slot_opt_p (s1
) != gimple_call_return_slot_opt_p (s2
)
778 || gimple_call_from_thunk_p (s1
) != gimple_call_from_thunk_p (s2
)
779 || gimple_call_va_arg_pack_p (s1
) != gimple_call_va_arg_pack_p (s2
)
780 || gimple_call_alloca_for_var_p (s1
) != gimple_call_alloca_for_var_p (s2
)
781 || gimple_call_with_bounds_p (s1
) != gimple_call_with_bounds_p (s2
))
784 if (gimple_call_internal_p (s1
)
785 && gimple_call_internal_fn (s1
) != gimple_call_internal_fn (s2
))
788 tree fntype1
= gimple_call_fntype (s1
);
789 tree fntype2
= gimple_call_fntype (s2
);
790 if ((fntype1
&& !fntype2
)
791 || (!fntype1
&& fntype2
)
792 || (fntype1
&& !types_compatible_p (fntype1
, fntype2
)))
793 return return_false_with_msg ("call function types are not compatible");
795 tree chain1
= gimple_call_chain (s1
);
796 tree chain2
= gimple_call_chain (s2
);
797 if ((chain1
&& !chain2
)
798 || (!chain1
&& chain2
)
799 || !compare_operand (chain1
, chain2
))
800 return return_false_with_msg ("static call chains are different");
802 /* Checking of argument. */
803 for (i
= 0; i
< gimple_call_num_args (s1
); ++i
)
805 t1
= gimple_call_arg (s1
, i
);
806 t2
= gimple_call_arg (s2
, i
);
808 if (!compare_memory_operand (t1
, t2
))
809 return return_false_with_msg ("memory operands are different");
812 /* Return value checking. */
813 t1
= gimple_get_lhs (s1
);
814 t2
= gimple_get_lhs (s2
);
816 return compare_memory_operand (t1
, t2
);
820 /* Verifies for given GIMPLEs S1 and S2 that
821 assignment statements are semantically equivalent. */
824 func_checker::compare_gimple_assign (gimple s1
, gimple s2
)
827 tree_code code1
, code2
;
830 code1
= gimple_expr_code (s1
);
831 code2
= gimple_expr_code (s2
);
836 code1
= gimple_assign_rhs_code (s1
);
837 code2
= gimple_assign_rhs_code (s2
);
842 for (i
= 0; i
< gimple_num_ops (s1
); i
++)
844 arg1
= gimple_op (s1
, i
);
845 arg2
= gimple_op (s2
, i
);
847 if (!compare_memory_operand (arg1
, arg2
))
848 return return_false_with_msg ("memory operands are different");
855 /* Verifies for given GIMPLEs S1 and S2 that
856 condition statements are semantically equivalent. */
859 func_checker::compare_gimple_cond (gimple s1
, gimple s2
)
862 tree_code code1
, code2
;
864 code1
= gimple_expr_code (s1
);
865 code2
= gimple_expr_code (s2
);
870 t1
= gimple_cond_lhs (s1
);
871 t2
= gimple_cond_lhs (s2
);
873 if (!compare_operand (t1
, t2
))
876 t1
= gimple_cond_rhs (s1
);
877 t2
= gimple_cond_rhs (s2
);
879 return compare_operand (t1
, t2
);
882 /* Verifies that tree labels T1 and T2 correspond in FUNC1 and FUNC2. */
885 func_checker::compare_tree_ssa_label (tree t1
, tree t2
)
887 return compare_operand (t1
, t2
);
890 /* Verifies for given GIMPLE_LABEL stmts S1 and S2 that
891 label statements are semantically equivalent. */
894 func_checker::compare_gimple_label (const glabel
*g1
, const glabel
*g2
)
899 tree t1
= gimple_label_label (g1
);
900 tree t2
= gimple_label_label (g2
);
902 if (FORCED_LABEL (t1
) || FORCED_LABEL (t2
))
903 return return_false_with_msg ("FORCED_LABEL");
905 /* As the pass build BB to label mapping, no further check is needed. */
909 /* Verifies for given GIMPLE_SWITCH stmts S1 and S2 that
910 switch statements are semantically equivalent. */
913 func_checker::compare_gimple_switch (const gswitch
*g1
, const gswitch
*g2
)
915 unsigned lsize1
, lsize2
, i
;
917 lsize1
= gimple_switch_num_labels (g1
);
918 lsize2
= gimple_switch_num_labels (g2
);
920 if (lsize1
!= lsize2
)
923 tree t1
= gimple_switch_index (g1
);
924 tree t2
= gimple_switch_index (g2
);
926 if (!compare_operand (t1
, t2
))
929 for (i
= 0; i
< lsize1
; i
++)
931 tree label1
= gimple_switch_label (g1
, i
);
932 tree label2
= gimple_switch_label (g2
, i
);
934 /* Label LOW and HIGH comparison. */
935 tree low1
= CASE_LOW (label1
);
936 tree low2
= CASE_LOW (label2
);
938 if (!tree_int_cst_equal (low1
, low2
))
939 return return_false_with_msg ("case low values are different");
941 tree high1
= CASE_HIGH (label1
);
942 tree high2
= CASE_HIGH (label2
);
944 if (!tree_int_cst_equal (high1
, high2
))
945 return return_false_with_msg ("case high values are different");
947 if (TREE_CODE (label1
) == CASE_LABEL_EXPR
948 && TREE_CODE (label2
) == CASE_LABEL_EXPR
)
950 label1
= CASE_LABEL (label1
);
951 label2
= CASE_LABEL (label2
);
953 if (!compare_operand (label1
, label2
))
954 return return_false_with_msg ("switch label_exprs are different");
956 else if (!tree_int_cst_equal (label1
, label2
))
957 return return_false_with_msg ("switch labels are different");
963 /* Verifies for given GIMPLE_RETURN stmts S1 and S2 that
964 return statements are semantically equivalent. */
967 func_checker::compare_gimple_return (const greturn
*g1
, const greturn
*g2
)
971 t1
= gimple_return_retval (g1
);
972 t2
= gimple_return_retval (g2
);
974 /* Void return type. */
975 if (t1
== NULL
&& t2
== NULL
)
978 return compare_operand (t1
, t2
);
981 /* Verifies for given GIMPLEs S1 and S2 that
982 goto statements are semantically equivalent. */
985 func_checker::compare_gimple_goto (gimple g1
, gimple g2
)
989 dest1
= gimple_goto_dest (g1
);
990 dest2
= gimple_goto_dest (g2
);
992 if (TREE_CODE (dest1
) != TREE_CODE (dest2
) || TREE_CODE (dest1
) != SSA_NAME
)
995 return compare_operand (dest1
, dest2
);
998 /* Verifies for given GIMPLE_RESX stmts S1 and S2 that
999 resx statements are semantically equivalent. */
1002 func_checker::compare_gimple_resx (const gresx
*g1
, const gresx
*g2
)
1004 return gimple_resx_region (g1
) == gimple_resx_region (g2
);
1007 /* Verifies for given GIMPLEs S1 and S2 that ASM statements are equivalent.
1008 For the beginning, the pass only supports equality for
1009 '__asm__ __volatile__ ("", "", "", "memory")'. */
1012 func_checker::compare_gimple_asm (const gasm
*g1
, const gasm
*g2
)
1014 if (gimple_asm_volatile_p (g1
) != gimple_asm_volatile_p (g2
))
1017 if (gimple_asm_ninputs (g1
) != gimple_asm_ninputs (g2
))
1020 if (gimple_asm_noutputs (g1
) != gimple_asm_noutputs (g2
))
1023 /* We do not suppport goto ASM statement comparison. */
1024 if (gimple_asm_nlabels (g1
) || gimple_asm_nlabels (g2
))
1027 if (gimple_asm_nclobbers (g1
) != gimple_asm_nclobbers (g2
))
1030 if (strcmp (gimple_asm_string (g1
), gimple_asm_string (g2
)) != 0)
1031 return return_false_with_msg ("ASM strings are different");
1033 for (unsigned i
= 0; i
< gimple_asm_ninputs (g1
); i
++)
1035 tree input1
= gimple_asm_input_op (g1
, i
);
1036 tree input2
= gimple_asm_input_op (g2
, i
);
1038 if (!compare_tree_list_operand (input1
, input2
))
1039 return return_false_with_msg ("ASM input is different");
1042 for (unsigned i
= 0; i
< gimple_asm_noutputs (g1
); i
++)
1044 tree output1
= gimple_asm_output_op (g1
, i
);
1045 tree output2
= gimple_asm_output_op (g2
, i
);
1047 if (!compare_tree_list_operand (output1
, output2
))
1048 return return_false_with_msg ("ASM output is different");
1051 for (unsigned i
= 0; i
< gimple_asm_nclobbers (g1
); i
++)
1053 tree clobber1
= gimple_asm_clobber_op (g1
, i
);
1054 tree clobber2
= gimple_asm_clobber_op (g2
, i
);
1056 if (!operand_equal_p (TREE_VALUE (clobber1
), TREE_VALUE (clobber2
),
1058 return return_false_with_msg ("ASM clobber is different");
1064 } // ipa_icf_gimple namespace