PR c++/64356
[official-gcc.git] / gcc / ipa-icf-gimple.c
blobed3cdf56ccb5e4ec46f1f96e25114bab810bcfc0
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
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 "hash-set.h"
26 #include "machmode.h"
27 #include "vec.h"
28 #include "double-int.h"
29 #include "input.h"
30 #include "alias.h"
31 #include "symtab.h"
32 #include "options.h"
33 #include "wide-int.h"
34 #include "inchash.h"
35 #include "tree.h"
36 #include "fold-const.h"
37 #include "predict.h"
38 #include "tm.h"
39 #include "hard-reg-set.h"
40 #include "input.h"
41 #include "function.h"
42 #include "basic-block.h"
43 #include "tree-ssa-alias.h"
44 #include "internal-fn.h"
45 #include "gimple-expr.h"
46 #include "is-a.h"
47 #include "gimple.h"
48 #include "expr.h"
49 #include "gimple-iterator.h"
50 #include "gimple-ssa.h"
51 #include "tree-cfg.h"
52 #include "stringpool.h"
53 #include "tree-dfa.h"
54 #include "tree-pass.h"
55 #include "gimple-pretty-print.h"
56 #include "cfgloop.h"
57 #include "except.h"
58 #include "hash-map.h"
59 #include "plugin-api.h"
60 #include "ipa-ref.h"
61 #include "cgraph.h"
62 #include "data-streamer.h"
63 #include "ipa-utils.h"
64 #include <list>
65 #include "tree-ssanames.h"
66 #include "tree-eh.h"
68 #include "ipa-icf-gimple.h"
69 #include "ipa-icf.h"
71 namespace ipa_icf_gimple {
73 /* Initialize internal structures for a given SOURCE_FUNC_DECL and
74 TARGET_FUNC_DECL. Strict polymorphic comparison is processed if
75 an option COMPARE_POLYMORPHIC is true. For special cases, one can
76 set IGNORE_LABELS to skip label comparison.
77 Similarly, IGNORE_SOURCE_DECLS and IGNORE_TARGET_DECLS are sets
78 of declarations that can be skipped. */
80 func_checker::func_checker (tree source_func_decl, tree target_func_decl,
81 bool compare_polymorphic,
82 bool ignore_labels,
83 hash_set<symtab_node *> *ignored_source_nodes,
84 hash_set<symtab_node *> *ignored_target_nodes)
85 : m_source_func_decl (source_func_decl), m_target_func_decl (target_func_decl),
86 m_ignored_source_nodes (ignored_source_nodes),
87 m_ignored_target_nodes (ignored_target_nodes),
88 m_compare_polymorphic (compare_polymorphic),
89 m_ignore_labels (ignore_labels)
91 function *source_func = DECL_STRUCT_FUNCTION (source_func_decl);
92 function *target_func = DECL_STRUCT_FUNCTION (target_func_decl);
94 unsigned ssa_source = SSANAMES (source_func)->length ();
95 unsigned ssa_target = SSANAMES (target_func)->length ();
97 m_source_ssa_names.create (ssa_source);
98 m_target_ssa_names.create (ssa_target);
100 for (unsigned i = 0; i < ssa_source; i++)
101 m_source_ssa_names.safe_push (-1);
103 for (unsigned i = 0; i < ssa_target; i++)
104 m_target_ssa_names.safe_push (-1);
107 /* Memory release routine. */
109 func_checker::~func_checker ()
111 m_source_ssa_names.release();
112 m_target_ssa_names.release();
115 /* Verifies that trees T1 and T2 are equivalent from perspective of ICF. */
117 bool
118 func_checker::compare_ssa_name (tree t1, tree t2)
120 gcc_assert (TREE_CODE (t1) == SSA_NAME);
121 gcc_assert (TREE_CODE (t2) == SSA_NAME);
123 unsigned i1 = SSA_NAME_VERSION (t1);
124 unsigned i2 = SSA_NAME_VERSION (t2);
126 if (m_source_ssa_names[i1] == -1)
127 m_source_ssa_names[i1] = i2;
128 else if (m_source_ssa_names[i1] != (int) i2)
129 return false;
131 if(m_target_ssa_names[i2] == -1)
132 m_target_ssa_names[i2] = i1;
133 else if (m_target_ssa_names[i2] != (int) i1)
134 return false;
136 if (SSA_NAME_IS_DEFAULT_DEF (t1))
138 tree b1 = SSA_NAME_VAR (t1);
139 tree b2 = SSA_NAME_VAR (t2);
141 if (b1 == NULL && b2 == NULL)
142 return true;
144 if (b1 == NULL || b2 == NULL || TREE_CODE (b1) != TREE_CODE (b2))
145 return return_false ();
147 return compare_cst_or_decl (b1, b2);
150 return true;
153 /* Verification function for edges E1 and E2. */
155 bool
156 func_checker::compare_edge (edge e1, edge e2)
158 if (e1->flags != e2->flags)
159 return false;
161 bool existed_p;
163 edge &slot = m_edge_map.get_or_insert (e1, &existed_p);
164 if (existed_p)
165 return return_with_debug (slot == e2);
166 else
167 slot = e2;
169 /* TODO: filter edge probabilities for profile feedback match. */
171 return true;
174 /* Verification function for declaration trees T1 and T2 that
175 come from functions FUNC1 and FUNC2. */
177 bool
178 func_checker::compare_decl (tree t1, tree t2)
180 if (!auto_var_in_fn_p (t1, m_source_func_decl)
181 || !auto_var_in_fn_p (t2, m_target_func_decl))
182 return return_with_debug (t1 == t2);
184 tree_code t = TREE_CODE (t1);
185 if ((t == VAR_DECL || t == PARM_DECL || t == RESULT_DECL)
186 && DECL_BY_REFERENCE (t1) != DECL_BY_REFERENCE (t2))
187 return return_false_with_msg ("DECL_BY_REFERENCE flags are different");
189 if (!compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2),
190 m_compare_polymorphic))
191 return return_false ();
193 bool existed_p;
195 tree &slot = m_decl_map.get_or_insert (t1, &existed_p);
196 if (existed_p)
197 return return_with_debug (slot == t2);
198 else
199 slot = t2;
201 return true;
204 /* Return true if types are compatible from perspective of ICF. */
205 bool
206 func_checker::compatible_types_p (tree t1, tree t2,
207 bool compare_polymorphic,
208 bool first_argument)
210 if (TREE_CODE (t1) != TREE_CODE (t2))
211 return return_false_with_msg ("different tree types");
213 if (TYPE_RESTRICT (t1) != TYPE_RESTRICT (t2))
214 return return_false_with_msg ("restrict flags are different");
216 if (!types_compatible_p (t1, t2))
217 return return_false_with_msg ("types are not compatible");
219 if (get_alias_set (t1) != get_alias_set (t2))
220 return return_false_with_msg ("alias sets are different");
222 /* We call contains_polymorphic_type_p with this pointer type. */
223 if (first_argument && TREE_CODE (t1) == POINTER_TYPE)
225 t1 = TREE_TYPE (t1);
226 t2 = TREE_TYPE (t2);
229 if (compare_polymorphic)
230 if (contains_polymorphic_type_p (t1) || contains_polymorphic_type_p (t2))
232 if (!contains_polymorphic_type_p (t1) || !contains_polymorphic_type_p (t2))
233 return return_false_with_msg ("one type is not polymorphic");
235 if (!types_must_be_same_for_odr (t1, t2))
236 return return_false_with_msg ("types are not same for ODR");
239 return true;
242 /* Function compare for equality given memory operands T1 and T2. */
244 bool
245 func_checker::compare_memory_operand (tree t1, tree t2)
247 if (!t1 && !t2)
248 return true;
249 else if (!t1 || !t2)
250 return false;
252 ao_ref r1, r2;
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");
278 return compare_operand (t1, t2);
281 /* Function compare for equality given trees T1 and T2 which
282 can be either a constant or a declaration type. */
284 bool
285 func_checker::compare_cst_or_decl (tree t1, tree t2)
287 bool ret;
289 switch (TREE_CODE (t1))
291 case INTEGER_CST:
292 case COMPLEX_CST:
293 case VECTOR_CST:
294 case STRING_CST:
295 case REAL_CST:
297 ret = compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2))
298 && operand_equal_p (t1, t2, OEP_ONLY_CONST);
299 return return_with_debug (ret);
301 case FUNCTION_DECL:
303 ret = compare_function_decl (t1, t2);
304 return return_with_debug (ret);
306 case VAR_DECL:
307 return return_with_debug (compare_variable_decl (t1, t2));
308 case FIELD_DECL:
310 tree offset1 = DECL_FIELD_OFFSET (t1);
311 tree offset2 = DECL_FIELD_OFFSET (t2);
313 tree bit_offset1 = DECL_FIELD_BIT_OFFSET (t1);
314 tree bit_offset2 = DECL_FIELD_BIT_OFFSET (t2);
316 ret = compare_operand (offset1, offset2)
317 && compare_operand (bit_offset1, bit_offset2);
319 return return_with_debug (ret);
321 case LABEL_DECL:
323 int *bb1 = m_label_bb_map.get (t1);
324 int *bb2 = m_label_bb_map.get (t2);
326 return return_with_debug (*bb1 == *bb2);
328 case PARM_DECL:
329 case RESULT_DECL:
330 case CONST_DECL:
332 ret = compare_decl (t1, t2);
333 return return_with_debug (ret);
335 default:
336 gcc_unreachable ();
340 /* Function responsible for comparison of various operands T1 and T2.
341 If these components, from functions FUNC1 and FUNC2, are equal, true
342 is returned. */
344 bool
345 func_checker::compare_operand (tree t1, tree t2)
347 tree x1, x2, y1, y2, z1, z2;
348 bool ret;
350 if (!t1 && !t2)
351 return true;
352 else if (!t1 || !t2)
353 return false;
355 tree tt1 = TREE_TYPE (t1);
356 tree tt2 = TREE_TYPE (t2);
358 if (!func_checker::compatible_types_p (tt1, tt2))
359 return false;
361 if (TREE_CODE (t1) != TREE_CODE (t2))
362 return return_false ();
364 switch (TREE_CODE (t1))
366 case CONSTRUCTOR:
368 unsigned length1 = vec_safe_length (CONSTRUCTOR_ELTS (t1));
369 unsigned length2 = vec_safe_length (CONSTRUCTOR_ELTS (t2));
371 if (length1 != length2)
372 return return_false ();
374 for (unsigned i = 0; i < length1; i++)
375 if (!compare_operand (CONSTRUCTOR_ELT (t1, i)->value,
376 CONSTRUCTOR_ELT (t2, i)->value))
377 return return_false();
379 return true;
381 case ARRAY_REF:
382 case ARRAY_RANGE_REF:
383 /* First argument is the array, second is the index. */
384 x1 = TREE_OPERAND (t1, 0);
385 x2 = TREE_OPERAND (t2, 0);
386 y1 = TREE_OPERAND (t1, 1);
387 y2 = TREE_OPERAND (t2, 1);
389 if (!compare_operand (array_ref_low_bound (t1),
390 array_ref_low_bound (t2)))
391 return return_false_with_msg ("");
392 if (!compare_operand (array_ref_element_size (t1),
393 array_ref_element_size (t2)))
394 return return_false_with_msg ("");
396 if (!compare_operand (x1, x2))
397 return return_false_with_msg ("");
398 return compare_operand (y1, y2);
399 case MEM_REF:
401 x1 = TREE_OPERAND (t1, 0);
402 x2 = TREE_OPERAND (t2, 0);
403 y1 = TREE_OPERAND (t1, 1);
404 y2 = TREE_OPERAND (t2, 1);
406 /* See if operand is an memory access (the test originate from
407 gimple_load_p).
409 In this case the alias set of the function being replaced must
410 be subset of the alias set of the other function. At the moment
411 we seek for equivalency classes, so simply require inclussion in
412 both directions. */
414 if (!func_checker::compatible_types_p (TREE_TYPE (x1), TREE_TYPE (x2)))
415 return return_false ();
417 if (!compare_operand (x1, x2))
418 return return_false_with_msg ("");
420 /* Type of the offset on MEM_REF does not matter. */
421 return wi::to_offset (y1) == wi::to_offset (y2);
423 case COMPONENT_REF:
425 x1 = TREE_OPERAND (t1, 0);
426 x2 = TREE_OPERAND (t2, 0);
427 y1 = TREE_OPERAND (t1, 1);
428 y2 = TREE_OPERAND (t2, 1);
430 ret = compare_operand (x1, x2)
431 && compare_cst_or_decl (y1, y2);
433 return return_with_debug (ret);
435 /* Virtual table call. */
436 case OBJ_TYPE_REF:
438 x1 = TREE_OPERAND (t1, 0);
439 x2 = TREE_OPERAND (t2, 0);
440 y1 = TREE_OPERAND (t1, 1);
441 y2 = TREE_OPERAND (t2, 1);
442 z1 = TREE_OPERAND (t1, 2);
443 z2 = TREE_OPERAND (t2, 2);
445 ret = compare_ssa_name (x1, x2)
446 && compare_ssa_name (y1, y2)
447 && compare_cst_or_decl (z1, z2);
449 return return_with_debug (ret);
451 case ADDR_EXPR:
453 x1 = TREE_OPERAND (t1, 0);
454 x2 = TREE_OPERAND (t2, 0);
456 ret = compare_operand (x1, x2);
457 return return_with_debug (ret);
459 case BIT_FIELD_REF:
461 ret = compare_decl (t1, t2);
462 return return_with_debug (ret);
464 case SSA_NAME:
465 return compare_ssa_name (t1, t2);
466 case INTEGER_CST:
467 case COMPLEX_CST:
468 case VECTOR_CST:
469 case STRING_CST:
470 case REAL_CST:
471 case FUNCTION_DECL:
472 case VAR_DECL:
473 case FIELD_DECL:
474 case LABEL_DECL:
475 case PARM_DECL:
476 case RESULT_DECL:
477 case CONST_DECL:
478 return compare_cst_or_decl (t1, t2);
479 default:
480 return return_false_with_msg ("Unknown TREE code reached");
484 /* Compares two tree list operands T1 and T2 and returns true if these
485 two trees are semantically equivalent. */
487 bool
488 func_checker::compare_tree_list_operand (tree t1, tree t2)
490 gcc_assert (TREE_CODE (t1) == TREE_LIST);
491 gcc_assert (TREE_CODE (t2) == TREE_LIST);
493 for (; t1; t1 = TREE_CHAIN (t1))
495 if (!t2)
496 return false;
498 if (!compare_operand (TREE_VALUE (t1), TREE_VALUE (t2)))
499 return return_false ();
501 t2 = TREE_CHAIN (t2);
504 if (t2)
505 return return_false ();
507 return true;
510 /* Verifies that trees T1 and T2, representing function declarations
511 are equivalent from perspective of ICF. */
513 bool
514 func_checker::compare_function_decl (tree t1, tree t2)
516 bool ret = false;
518 if (t1 == t2)
519 return true;
521 symtab_node *n1 = symtab_node::get (t1);
522 symtab_node *n2 = symtab_node::get (t2);
524 if (m_ignored_source_nodes != NULL && m_ignored_target_nodes != NULL)
526 ret = m_ignored_source_nodes->contains (n1)
527 && m_ignored_target_nodes->contains (n2);
529 if (ret)
530 return true;
533 /* If function decl is WEAKREF, we compare targets. */
534 cgraph_node *f1 = cgraph_node::get (t1);
535 cgraph_node *f2 = cgraph_node::get (t2);
537 if(f1 && f2 && f1->weakref && f2->weakref)
538 ret = f1->alias_target == f2->alias_target;
540 return ret;
543 /* Verifies that trees T1 and T2 do correspond. */
545 bool
546 func_checker::compare_variable_decl (tree t1, tree t2)
548 bool ret = false;
550 if (t1 == t2)
551 return true;
553 if (TREE_CODE (t1) == VAR_DECL && (DECL_EXTERNAL (t1) || TREE_STATIC (t1)))
555 symtab_node *n1 = symtab_node::get (t1);
556 symtab_node *n2 = symtab_node::get (t2);
558 if (m_ignored_source_nodes != NULL && m_ignored_target_nodes != NULL)
560 ret = m_ignored_source_nodes->contains (n1)
561 && m_ignored_target_nodes->contains (n2);
563 if (ret)
564 return true;
567 ret = compare_decl (t1, t2);
569 return return_with_debug (ret);
573 /* Function visits all gimple labels and creates corresponding
574 mapping between basic blocks and labels. */
576 void
577 func_checker::parse_labels (sem_bb *bb)
579 for (gimple_stmt_iterator gsi = gsi_start_bb (bb->bb); !gsi_end_p (gsi);
580 gsi_next (&gsi))
582 gimple stmt = gsi_stmt (gsi);
584 if (glabel *label_stmt = dyn_cast <glabel *> (stmt))
586 tree t = gimple_label_label (label_stmt);
587 gcc_assert (TREE_CODE (t) == LABEL_DECL);
589 m_label_bb_map.put (t, bb->bb->index);
594 /* Basic block equivalence comparison function that returns true if
595 basic blocks BB1 and BB2 (from functions FUNC1 and FUNC2) correspond.
597 In general, a collection of equivalence dictionaries is built for types
598 like SSA names, declarations (VAR_DECL, PARM_DECL, ..). This infrastructure
599 is utilized by every statement-by-statement comparison function. */
601 bool
602 func_checker::compare_bb (sem_bb *bb1, sem_bb *bb2)
604 gimple_stmt_iterator gsi1, gsi2;
605 gimple s1, s2;
607 gsi1 = gsi_start_bb_nondebug (bb1->bb);
608 gsi2 = gsi_start_bb_nondebug (bb2->bb);
610 while (!gsi_end_p (gsi1))
612 if (gsi_end_p (gsi2))
613 return return_false ();
615 s1 = gsi_stmt (gsi1);
616 s2 = gsi_stmt (gsi2);
618 int eh1 = lookup_stmt_eh_lp_fn
619 (DECL_STRUCT_FUNCTION (m_source_func_decl), s1);
620 int eh2 = lookup_stmt_eh_lp_fn
621 (DECL_STRUCT_FUNCTION (m_target_func_decl), s2);
623 if (eh1 != eh2)
624 return return_false_with_msg ("EH regions are different");
626 if (gimple_code (s1) != gimple_code (s2))
627 return return_false_with_msg ("gimple codes are different");
629 switch (gimple_code (s1))
631 case GIMPLE_CALL:
632 if (!compare_gimple_call (as_a <gcall *> (s1),
633 as_a <gcall *> (s2)))
634 return return_different_stmts (s1, s2, "GIMPLE_CALL");
635 break;
636 case GIMPLE_ASSIGN:
637 if (!compare_gimple_assign (s1, s2))
638 return return_different_stmts (s1, s2, "GIMPLE_ASSIGN");
639 break;
640 case GIMPLE_COND:
641 if (!compare_gimple_cond (s1, s2))
642 return return_different_stmts (s1, s2, "GIMPLE_COND");
643 break;
644 case GIMPLE_SWITCH:
645 if (!compare_gimple_switch (as_a <gswitch *> (s1),
646 as_a <gswitch *> (s2)))
647 return return_different_stmts (s1, s2, "GIMPLE_SWITCH");
648 break;
649 case GIMPLE_DEBUG:
650 case GIMPLE_EH_DISPATCH:
651 break;
652 case GIMPLE_RESX:
653 if (!compare_gimple_resx (as_a <gresx *> (s1),
654 as_a <gresx *> (s2)))
655 return return_different_stmts (s1, s2, "GIMPLE_RESX");
656 break;
657 case GIMPLE_LABEL:
658 if (!compare_gimple_label (as_a <glabel *> (s1),
659 as_a <glabel *> (s2)))
660 return return_different_stmts (s1, s2, "GIMPLE_LABEL");
661 break;
662 case GIMPLE_RETURN:
663 if (!compare_gimple_return (as_a <greturn *> (s1),
664 as_a <greturn *> (s2)))
665 return return_different_stmts (s1, s2, "GIMPLE_RETURN");
666 break;
667 case GIMPLE_GOTO:
668 if (!compare_gimple_goto (s1, s2))
669 return return_different_stmts (s1, s2, "GIMPLE_GOTO");
670 break;
671 case GIMPLE_ASM:
672 if (!compare_gimple_asm (as_a <gasm *> (s1),
673 as_a <gasm *> (s2)))
674 return return_different_stmts (s1, s2, "GIMPLE_ASM");
675 break;
676 case GIMPLE_PREDICT:
677 case GIMPLE_NOP:
678 return true;
679 default:
680 return return_false_with_msg ("Unknown GIMPLE code reached");
683 gsi_next_nondebug (&gsi1);
684 gsi_next_nondebug (&gsi2);
687 if (!gsi_end_p (gsi2))
688 return return_false ();
690 return true;
693 /* Verifies for given GIMPLEs S1 and S2 that
694 call statements are semantically equivalent. */
696 bool
697 func_checker::compare_gimple_call (gcall *s1, gcall *s2)
699 unsigned i;
700 tree t1, t2;
702 if (gimple_call_num_args (s1) != gimple_call_num_args (s2))
703 return false;
705 t1 = gimple_call_fn (s1);
706 t2 = gimple_call_fn (s2);
707 if (!compare_operand (t1, t2))
708 return return_false ();
710 /* Compare flags. */
711 if (gimple_call_internal_p (s1) != gimple_call_internal_p (s2)
712 || gimple_call_ctrl_altering_p (s1) != gimple_call_ctrl_altering_p (s2)
713 || gimple_call_tail_p (s1) != gimple_call_tail_p (s2)
714 || gimple_call_return_slot_opt_p (s1) != gimple_call_return_slot_opt_p (s2)
715 || gimple_call_from_thunk_p (s1) != gimple_call_from_thunk_p (s2)
716 || gimple_call_va_arg_pack_p (s1) != gimple_call_va_arg_pack_p (s2)
717 || gimple_call_alloca_for_var_p (s1) != gimple_call_alloca_for_var_p (s2)
718 || gimple_call_with_bounds_p (s1) != gimple_call_with_bounds_p (s2))
719 return false;
721 if (gimple_call_internal_p (s1)
722 && gimple_call_internal_fn (s1) != gimple_call_internal_fn (s2))
723 return false;
725 tree fntype1 = gimple_call_fntype (s1);
726 tree fntype2 = gimple_call_fntype (s2);
727 if ((fntype1 && !fntype2)
728 || (!fntype1 && fntype2)
729 || (fntype1 && !types_compatible_p (fntype1, fntype2)))
730 return return_false_with_msg ("call function types are not compatible");
732 tree chain1 = gimple_call_chain (s1);
733 tree chain2 = gimple_call_chain (s2);
734 if ((chain1 && !chain2)
735 || (!chain1 && chain2)
736 || !compare_operand (chain1, chain2))
737 return return_false_with_msg ("static call chains are different");
739 /* Checking of argument. */
740 for (i = 0; i < gimple_call_num_args (s1); ++i)
742 t1 = gimple_call_arg (s1, i);
743 t2 = gimple_call_arg (s2, i);
745 if (!compare_memory_operand (t1, t2))
746 return return_false_with_msg ("memory operands are different");
749 /* Return value checking. */
750 t1 = gimple_get_lhs (s1);
751 t2 = gimple_get_lhs (s2);
753 return compare_memory_operand (t1, t2);
757 /* Verifies for given GIMPLEs S1 and S2 that
758 assignment statements are semantically equivalent. */
760 bool
761 func_checker::compare_gimple_assign (gimple s1, gimple s2)
763 tree arg1, arg2;
764 tree_code code1, code2;
765 unsigned i;
767 code1 = gimple_expr_code (s1);
768 code2 = gimple_expr_code (s2);
770 if (code1 != code2)
771 return false;
773 code1 = gimple_assign_rhs_code (s1);
774 code2 = gimple_assign_rhs_code (s2);
776 if (code1 != code2)
777 return false;
779 for (i = 0; i < gimple_num_ops (s1); i++)
781 arg1 = gimple_op (s1, i);
782 arg2 = gimple_op (s2, i);
784 if (!compare_memory_operand (arg1, arg2))
785 return return_false_with_msg ("memory operands are different");
789 return true;
792 /* Verifies for given GIMPLEs S1 and S2 that
793 condition statements are semantically equivalent. */
795 bool
796 func_checker::compare_gimple_cond (gimple s1, gimple s2)
798 tree t1, t2;
799 tree_code code1, code2;
801 code1 = gimple_expr_code (s1);
802 code2 = gimple_expr_code (s2);
804 if (code1 != code2)
805 return false;
807 t1 = gimple_cond_lhs (s1);
808 t2 = gimple_cond_lhs (s2);
810 if (!compare_operand (t1, t2))
811 return false;
813 t1 = gimple_cond_rhs (s1);
814 t2 = gimple_cond_rhs (s2);
816 return compare_operand (t1, t2);
819 /* Verifies that tree labels T1 and T2 correspond in FUNC1 and FUNC2. */
821 bool
822 func_checker::compare_tree_ssa_label (tree t1, tree t2)
824 return compare_operand (t1, t2);
827 /* Verifies for given GIMPLE_LABEL stmts S1 and S2 that
828 label statements are semantically equivalent. */
830 bool
831 func_checker::compare_gimple_label (const glabel *g1, const glabel *g2)
833 if (m_ignore_labels)
834 return true;
836 tree t1 = gimple_label_label (g1);
837 tree t2 = gimple_label_label (g2);
839 if (FORCED_LABEL (t1) || FORCED_LABEL (t2))
840 return return_false_with_msg ("FORCED_LABEL");
842 /* As the pass build BB to label mapping, no further check is needed. */
843 return true;
846 /* Verifies for given GIMPLE_SWITCH stmts S1 and S2 that
847 switch statements are semantically equivalent. */
849 bool
850 func_checker::compare_gimple_switch (const gswitch *g1, const gswitch *g2)
852 unsigned lsize1, lsize2, i;
854 lsize1 = gimple_switch_num_labels (g1);
855 lsize2 = gimple_switch_num_labels (g2);
857 if (lsize1 != lsize2)
858 return false;
860 tree t1 = gimple_switch_index (g1);
861 tree t2 = gimple_switch_index (g2);
863 if (!compare_operand (t1, t2))
864 return false;
866 for (i = 0; i < lsize1; i++)
868 tree label1 = gimple_switch_label (g1, i);
869 tree label2 = gimple_switch_label (g2, i);
871 /* Label LOW and HIGH comparison. */
872 tree low1 = CASE_LOW (label1);
873 tree low2 = CASE_LOW (label2);
875 if (!tree_int_cst_equal (low1, low2))
876 return return_false_with_msg ("case low values are different");
878 tree high1 = CASE_HIGH (label1);
879 tree high2 = CASE_HIGH (label2);
881 if (!tree_int_cst_equal (high1, high2))
882 return return_false_with_msg ("case high values are different");
884 if (TREE_CODE (label1) == CASE_LABEL_EXPR
885 && TREE_CODE (label2) == CASE_LABEL_EXPR)
887 label1 = CASE_LABEL (label1);
888 label2 = CASE_LABEL (label2);
890 if (!compare_operand (label1, label2))
891 return return_false_with_msg ("switch label_exprs are different");
893 else if (!tree_int_cst_equal (label1, label2))
894 return return_false_with_msg ("switch labels are different");
897 return true;
900 /* Verifies for given GIMPLE_RETURN stmts S1 and S2 that
901 return statements are semantically equivalent. */
903 bool
904 func_checker::compare_gimple_return (const greturn *g1, const greturn *g2)
906 tree t1, t2;
908 t1 = gimple_return_retval (g1);
909 t2 = gimple_return_retval (g2);
911 /* Void return type. */
912 if (t1 == NULL && t2 == NULL)
913 return true;
914 else
915 return compare_operand (t1, t2);
918 /* Verifies for given GIMPLEs S1 and S2 that
919 goto statements are semantically equivalent. */
921 bool
922 func_checker::compare_gimple_goto (gimple g1, gimple g2)
924 tree dest1, dest2;
926 dest1 = gimple_goto_dest (g1);
927 dest2 = gimple_goto_dest (g2);
929 if (TREE_CODE (dest1) != TREE_CODE (dest2) || TREE_CODE (dest1) != SSA_NAME)
930 return false;
932 return compare_operand (dest1, dest2);
935 /* Verifies for given GIMPLE_RESX stmts S1 and S2 that
936 resx statements are semantically equivalent. */
938 bool
939 func_checker::compare_gimple_resx (const gresx *g1, const gresx *g2)
941 return gimple_resx_region (g1) == gimple_resx_region (g2);
944 /* Verifies for given GIMPLEs S1 and S2 that ASM statements are equivalent.
945 For the beginning, the pass only supports equality for
946 '__asm__ __volatile__ ("", "", "", "memory")'. */
948 bool
949 func_checker::compare_gimple_asm (const gasm *g1, const gasm *g2)
951 if (gimple_asm_volatile_p (g1) != gimple_asm_volatile_p (g2))
952 return false;
954 if (gimple_asm_ninputs (g1) != gimple_asm_ninputs (g2))
955 return false;
957 if (gimple_asm_noutputs (g1) != gimple_asm_noutputs (g2))
958 return false;
960 /* We do not suppport goto ASM statement comparison. */
961 if (gimple_asm_nlabels (g1) || gimple_asm_nlabels (g2))
962 return false;
964 if (gimple_asm_nclobbers (g1) != gimple_asm_nclobbers (g2))
965 return false;
967 if (strcmp (gimple_asm_string (g1), gimple_asm_string (g2)) != 0)
968 return return_false_with_msg ("ASM strings are different");
970 for (unsigned i = 0; i < gimple_asm_ninputs (g1); i++)
972 tree input1 = gimple_asm_input_op (g1, i);
973 tree input2 = gimple_asm_input_op (g2, i);
975 if (!compare_tree_list_operand (input1, input2))
976 return return_false_with_msg ("ASM input is different");
979 for (unsigned i = 0; i < gimple_asm_noutputs (g1); i++)
981 tree output1 = gimple_asm_output_op (g1, i);
982 tree output2 = gimple_asm_output_op (g2, i);
984 if (!compare_tree_list_operand (output1, output2))
985 return return_false_with_msg ("ASM output is different");
988 for (unsigned i = 0; i < gimple_asm_nclobbers (g1); i++)
990 tree clobber1 = gimple_asm_clobber_op (g1, i);
991 tree clobber2 = gimple_asm_clobber_op (g2, i);
993 if (!operand_equal_p (TREE_VALUE (clobber1), TREE_VALUE (clobber2),
994 OEP_ONLY_CONST))
995 return return_false_with_msg ("ASM clobber is different");
998 return true;
1001 } // ipa_icf_gimple namespace