svn merge -r215707:216846 svn+ssh://gcc.gnu.org/svn/gcc/trunk
[official-gcc.git] / gcc / ipa-icf-gimple.c
blobd3f379557f16528d59a1f33b3314c79bd1797375
1 /* Interprocedural Identical Code Folding pass
2 Copyright (C) 2014 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
11 version.
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
16 for more details.
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/>. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tree.h"
26 #include "predict.h"
27 #include "vec.h"
28 #include "hashtab.h"
29 #include "hash-set.h"
30 #include "machmode.h"
31 #include "tm.h"
32 #include "hard-reg-set.h"
33 #include "input.h"
34 #include "function.h"
35 #include "basic-block.h"
36 #include "tree-ssa-alias.h"
37 #include "internal-fn.h"
38 #include "gimple-expr.h"
39 #include "is-a.h"
40 #include "gimple.h"
41 #include "expr.h"
42 #include "gimple-iterator.h"
43 #include "gimple-ssa.h"
44 #include "tree-cfg.h"
45 #include "stringpool.h"
46 #include "tree-dfa.h"
47 #include "tree-pass.h"
48 #include "gimple-pretty-print.h"
49 #include "cfgloop.h"
50 #include "except.h"
51 #include "hash-map.h"
52 #include "plugin-api.h"
53 #include "ipa-ref.h"
54 #include "cgraph.h"
55 #include "data-streamer.h"
56 #include "ipa-utils.h"
57 #include <list>
58 #include "tree-ssanames.h"
59 #include "tree-eh.h"
61 #include "ipa-icf-gimple.h"
62 #include "ipa-icf.h"
64 namespace ipa_icf_gimple {
66 /* Initialize internal structures for a given SOURCE_FUNC_DECL and
67 TARGET_FUNC_DECL. Strict polymorphic comparison is processed if
68 an option COMPARE_POLYMORPHIC is true. For special cases, one can
69 set IGNORE_LABELS to skip label comparison.
70 Similarly, IGNORE_SOURCE_DECLS and IGNORE_TARGET_DECLS are sets
71 of declarations that can be skipped. */
73 func_checker::func_checker (tree source_func_decl, tree target_func_decl,
74 bool compare_polymorphic,
75 bool ignore_labels,
76 hash_set<symtab_node *> *ignored_source_nodes,
77 hash_set<symtab_node *> *ignored_target_nodes)
78 : m_source_func_decl (source_func_decl), m_target_func_decl (target_func_decl),
79 m_ignored_source_nodes (ignored_source_nodes),
80 m_ignored_target_nodes (ignored_target_nodes),
81 m_compare_polymorphic (compare_polymorphic),
82 m_ignore_labels (ignore_labels)
84 function *source_func = DECL_STRUCT_FUNCTION (source_func_decl);
85 function *target_func = DECL_STRUCT_FUNCTION (target_func_decl);
87 unsigned ssa_source = SSANAMES (source_func)->length ();
88 unsigned ssa_target = SSANAMES (target_func)->length ();
90 m_source_ssa_names.create (ssa_source);
91 m_target_ssa_names.create (ssa_target);
93 for (unsigned i = 0; i < ssa_source; i++)
94 m_source_ssa_names.safe_push (-1);
96 for (unsigned i = 0; i < ssa_target; i++)
97 m_target_ssa_names.safe_push (-1);
100 /* Memory release routine. */
102 func_checker::~func_checker ()
104 m_source_ssa_names.release();
105 m_target_ssa_names.release();
108 /* Verifies that trees T1 and T2 are equivalent from perspective of ICF. */
110 bool
111 func_checker::compare_ssa_name (tree t1, tree t2)
113 unsigned i1 = SSA_NAME_VERSION (t1);
114 unsigned i2 = SSA_NAME_VERSION (t2);
116 if (m_source_ssa_names[i1] == -1)
117 m_source_ssa_names[i1] = i2;
118 else if (m_source_ssa_names[i1] != (int) i2)
119 return false;
121 if(m_target_ssa_names[i2] == -1)
122 m_target_ssa_names[i2] = i1;
123 else if (m_target_ssa_names[i2] != (int) i1)
124 return false;
126 return true;
129 /* Verification function for edges E1 and E2. */
131 bool
132 func_checker::compare_edge (edge e1, edge e2)
134 if (e1->flags != e2->flags)
135 return false;
137 bool existed_p;
139 edge &slot = m_edge_map.get_or_insert (e1, &existed_p);
140 if (existed_p)
141 return return_with_debug (slot == e2);
142 else
143 slot = e2;
145 /* TODO: filter edge probabilities for profile feedback match. */
147 return true;
150 /* Verification function for declaration trees T1 and T2 that
151 come from functions FUNC1 and FUNC2. */
153 bool
154 func_checker::compare_decl (tree t1, tree t2)
156 if (!auto_var_in_fn_p (t1, m_source_func_decl)
157 || !auto_var_in_fn_p (t2, m_target_func_decl))
158 return return_with_debug (t1 == t2);
160 tree_code t = TREE_CODE (t1);
161 if ((t == VAR_DECL || t == PARM_DECL || t == RESULT_DECL)
162 && DECL_BY_REFERENCE (t1) != DECL_BY_REFERENCE (t2))
163 return return_false_with_msg ("DECL_BY_REFERENCE flags are different");
165 if (!compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2),
166 m_compare_polymorphic))
167 return return_false ();
169 bool existed_p;
171 tree &slot = m_decl_map.get_or_insert (t1, &existed_p);
172 if (existed_p)
173 return return_with_debug (slot == t2);
174 else
175 slot = t2;
177 return true;
180 /* Return true if types are compatible from perspective of ICF. */
181 bool func_checker::compatible_types_p (tree t1, tree t2,
182 bool compare_polymorphic,
183 bool first_argument)
185 if (TREE_CODE (t1) != TREE_CODE (t2))
186 return return_false_with_msg ("different tree types");
188 if (!types_compatible_p (t1, t2))
189 return return_false_with_msg ("types are not compatible");
191 if (get_alias_set (t1) != get_alias_set (t2))
192 return return_false_with_msg ("alias sets are different");
194 /* We call contains_polymorphic_type_p with this pointer type. */
195 if (first_argument && TREE_CODE (t1) == POINTER_TYPE)
197 t1 = TREE_TYPE (t1);
198 t2 = TREE_TYPE (t2);
201 if (compare_polymorphic)
202 if (contains_polymorphic_type_p (t1) || contains_polymorphic_type_p (t2))
204 if (!contains_polymorphic_type_p (t1) || !contains_polymorphic_type_p (t2))
205 return return_false_with_msg ("one type is not polymorphic");
207 if (!types_must_be_same_for_odr (t1, t2))
208 return return_false_with_msg ("types are not same for ODR");
211 return true;
214 /* Function responsible for comparison of handled components T1 and T2.
215 If these components, from functions FUNC1 and FUNC2, are equal, true
216 is returned. */
218 bool
219 func_checker::compare_operand (tree t1, tree t2)
221 tree base1, base2, x1, x2, y1, y2, z1, z2;
222 HOST_WIDE_INT offset1 = 0, offset2 = 0;
223 bool ret;
225 if (!t1 && !t2)
226 return true;
227 else if (!t1 || !t2)
228 return false;
230 tree tt1 = TREE_TYPE (t1);
231 tree tt2 = TREE_TYPE (t2);
233 if (!func_checker::compatible_types_p (tt1, tt2))
234 return false;
236 base1 = get_addr_base_and_unit_offset (t1, &offset1);
237 base2 = get_addr_base_and_unit_offset (t2, &offset2);
239 if (base1 && base2)
241 if (offset1 != offset2)
242 return return_false_with_msg ("base offsets are different");
244 t1 = base1;
245 t2 = base2;
248 if (TREE_CODE (t1) != TREE_CODE (t2))
249 return return_false ();
251 switch (TREE_CODE (t1))
253 case CONSTRUCTOR:
255 unsigned length1 = vec_safe_length (CONSTRUCTOR_ELTS (t1));
256 unsigned length2 = vec_safe_length (CONSTRUCTOR_ELTS (t2));
258 if (length1 != length2)
259 return return_false ();
261 for (unsigned i = 0; i < length1; i++)
262 if (!compare_operand (CONSTRUCTOR_ELT (t1, i)->value,
263 CONSTRUCTOR_ELT (t2, i)->value))
264 return return_false();
266 return true;
268 case ARRAY_REF:
269 case ARRAY_RANGE_REF:
270 x1 = TREE_OPERAND (t1, 0);
271 x2 = TREE_OPERAND (t2, 0);
272 y1 = TREE_OPERAND (t1, 1);
273 y2 = TREE_OPERAND (t2, 1);
275 if (!compare_operand (array_ref_low_bound (t1),
276 array_ref_low_bound (t2)))
277 return return_false_with_msg ("");
278 if (!compare_operand (array_ref_element_size (t1),
279 array_ref_element_size (t2)))
280 return return_false_with_msg ("");
281 if (!compare_operand (x1, x2))
282 return return_false_with_msg ("");
283 return compare_operand (y1, y2);
284 case MEM_REF:
286 x1 = TREE_OPERAND (t1, 0);
287 x2 = TREE_OPERAND (t2, 0);
288 y1 = TREE_OPERAND (t1, 1);
289 y2 = TREE_OPERAND (t2, 1);
291 /* See if operand is an memory access (the test originate from
292 gimple_load_p).
294 In this case the alias set of the function being replaced must
295 be subset of the alias set of the other function. At the moment
296 we seek for equivalency classes, so simply require inclussion in
297 both directions. */
299 if (!func_checker::compatible_types_p (TREE_TYPE (x1), TREE_TYPE (x2)))
300 return return_false ();
302 if (!compare_operand (x1, x2))
303 return return_false_with_msg ("");
305 if (get_alias_set (TREE_TYPE (y1)) != get_alias_set (TREE_TYPE (y2)))
306 return return_false_with_msg ("alias set for MEM_REF offsets are different");
308 ao_ref r1, r2;
309 ao_ref_init (&r1, t1);
310 ao_ref_init (&r2, t2);
311 if (ao_ref_alias_set (&r1) != ao_ref_alias_set (&r2)
312 || ao_ref_base_alias_set (&r1) != ao_ref_base_alias_set (&r2))
313 return return_false_with_msg ("ao alias sets are different");
315 /* Type of the offset on MEM_REF does not matter. */
316 return wi::to_offset (y1) == wi::to_offset (y2);
318 case COMPONENT_REF:
320 x1 = TREE_OPERAND (t1, 0);
321 x2 = TREE_OPERAND (t2, 0);
322 y1 = TREE_OPERAND (t1, 1);
323 y2 = TREE_OPERAND (t2, 1);
325 ret = compare_operand (x1, x2)
326 && compare_operand (y1, y2);
328 return return_with_debug (ret);
330 /* Virtual table call. */
331 case OBJ_TYPE_REF:
333 x1 = TREE_OPERAND (t1, 0);
334 x2 = TREE_OPERAND (t2, 0);
335 y1 = TREE_OPERAND (t1, 1);
336 y2 = TREE_OPERAND (t2, 1);
337 z1 = TREE_OPERAND (t1, 2);
338 z2 = TREE_OPERAND (t2, 2);
340 ret = compare_operand (x1, x2)
341 && compare_operand (y1, y2)
342 && compare_operand (z1, z2);
344 return return_with_debug (ret);
346 case ADDR_EXPR:
348 x1 = TREE_OPERAND (t1, 0);
349 x2 = TREE_OPERAND (t2, 0);
351 ret = compare_operand (x1, x2);
352 return return_with_debug (ret);
354 case SSA_NAME:
356 ret = compare_ssa_name (t1, t2);
358 if (!ret)
359 return return_with_debug (ret);
361 if (SSA_NAME_IS_DEFAULT_DEF (t1))
363 tree b1 = SSA_NAME_VAR (t1);
364 tree b2 = SSA_NAME_VAR (t2);
366 if (b1 == NULL && b2 == NULL)
367 return true;
369 if (b1 == NULL || b2 == NULL || TREE_CODE (b1) != TREE_CODE (b2))
370 return return_false ();
372 switch (TREE_CODE (b1))
374 case VAR_DECL:
375 return return_with_debug (compare_variable_decl (t1, t2));
376 case PARM_DECL:
377 case RESULT_DECL:
378 ret = compare_decl (b1, b2);
379 return return_with_debug (ret);
380 default:
381 return return_false_with_msg ("Unknown TREE code reached");
384 else
385 return true;
387 case INTEGER_CST:
389 ret = compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2))
390 && wi::to_offset (t1) == wi::to_offset (t2);
392 return return_with_debug (ret);
394 case COMPLEX_CST:
395 case VECTOR_CST:
396 case STRING_CST:
397 case REAL_CST:
399 ret = operand_equal_p (t1, t2, OEP_ONLY_CONST);
400 return return_with_debug (ret);
402 case FUNCTION_DECL:
404 ret = compare_function_decl (t1, t2);
405 return return_with_debug (ret);
407 case VAR_DECL:
408 return return_with_debug (compare_variable_decl (t1, t2));
409 case FIELD_DECL:
411 tree offset1 = DECL_FIELD_OFFSET (t1);
412 tree offset2 = DECL_FIELD_OFFSET (t2);
414 tree bit_offset1 = DECL_FIELD_BIT_OFFSET (t1);
415 tree bit_offset2 = DECL_FIELD_BIT_OFFSET (t2);
417 ret = compare_operand (offset1, offset2)
418 && compare_operand (bit_offset1, bit_offset2);
420 return return_with_debug (ret);
422 case LABEL_DECL:
424 int *bb1 = m_label_bb_map.get (t1);
425 int *bb2 = m_label_bb_map.get (t2);
427 return return_with_debug (*bb1 == *bb2);
429 case PARM_DECL:
430 case RESULT_DECL:
431 case CONST_DECL:
432 case BIT_FIELD_REF:
434 ret = compare_decl (t1, t2);
435 return return_with_debug (ret);
437 default:
438 return return_false_with_msg ("Unknown TREE code reached");
442 /* Compares two tree list operands T1 and T2 and returns true if these
443 two trees are semantically equivalent. */
445 bool
446 func_checker::compare_tree_list_operand (tree t1, tree t2)
448 gcc_assert (TREE_CODE (t1) == TREE_LIST);
449 gcc_assert (TREE_CODE (t2) == TREE_LIST);
451 for (; t1; t1 = TREE_CHAIN (t1))
453 if (!t2)
454 return false;
456 if (!compare_operand (TREE_VALUE (t1), TREE_VALUE (t2)))
457 return return_false ();
459 t2 = TREE_CHAIN (t2);
462 if (t2)
463 return return_false ();
465 return true;
468 /* Verifies that trees T1 and T2, representing function declarations
469 are equivalent from perspective of ICF. */
471 bool
472 func_checker::compare_function_decl (tree t1, tree t2)
474 bool ret = false;
476 if (t1 == t2)
477 return true;
479 symtab_node *n1 = symtab_node::get (t1);
480 symtab_node *n2 = symtab_node::get (t2);
482 if (m_ignored_source_nodes != NULL && m_ignored_target_nodes != NULL)
484 ret = m_ignored_source_nodes->contains (n1)
485 && m_ignored_target_nodes->contains (n2);
487 if (ret)
488 return true;
491 /* If function decl is WEAKREF, we compare targets. */
492 cgraph_node *f1 = cgraph_node::get (t1);
493 cgraph_node *f2 = cgraph_node::get (t2);
495 if(f1 && f2 && f1->weakref && f2->weakref)
496 ret = f1->alias_target == f2->alias_target;
498 return ret;
501 /* Verifies that trees T1 and T2 do correspond. */
503 bool
504 func_checker::compare_variable_decl (tree t1, tree t2)
506 bool ret = false;
508 if (t1 == t2)
509 return true;
511 if (TREE_CODE (t1) == VAR_DECL && (DECL_EXTERNAL (t1) || TREE_STATIC (t1)))
513 symtab_node *n1 = symtab_node::get (t1);
514 symtab_node *n2 = symtab_node::get (t2);
516 if (m_ignored_source_nodes != NULL && m_ignored_target_nodes != NULL)
518 ret = m_ignored_source_nodes->contains (n1)
519 && m_ignored_target_nodes->contains (n2);
521 if (ret)
522 return true;
525 ret = compare_decl (t1, t2);
527 return return_with_debug (ret);
530 void
531 func_checker::parse_labels (sem_bb *bb)
533 for (gimple_stmt_iterator gsi = gsi_start_bb (bb->bb); !gsi_end_p (gsi);
534 gsi_next (&gsi))
536 gimple stmt = gsi_stmt (gsi);
538 if (gimple_code (stmt) == GIMPLE_LABEL)
540 tree t = gimple_label_label (stmt);
541 gcc_assert (TREE_CODE (t) == LABEL_DECL);
543 m_label_bb_map.put (t, bb->bb->index);
548 /* Basic block equivalence comparison function that returns true if
549 basic blocks BB1 and BB2 (from functions FUNC1 and FUNC2) correspond.
551 In general, a collection of equivalence dictionaries is built for types
552 like SSA names, declarations (VAR_DECL, PARM_DECL, ..). This infrastructure
553 is utilized by every statement-by-stament comparison function. */
555 bool
556 func_checker::compare_bb (sem_bb *bb1, sem_bb *bb2)
558 unsigned i;
559 gimple_stmt_iterator gsi1, gsi2;
560 gimple s1, s2;
562 if (bb1->nondbg_stmt_count != bb2->nondbg_stmt_count
563 || bb1->edge_count != bb2->edge_count)
564 return return_false ();
566 gsi1 = gsi_start_bb (bb1->bb);
567 gsi2 = gsi_start_bb (bb2->bb);
569 for (i = 0; i < bb1->nondbg_stmt_count; i++)
571 if (is_gimple_debug (gsi_stmt (gsi1)))
572 gsi_next_nondebug (&gsi1);
574 if (is_gimple_debug (gsi_stmt (gsi2)))
575 gsi_next_nondebug (&gsi2);
577 s1 = gsi_stmt (gsi1);
578 s2 = gsi_stmt (gsi2);
580 int eh1 = lookup_stmt_eh_lp_fn
581 (DECL_STRUCT_FUNCTION (m_source_func_decl), s1);
582 int eh2 = lookup_stmt_eh_lp_fn
583 (DECL_STRUCT_FUNCTION (m_target_func_decl), s2);
585 if (eh1 != eh2)
586 return return_false_with_msg ("EH regions are different");
588 if (gimple_code (s1) != gimple_code (s2))
589 return return_false_with_msg ("gimple codes are different");
591 switch (gimple_code (s1))
593 case GIMPLE_CALL:
594 if (!compare_gimple_call (s1, s2))
595 return return_different_stmts (s1, s2, "GIMPLE_CALL");
596 break;
597 case GIMPLE_ASSIGN:
598 if (!compare_gimple_assign (s1, s2))
599 return return_different_stmts (s1, s2, "GIMPLE_ASSIGN");
600 break;
601 case GIMPLE_COND:
602 if (!compare_gimple_cond (s1, s2))
603 return return_different_stmts (s1, s2, "GIMPLE_COND");
604 break;
605 case GIMPLE_SWITCH:
606 if (!compare_gimple_switch (s1, s2))
607 return return_different_stmts (s1, s2, "GIMPLE_SWITCH");
608 break;
609 case GIMPLE_DEBUG:
610 case GIMPLE_EH_DISPATCH:
611 break;
612 case GIMPLE_RESX:
613 if (!compare_gimple_resx (s1, s2))
614 return return_different_stmts (s1, s2, "GIMPLE_RESX");
615 break;
616 case GIMPLE_LABEL:
617 if (!compare_gimple_label (s1, s2))
618 return return_different_stmts (s1, s2, "GIMPLE_LABEL");
619 break;
620 case GIMPLE_RETURN:
621 if (!compare_gimple_return (s1, s2))
622 return return_different_stmts (s1, s2, "GIMPLE_RETURN");
623 break;
624 case GIMPLE_GOTO:
625 if (!compare_gimple_goto (s1, s2))
626 return return_different_stmts (s1, s2, "GIMPLE_GOTO");
627 break;
628 case GIMPLE_ASM:
629 if (!compare_gimple_asm (s1, s2))
630 return return_different_stmts (s1, s2, "GIMPLE_ASM");
631 break;
632 case GIMPLE_PREDICT:
633 case GIMPLE_NOP:
634 return true;
635 default:
636 return return_false_with_msg ("Unknown GIMPLE code reached");
639 gsi_next (&gsi1);
640 gsi_next (&gsi2);
643 return true;
646 /* Verifies for given GIMPLEs S1 and S2 that
647 call statements are semantically equivalent. */
649 bool
650 func_checker::compare_gimple_call (gimple s1, gimple s2)
652 unsigned i;
653 tree t1, t2;
655 if (gimple_call_num_args (s1) != gimple_call_num_args (s2))
656 return false;
658 t1 = gimple_call_fndecl (s1);
659 t2 = gimple_call_fndecl (s2);
661 /* Function pointer variables are not supported yet. */
662 if (!compare_operand (t1, t2))
663 return return_false();
665 /* Checking of argument. */
666 for (i = 0; i < gimple_call_num_args (s1); ++i)
668 t1 = gimple_call_arg (s1, i);
669 t2 = gimple_call_arg (s2, i);
671 if (!compare_operand (t1, t2))
672 return false;
675 /* Return value checking. */
676 t1 = gimple_get_lhs (s1);
677 t2 = gimple_get_lhs (s2);
679 return compare_operand (t1, t2);
683 /* Verifies for given GIMPLEs S1 and S2 that
684 assignment statements are semantically equivalent. */
686 bool
687 func_checker::compare_gimple_assign (gimple s1, gimple s2)
689 tree arg1, arg2;
690 tree_code code1, code2;
691 unsigned i;
693 code1 = gimple_expr_code (s1);
694 code2 = gimple_expr_code (s2);
696 if (code1 != code2)
697 return false;
699 code1 = gimple_assign_rhs_code (s1);
700 code2 = gimple_assign_rhs_code (s2);
702 if (code1 != code2)
703 return false;
705 for (i = 0; i < gimple_num_ops (s1); i++)
707 arg1 = gimple_op (s1, i);
708 arg2 = gimple_op (s2, i);
710 if (!compare_operand (arg1, arg2))
711 return false;
715 return true;
718 /* Verifies for given GIMPLEs S1 and S2 that
719 condition statements are semantically equivalent. */
721 bool
722 func_checker::compare_gimple_cond (gimple s1, gimple s2)
724 tree t1, t2;
725 tree_code code1, code2;
727 code1 = gimple_expr_code (s1);
728 code2 = gimple_expr_code (s2);
730 if (code1 != code2)
731 return false;
733 t1 = gimple_cond_lhs (s1);
734 t2 = gimple_cond_lhs (s2);
736 if (!compare_operand (t1, t2))
737 return false;
739 t1 = gimple_cond_rhs (s1);
740 t2 = gimple_cond_rhs (s2);
742 return compare_operand (t1, t2);
745 /* Verifies that tree labels T1 and T2 correspond in FUNC1 and FUNC2. */
747 bool
748 func_checker::compare_tree_ssa_label (tree t1, tree t2)
750 return compare_operand (t1, t2);
753 /* Verifies for given GIMPLEs S1 and S2 that
754 label statements are semantically equivalent. */
756 bool
757 func_checker::compare_gimple_label (gimple g1, gimple g2)
759 if (m_ignore_labels)
760 return true;
762 tree t1 = gimple_label_label (g1);
763 tree t2 = gimple_label_label (g2);
765 if (FORCED_LABEL (t1) || FORCED_LABEL (t2))
766 return return_false_with_msg ("FORCED_LABEL");
768 return compare_tree_ssa_label (t1, t2);
771 /* Verifies for given GIMPLEs S1 and S2 that
772 switch statements are semantically equivalent. */
774 bool
775 func_checker::compare_gimple_switch (gimple g1, gimple g2)
777 unsigned lsize1, lsize2, i;
779 lsize1 = gimple_switch_num_labels (g1);
780 lsize2 = gimple_switch_num_labels (g2);
782 if (lsize1 != lsize2)
783 return false;
785 tree t1 = gimple_switch_index (g1);
786 tree t2 = gimple_switch_index (g2);
788 if (!compare_operand (t1, t2))
789 return false;
791 for (i = 0; i < lsize1; i++)
793 tree label1 = gimple_switch_label (g1, i);
794 tree label2 = gimple_switch_label (g2, i);
796 if (TREE_CODE (label1) == CASE_LABEL_EXPR
797 && TREE_CODE (label2) == CASE_LABEL_EXPR)
799 label1 = CASE_LABEL (label1);
800 label2 = CASE_LABEL (label2);
802 if (!compare_operand (label1, label2))
803 return return_false_with_msg ("switch label_exprs are different");
805 else if (!tree_int_cst_equal (label1, label2))
806 return return_false_with_msg ("switch labels are different");
809 return true;
812 /* Verifies for given GIMPLEs S1 and S2 that
813 return statements are semantically equivalent. */
815 bool
816 func_checker::compare_gimple_return (gimple g1, gimple g2)
818 tree t1, t2;
820 t1 = gimple_return_retval (g1);
821 t2 = gimple_return_retval (g2);
823 /* Void return type. */
824 if (t1 == NULL && t2 == NULL)
825 return true;
826 else
827 return compare_operand (t1, t2);
830 /* Verifies for given GIMPLEs S1 and S2 that
831 goto statements are semantically equivalent. */
833 bool
834 func_checker::compare_gimple_goto (gimple g1, gimple g2)
836 tree dest1, dest2;
838 dest1 = gimple_goto_dest (g1);
839 dest2 = gimple_goto_dest (g2);
841 if (TREE_CODE (dest1) != TREE_CODE (dest2) || TREE_CODE (dest1) != SSA_NAME)
842 return false;
844 return compare_operand (dest1, dest2);
847 /* Verifies for given GIMPLEs S1 and S2 that
848 resx statements are semantically equivalent. */
850 bool
851 func_checker::compare_gimple_resx (gimple g1, gimple g2)
853 return gimple_resx_region (g1) == gimple_resx_region (g2);
856 /* Verifies for given GIMPLEs S1 and S2 that ASM statements are equivalent.
857 For the beginning, the pass only supports equality for
858 '__asm__ __volatile__ ("", "", "", "memory")'. */
860 bool
861 func_checker::compare_gimple_asm (gimple g1, gimple g2)
863 if (gimple_asm_volatile_p (g1) != gimple_asm_volatile_p (g2))
864 return false;
866 if (gimple_asm_ninputs (g1) != gimple_asm_ninputs (g2))
867 return false;
869 if (gimple_asm_noutputs (g1) != gimple_asm_noutputs (g2))
870 return false;
872 /* We do not suppport goto ASM statement comparison. */
873 if (gimple_asm_nlabels (g1) || gimple_asm_nlabels (g2))
874 return false;
876 if (gimple_asm_nclobbers (g1) != gimple_asm_nclobbers (g2))
877 return false;
879 if (strcmp (gimple_asm_string (g1), gimple_asm_string (g2)) != 0)
880 return return_false_with_msg ("ASM strings are different");
882 for (unsigned i = 0; i < gimple_asm_ninputs (g1); i++)
884 tree input1 = gimple_asm_input_op (g1, i);
885 tree input2 = gimple_asm_input_op (g2, i);
887 if (!compare_tree_list_operand (input1, input2))
888 return return_false_with_msg ("ASM input is different");
891 for (unsigned i = 0; i < gimple_asm_noutputs (g1); i++)
893 tree output1 = gimple_asm_output_op (g1, i);
894 tree output2 = gimple_asm_output_op (g2, i);
896 if (!compare_tree_list_operand (output1, output2))
897 return return_false_with_msg ("ASM output is different");
900 for (unsigned i = 0; i < gimple_asm_nclobbers (g1); i++)
902 tree clobber1 = gimple_asm_clobber_op (g1, i);
903 tree clobber2 = gimple_asm_clobber_op (g2, i);
905 if (!operand_equal_p (TREE_VALUE (clobber1), TREE_VALUE (clobber2),
906 OEP_ONLY_CONST))
907 return return_false_with_msg ("ASM clobber is different");
910 return true;
913 } // ipa_icf_gimple namespace