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"
81 #include "ipa-icf-gimple.h"
84 namespace ipa_icf_gimple {
86 /* Initialize internal structures for a given SOURCE_FUNC_DECL and
87 TARGET_FUNC_DECL. Strict polymorphic comparison is processed if
88 an option COMPARE_POLYMORPHIC is true. For special cases, one can
89 set IGNORE_LABELS to skip label comparison.
90 Similarly, IGNORE_SOURCE_DECLS and IGNORE_TARGET_DECLS are sets
91 of declarations that can be skipped. */
93 func_checker::func_checker (tree source_func_decl, tree target_func_decl,
94 bool compare_polymorphic,
96 hash_set<symtab_node *> *ignored_source_nodes,
97 hash_set<symtab_node *> *ignored_target_nodes)
98 : m_source_func_decl (source_func_decl), m_target_func_decl (target_func_decl),
99 m_ignored_source_nodes (ignored_source_nodes),
100 m_ignored_target_nodes (ignored_target_nodes),
101 m_compare_polymorphic (compare_polymorphic),
102 m_ignore_labels (ignore_labels)
104 function *source_func = DECL_STRUCT_FUNCTION (source_func_decl);
105 function *target_func = DECL_STRUCT_FUNCTION (target_func_decl);
107 unsigned ssa_source = SSANAMES (source_func)->length ();
108 unsigned ssa_target = SSANAMES (target_func)->length ();
110 m_source_ssa_names.create (ssa_source);
111 m_target_ssa_names.create (ssa_target);
113 for (unsigned i = 0; i < ssa_source; i++)
114 m_source_ssa_names.safe_push (-1);
116 for (unsigned i = 0; i < ssa_target; i++)
117 m_target_ssa_names.safe_push (-1);
120 /* Memory release routine. */
122 func_checker::~func_checker ()
124 m_source_ssa_names.release();
125 m_target_ssa_names.release();
128 /* Verifies that trees T1 and T2 are equivalent from perspective of ICF. */
131 func_checker::compare_ssa_name (tree t1, tree t2)
133 gcc_assert (TREE_CODE (t1) == SSA_NAME);
134 gcc_assert (TREE_CODE (t2) == SSA_NAME);
136 unsigned i1 = SSA_NAME_VERSION (t1);
137 unsigned i2 = SSA_NAME_VERSION (t2);
139 if (m_source_ssa_names[i1] == -1)
140 m_source_ssa_names[i1] = i2;
141 else if (m_source_ssa_names[i1] != (int) i2)
144 if(m_target_ssa_names[i2] == -1)
145 m_target_ssa_names[i2] = i1;
146 else if (m_target_ssa_names[i2] != (int) i1)
149 if (SSA_NAME_IS_DEFAULT_DEF (t1))
151 tree b1 = SSA_NAME_VAR (t1);
152 tree b2 = SSA_NAME_VAR (t2);
154 if (b1 == NULL && b2 == NULL)
157 if (b1 == NULL || b2 == NULL || TREE_CODE (b1) != TREE_CODE (b2))
158 return return_false ();
160 return compare_cst_or_decl (b1, b2);
166 /* Verification function for edges E1 and E2. */
169 func_checker::compare_edge (edge e1, edge e2)
171 if (e1->flags != e2->flags)
176 edge &slot = m_edge_map.get_or_insert (e1, &existed_p);
178 return return_with_debug (slot == e2);
182 /* TODO: filter edge probabilities for profile feedback match. */
187 /* Verification function for declaration trees T1 and T2 that
188 come from functions FUNC1 and FUNC2. */
191 func_checker::compare_decl (tree t1, tree t2)
193 if (!auto_var_in_fn_p (t1, m_source_func_decl)
194 || !auto_var_in_fn_p (t2, m_target_func_decl))
195 return return_with_debug (t1 == t2);
197 tree_code t = TREE_CODE (t1);
198 if ((t == VAR_DECL || t == PARM_DECL || t == RESULT_DECL)
199 && DECL_BY_REFERENCE (t1) != DECL_BY_REFERENCE (t2))
200 return return_false_with_msg ("DECL_BY_REFERENCE flags are different");
202 if (!compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2),
203 m_compare_polymorphic))
204 return return_false ();
208 tree &slot = m_decl_map.get_or_insert (t1, &existed_p);
210 return return_with_debug (slot == t2);
217 /* Return true if types are compatible from perspective of ICF. */
219 func_checker::compatible_types_p (tree t1, tree t2,
220 bool compare_polymorphic,
223 if (TREE_CODE (t1) != TREE_CODE (t2))
224 return return_false_with_msg ("different tree types");
226 if (TYPE_RESTRICT (t1) != TYPE_RESTRICT (t2))
227 return return_false_with_msg ("restrict flags are different");
229 if (!types_compatible_p (t1, t2))
230 return return_false_with_msg ("types are not compatible");
232 if (get_alias_set (t1) != get_alias_set (t2))
233 return return_false_with_msg ("alias sets are different");
235 /* We call contains_polymorphic_type_p with this pointer type. */
236 if (first_argument && TREE_CODE (t1) == POINTER_TYPE)
242 if (compare_polymorphic)
243 if (contains_polymorphic_type_p (t1) || contains_polymorphic_type_p (t2))
245 if (!contains_polymorphic_type_p (t1) || !contains_polymorphic_type_p (t2))
246 return return_false_with_msg ("one type is not polymorphic");
248 if (!types_must_be_same_for_odr (t1, t2))
249 return return_false_with_msg ("types are not same for ODR");
255 /* Function compare for equality given memory operands T1 and T2. */
258 func_checker::compare_memory_operand (tree t1, tree t2)
266 ao_ref_init (&r1, t1);
267 ao_ref_init (&r2, t2);
269 tree b1 = ao_ref_base (&r1);
270 tree b2 = ao_ref_base (&r2);
272 bool source_is_memop = DECL_P (b1) || INDIRECT_REF_P (b1)
273 || TREE_CODE (b1) == MEM_REF
274 || TREE_CODE (b1) == TARGET_MEM_REF;
276 bool target_is_memop = DECL_P (b2) || INDIRECT_REF_P (b2)
277 || TREE_CODE (b2) == MEM_REF
278 || TREE_CODE (b2) == TARGET_MEM_REF;
280 /* Compare alias sets for memory operands. */
281 if (source_is_memop && target_is_memop)
283 if (TREE_THIS_VOLATILE (t1) != TREE_THIS_VOLATILE (t2))
284 return return_false_with_msg ("different operand volatility");
286 if (ao_ref_alias_set (&r1) != ao_ref_alias_set (&r2)
287 || ao_ref_base_alias_set (&r1) != ao_ref_base_alias_set (&r2))
288 return return_false_with_msg ("ao alias sets are different");
291 return compare_operand (t1, t2);
294 /* Function compare for equality given trees T1 and T2 which
295 can be either a constant or a declaration type. */
298 func_checker::compare_cst_or_decl (tree t1, tree t2)
302 switch (TREE_CODE (t1))
310 ret = compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2))
311 && operand_equal_p (t1, t2, OEP_ONLY_CONST);
312 return return_with_debug (ret);
316 ret = compare_function_decl (t1, t2);
317 return return_with_debug (ret);
320 return return_with_debug (compare_variable_decl (t1, t2));
323 tree offset1 = DECL_FIELD_OFFSET (t1);
324 tree offset2 = DECL_FIELD_OFFSET (t2);
326 tree bit_offset1 = DECL_FIELD_BIT_OFFSET (t1);
327 tree bit_offset2 = DECL_FIELD_BIT_OFFSET (t2);
329 ret = compare_operand (offset1, offset2)
330 && compare_operand (bit_offset1, bit_offset2);
332 return return_with_debug (ret);
336 int *bb1 = m_label_bb_map.get (t1);
337 int *bb2 = m_label_bb_map.get (t2);
339 return return_with_debug (*bb1 == *bb2);
345 ret = compare_decl (t1, t2);
346 return return_with_debug (ret);
353 /* Function responsible for comparison of various operands T1 and T2.
354 If these components, from functions FUNC1 and FUNC2, are equal, true
358 func_checker::compare_operand (tree t1, tree t2)
360 tree x1, x2, y1, y2, z1, z2;
368 tree tt1 = TREE_TYPE (t1);
369 tree tt2 = TREE_TYPE (t2);
371 if (!func_checker::compatible_types_p (tt1, tt2))
374 if (TREE_CODE (t1) != TREE_CODE (t2))
375 return return_false ();
377 switch (TREE_CODE (t1))
381 unsigned length1 = vec_safe_length (CONSTRUCTOR_ELTS (t1));
382 unsigned length2 = vec_safe_length (CONSTRUCTOR_ELTS (t2));
384 if (length1 != length2)
385 return return_false ();
387 for (unsigned i = 0; i < length1; i++)
388 if (!compare_operand (CONSTRUCTOR_ELT (t1, i)->value,
389 CONSTRUCTOR_ELT (t2, i)->value))
390 return return_false();
395 case ARRAY_RANGE_REF:
396 /* First argument is the array, second is the index. */
397 x1 = TREE_OPERAND (t1, 0);
398 x2 = TREE_OPERAND (t2, 0);
399 y1 = TREE_OPERAND (t1, 1);
400 y2 = TREE_OPERAND (t2, 1);
402 if (!compare_operand (array_ref_low_bound (t1),
403 array_ref_low_bound (t2)))
404 return return_false_with_msg ("");
405 if (!compare_operand (array_ref_element_size (t1),
406 array_ref_element_size (t2)))
407 return return_false_with_msg ("");
409 if (!compare_operand (x1, x2))
410 return return_false_with_msg ("");
411 return compare_operand (y1, y2);
414 x1 = TREE_OPERAND (t1, 0);
415 x2 = TREE_OPERAND (t2, 0);
416 y1 = TREE_OPERAND (t1, 1);
417 y2 = TREE_OPERAND (t2, 1);
419 /* See if operand is an memory access (the test originate from
422 In this case the alias set of the function being replaced must
423 be subset of the alias set of the other function. At the moment
424 we seek for equivalency classes, so simply require inclussion in
427 if (!func_checker::compatible_types_p (TREE_TYPE (x1), TREE_TYPE (x2)))
428 return return_false ();
430 if (!compare_operand (x1, x2))
431 return return_false_with_msg ("");
433 /* Type of the offset on MEM_REF does not matter. */
434 return wi::to_offset (y1) == wi::to_offset (y2);
438 x1 = TREE_OPERAND (t1, 0);
439 x2 = TREE_OPERAND (t2, 0);
440 y1 = TREE_OPERAND (t1, 1);
441 y2 = TREE_OPERAND (t2, 1);
443 ret = compare_operand (x1, x2)
444 && compare_cst_or_decl (y1, y2);
446 return return_with_debug (ret);
448 /* Virtual table call. */
451 x1 = TREE_OPERAND (t1, 0);
452 x2 = TREE_OPERAND (t2, 0);
453 y1 = TREE_OPERAND (t1, 1);
454 y2 = TREE_OPERAND (t2, 1);
455 z1 = TREE_OPERAND (t1, 2);
456 z2 = TREE_OPERAND (t2, 2);
458 ret = compare_ssa_name (x1, x2)
459 && compare_operand (y1, y2)
460 && compare_cst_or_decl (z1, z2);
462 return return_with_debug (ret);
468 x1 = TREE_OPERAND (t1, 0);
469 x2 = TREE_OPERAND (t2, 0);
471 ret = compare_operand (x1, x2);
472 return return_with_debug (ret);
476 x1 = TREE_OPERAND (t1, 0);
477 x2 = TREE_OPERAND (t2, 0);
478 y1 = TREE_OPERAND (t1, 1);
479 y2 = TREE_OPERAND (t2, 1);
480 z1 = TREE_OPERAND (t1, 2);
481 z2 = TREE_OPERAND (t2, 2);
483 ret = compare_operand (x1, x2)
484 && compare_cst_or_decl (y1, y2)
485 && compare_cst_or_decl (z1, z2);
487 return return_with_debug (ret);
490 return compare_ssa_name (t1, t2);
503 return compare_cst_or_decl (t1, t2);
505 return return_false_with_msg ("Unknown TREE code reached");
509 /* Compares two tree list operands T1 and T2 and returns true if these
510 two trees are semantically equivalent. */
513 func_checker::compare_tree_list_operand (tree t1, tree t2)
515 gcc_assert (TREE_CODE (t1) == TREE_LIST);
516 gcc_assert (TREE_CODE (t2) == TREE_LIST);
518 for (; t1; t1 = TREE_CHAIN (t1))
523 if (!compare_operand (TREE_VALUE (t1), TREE_VALUE (t2)))
524 return return_false ();
526 t2 = TREE_CHAIN (t2);
530 return return_false ();
535 /* Verifies that trees T1 and T2, representing function declarations
536 are equivalent from perspective of ICF. */
539 func_checker::compare_function_decl (tree t1, tree t2)
546 symtab_node *n1 = symtab_node::get (t1);
547 symtab_node *n2 = symtab_node::get (t2);
549 if (m_ignored_source_nodes != NULL && m_ignored_target_nodes != NULL)
551 ret = m_ignored_source_nodes->contains (n1)
552 && m_ignored_target_nodes->contains (n2);
558 /* If function decl is WEAKREF, we compare targets. */
559 cgraph_node *f1 = cgraph_node::get (t1);
560 cgraph_node *f2 = cgraph_node::get (t2);
562 if(f1 && f2 && f1->weakref && f2->weakref)
563 ret = f1->alias_target == f2->alias_target;
568 /* Verifies that trees T1 and T2 do correspond. */
571 func_checker::compare_variable_decl (tree t1, tree t2)
578 if (DECL_HARD_REGISTER (t1) != DECL_HARD_REGISTER (t2))
579 return return_false_with_msg ("DECL_HARD_REGISTER are different");
581 if (DECL_HARD_REGISTER (t1)
582 && DECL_ASSEMBLER_NAME (t1) != DECL_ASSEMBLER_NAME (t2))
583 return return_false_with_msg ("HARD REGISTERS are different");
585 if (TREE_CODE (t1) == VAR_DECL && (DECL_EXTERNAL (t1) || TREE_STATIC (t1)))
587 symtab_node *n1 = symtab_node::get (t1);
588 symtab_node *n2 = symtab_node::get (t2);
590 if (m_ignored_source_nodes != NULL && m_ignored_target_nodes != NULL)
592 ret = m_ignored_source_nodes->contains (n1)
593 && m_ignored_target_nodes->contains (n2);
599 ret = compare_decl (t1, t2);
601 return return_with_debug (ret);
605 /* Function visits all gimple labels and creates corresponding
606 mapping between basic blocks and labels. */
609 func_checker::parse_labels (sem_bb *bb)
611 for (gimple_stmt_iterator gsi = gsi_start_bb (bb->bb); !gsi_end_p (gsi);
614 gimple stmt = gsi_stmt (gsi);
616 if (glabel *label_stmt = dyn_cast <glabel *> (stmt))
618 tree t = gimple_label_label (label_stmt);
619 gcc_assert (TREE_CODE (t) == LABEL_DECL);
621 m_label_bb_map.put (t, bb->bb->index);
626 /* Basic block equivalence comparison function that returns true if
627 basic blocks BB1 and BB2 (from functions FUNC1 and FUNC2) correspond.
629 In general, a collection of equivalence dictionaries is built for types
630 like SSA names, declarations (VAR_DECL, PARM_DECL, ..). This infrastructure
631 is utilized by every statement-by-statement comparison function. */
634 func_checker::compare_bb (sem_bb *bb1, sem_bb *bb2)
636 gimple_stmt_iterator gsi1, gsi2;
639 gsi1 = gsi_start_bb_nondebug (bb1->bb);
640 gsi2 = gsi_start_bb_nondebug (bb2->bb);
642 while (!gsi_end_p (gsi1))
644 if (gsi_end_p (gsi2))
645 return return_false ();
647 s1 = gsi_stmt (gsi1);
648 s2 = gsi_stmt (gsi2);
650 int eh1 = lookup_stmt_eh_lp_fn
651 (DECL_STRUCT_FUNCTION (m_source_func_decl), s1);
652 int eh2 = lookup_stmt_eh_lp_fn
653 (DECL_STRUCT_FUNCTION (m_target_func_decl), s2);
656 return return_false_with_msg ("EH regions are different");
658 if (gimple_code (s1) != gimple_code (s2))
659 return return_false_with_msg ("gimple codes are different");
661 switch (gimple_code (s1))
664 if (!compare_gimple_call (as_a <gcall *> (s1),
665 as_a <gcall *> (s2)))
666 return return_different_stmts (s1, s2, "GIMPLE_CALL");
669 if (!compare_gimple_assign (s1, s2))
670 return return_different_stmts (s1, s2, "GIMPLE_ASSIGN");
673 if (!compare_gimple_cond (s1, s2))
674 return return_different_stmts (s1, s2, "GIMPLE_COND");
677 if (!compare_gimple_switch (as_a <gswitch *> (s1),
678 as_a <gswitch *> (s2)))
679 return return_different_stmts (s1, s2, "GIMPLE_SWITCH");
682 case GIMPLE_EH_DISPATCH:
685 if (!compare_gimple_resx (as_a <gresx *> (s1),
686 as_a <gresx *> (s2)))
687 return return_different_stmts (s1, s2, "GIMPLE_RESX");
690 if (!compare_gimple_label (as_a <glabel *> (s1),
691 as_a <glabel *> (s2)))
692 return return_different_stmts (s1, s2, "GIMPLE_LABEL");
695 if (!compare_gimple_return (as_a <greturn *> (s1),
696 as_a <greturn *> (s2)))
697 return return_different_stmts (s1, s2, "GIMPLE_RETURN");
700 if (!compare_gimple_goto (s1, s2))
701 return return_different_stmts (s1, s2, "GIMPLE_GOTO");
704 if (!compare_gimple_asm (as_a <gasm *> (s1),
706 return return_different_stmts (s1, s2, "GIMPLE_ASM");
712 return return_false_with_msg ("Unknown GIMPLE code reached");
715 gsi_next_nondebug (&gsi1);
716 gsi_next_nondebug (&gsi2);
719 if (!gsi_end_p (gsi2))
720 return return_false ();
725 /* Verifies for given GIMPLEs S1 and S2 that
726 call statements are semantically equivalent. */
729 func_checker::compare_gimple_call (gcall *s1, gcall *s2)
734 if (gimple_call_num_args (s1) != gimple_call_num_args (s2))
737 t1 = gimple_call_fn (s1);
738 t2 = gimple_call_fn (s2);
739 if (!compare_operand (t1, t2))
740 return return_false ();
743 if (gimple_call_internal_p (s1) != gimple_call_internal_p (s2)
744 || gimple_call_ctrl_altering_p (s1) != gimple_call_ctrl_altering_p (s2)
745 || gimple_call_tail_p (s1) != gimple_call_tail_p (s2)
746 || gimple_call_return_slot_opt_p (s1) != gimple_call_return_slot_opt_p (s2)
747 || gimple_call_from_thunk_p (s1) != gimple_call_from_thunk_p (s2)
748 || gimple_call_va_arg_pack_p (s1) != gimple_call_va_arg_pack_p (s2)
749 || gimple_call_alloca_for_var_p (s1) != gimple_call_alloca_for_var_p (s2)
750 || gimple_call_with_bounds_p (s1) != gimple_call_with_bounds_p (s2))
753 if (gimple_call_internal_p (s1)
754 && gimple_call_internal_fn (s1) != gimple_call_internal_fn (s2))
757 tree fntype1 = gimple_call_fntype (s1);
758 tree fntype2 = gimple_call_fntype (s2);
759 if ((fntype1 && !fntype2)
760 || (!fntype1 && fntype2)
761 || (fntype1 && !types_compatible_p (fntype1, fntype2)))
762 return return_false_with_msg ("call function types are not compatible");
764 tree chain1 = gimple_call_chain (s1);
765 tree chain2 = gimple_call_chain (s2);
766 if ((chain1 && !chain2)
767 || (!chain1 && chain2)
768 || !compare_operand (chain1, chain2))
769 return return_false_with_msg ("static call chains are different");
771 /* Checking of argument. */
772 for (i = 0; i < gimple_call_num_args (s1); ++i)
774 t1 = gimple_call_arg (s1, i);
775 t2 = gimple_call_arg (s2, i);
777 if (!compare_memory_operand (t1, t2))
778 return return_false_with_msg ("memory operands are different");
781 /* Return value checking. */
782 t1 = gimple_get_lhs (s1);
783 t2 = gimple_get_lhs (s2);
785 return compare_memory_operand (t1, t2);
789 /* Verifies for given GIMPLEs S1 and S2 that
790 assignment statements are semantically equivalent. */
793 func_checker::compare_gimple_assign (gimple s1, gimple s2)
796 tree_code code1, code2;
799 code1 = gimple_expr_code (s1);
800 code2 = gimple_expr_code (s2);
805 code1 = gimple_assign_rhs_code (s1);
806 code2 = gimple_assign_rhs_code (s2);
811 for (i = 0; i < gimple_num_ops (s1); i++)
813 arg1 = gimple_op (s1, i);
814 arg2 = gimple_op (s2, i);
816 if (!compare_memory_operand (arg1, arg2))
817 return return_false_with_msg ("memory operands are different");
824 /* Verifies for given GIMPLEs S1 and S2 that
825 condition statements are semantically equivalent. */
828 func_checker::compare_gimple_cond (gimple s1, gimple s2)
831 tree_code code1, code2;
833 code1 = gimple_expr_code (s1);
834 code2 = gimple_expr_code (s2);
839 t1 = gimple_cond_lhs (s1);
840 t2 = gimple_cond_lhs (s2);
842 if (!compare_operand (t1, t2))
845 t1 = gimple_cond_rhs (s1);
846 t2 = gimple_cond_rhs (s2);
848 return compare_operand (t1, t2);
851 /* Verifies that tree labels T1 and T2 correspond in FUNC1 and FUNC2. */
854 func_checker::compare_tree_ssa_label (tree t1, tree t2)
856 return compare_operand (t1, t2);
859 /* Verifies for given GIMPLE_LABEL stmts S1 and S2 that
860 label statements are semantically equivalent. */
863 func_checker::compare_gimple_label (const glabel *g1, const glabel *g2)
868 tree t1 = gimple_label_label (g1);
869 tree t2 = gimple_label_label (g2);
871 if (FORCED_LABEL (t1) || FORCED_LABEL (t2))
872 return return_false_with_msg ("FORCED_LABEL");
874 /* As the pass build BB to label mapping, no further check is needed. */
878 /* Verifies for given GIMPLE_SWITCH stmts S1 and S2 that
879 switch statements are semantically equivalent. */
882 func_checker::compare_gimple_switch (const gswitch *g1, const gswitch *g2)
884 unsigned lsize1, lsize2, i;
886 lsize1 = gimple_switch_num_labels (g1);
887 lsize2 = gimple_switch_num_labels (g2);
889 if (lsize1 != lsize2)
892 tree t1 = gimple_switch_index (g1);
893 tree t2 = gimple_switch_index (g2);
895 if (!compare_operand (t1, t2))
898 for (i = 0; i < lsize1; i++)
900 tree label1 = gimple_switch_label (g1, i);
901 tree label2 = gimple_switch_label (g2, i);
903 /* Label LOW and HIGH comparison. */
904 tree low1 = CASE_LOW (label1);
905 tree low2 = CASE_LOW (label2);
907 if (!tree_int_cst_equal (low1, low2))
908 return return_false_with_msg ("case low values are different");
910 tree high1 = CASE_HIGH (label1);
911 tree high2 = CASE_HIGH (label2);
913 if (!tree_int_cst_equal (high1, high2))
914 return return_false_with_msg ("case high values are different");
916 if (TREE_CODE (label1) == CASE_LABEL_EXPR
917 && TREE_CODE (label2) == CASE_LABEL_EXPR)
919 label1 = CASE_LABEL (label1);
920 label2 = CASE_LABEL (label2);
922 if (!compare_operand (label1, label2))
923 return return_false_with_msg ("switch label_exprs are different");
925 else if (!tree_int_cst_equal (label1, label2))
926 return return_false_with_msg ("switch labels are different");
932 /* Verifies for given GIMPLE_RETURN stmts S1 and S2 that
933 return statements are semantically equivalent. */
936 func_checker::compare_gimple_return (const greturn *g1, const greturn *g2)
940 t1 = gimple_return_retval (g1);
941 t2 = gimple_return_retval (g2);
943 /* Void return type. */
944 if (t1 == NULL && t2 == NULL)
947 return compare_operand (t1, t2);
950 /* Verifies for given GIMPLEs S1 and S2 that
951 goto statements are semantically equivalent. */
954 func_checker::compare_gimple_goto (gimple g1, gimple g2)
958 dest1 = gimple_goto_dest (g1);
959 dest2 = gimple_goto_dest (g2);
961 if (TREE_CODE (dest1) != TREE_CODE (dest2) || TREE_CODE (dest1) != SSA_NAME)
964 return compare_operand (dest1, dest2);
967 /* Verifies for given GIMPLE_RESX stmts S1 and S2 that
968 resx statements are semantically equivalent. */
971 func_checker::compare_gimple_resx (const gresx *g1, const gresx *g2)
973 return gimple_resx_region (g1) == gimple_resx_region (g2);
976 /* Verifies for given GIMPLEs S1 and S2 that ASM statements are equivalent.
977 For the beginning, the pass only supports equality for
978 '__asm__ __volatile__ ("", "", "", "memory")'. */
981 func_checker::compare_gimple_asm (const gasm *g1, const gasm *g2)
983 if (gimple_asm_volatile_p (g1) != gimple_asm_volatile_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