* g++.dg/template/using30.C: Move ...
[official-gcc.git] / gcc / ipa-icf-gimple.c
blobfa2c3534d8dc214ea425cfffdef21b297baea386
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 (TREE_THIS_VOLATILE (t1) != TREE_THIS_VOLATILE (t2))
234 return return_false_with_msg ("different operand volatility");
236 if (!func_checker::compatible_types_p (tt1, tt2))
237 return false;
239 base1 = get_addr_base_and_unit_offset (t1, &offset1);
240 base2 = get_addr_base_and_unit_offset (t2, &offset2);
242 if (base1 && base2)
244 if (offset1 != offset2)
245 return return_false_with_msg ("base offsets are different");
247 t1 = base1;
248 t2 = base2;
251 if (TREE_CODE (t1) != TREE_CODE (t2))
252 return return_false ();
254 switch (TREE_CODE (t1))
256 case CONSTRUCTOR:
258 unsigned length1 = vec_safe_length (CONSTRUCTOR_ELTS (t1));
259 unsigned length2 = vec_safe_length (CONSTRUCTOR_ELTS (t2));
261 if (length1 != length2)
262 return return_false ();
264 for (unsigned i = 0; i < length1; i++)
265 if (!compare_operand (CONSTRUCTOR_ELT (t1, i)->value,
266 CONSTRUCTOR_ELT (t2, i)->value))
267 return return_false();
269 return true;
271 case ARRAY_REF:
272 case ARRAY_RANGE_REF:
273 x1 = TREE_OPERAND (t1, 0);
274 x2 = TREE_OPERAND (t2, 0);
275 y1 = TREE_OPERAND (t1, 1);
276 y2 = TREE_OPERAND (t2, 1);
278 if (!compare_operand (array_ref_low_bound (t1),
279 array_ref_low_bound (t2)))
280 return return_false_with_msg ("");
281 if (!compare_operand (array_ref_element_size (t1),
282 array_ref_element_size (t2)))
283 return return_false_with_msg ("");
284 if (!compare_operand (x1, x2))
285 return return_false_with_msg ("");
286 return compare_operand (y1, y2);
287 case MEM_REF:
289 x1 = TREE_OPERAND (t1, 0);
290 x2 = TREE_OPERAND (t2, 0);
291 y1 = TREE_OPERAND (t1, 1);
292 y2 = TREE_OPERAND (t2, 1);
294 /* See if operand is an memory access (the test originate from
295 gimple_load_p).
297 In this case the alias set of the function being replaced must
298 be subset of the alias set of the other function. At the moment
299 we seek for equivalency classes, so simply require inclussion in
300 both directions. */
302 if (!func_checker::compatible_types_p (TREE_TYPE (x1), TREE_TYPE (x2)))
303 return return_false ();
305 if (!compare_operand (x1, x2))
306 return return_false_with_msg ("");
308 if (get_alias_set (TREE_TYPE (y1)) != get_alias_set (TREE_TYPE (y2)))
309 return return_false_with_msg ("alias set for MEM_REF offsets are different");
311 ao_ref r1, r2;
312 ao_ref_init (&r1, t1);
313 ao_ref_init (&r2, t2);
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 /* Type of the offset on MEM_REF does not matter. */
319 return wi::to_offset (y1) == wi::to_offset (y2);
321 case COMPONENT_REF:
323 x1 = TREE_OPERAND (t1, 0);
324 x2 = TREE_OPERAND (t2, 0);
325 y1 = TREE_OPERAND (t1, 1);
326 y2 = TREE_OPERAND (t2, 1);
328 ret = compare_operand (x1, x2)
329 && compare_operand (y1, y2);
331 return return_with_debug (ret);
333 /* Virtual table call. */
334 case OBJ_TYPE_REF:
336 x1 = TREE_OPERAND (t1, 0);
337 x2 = TREE_OPERAND (t2, 0);
338 y1 = TREE_OPERAND (t1, 1);
339 y2 = TREE_OPERAND (t2, 1);
340 z1 = TREE_OPERAND (t1, 2);
341 z2 = TREE_OPERAND (t2, 2);
343 ret = compare_operand (x1, x2)
344 && compare_operand (y1, y2)
345 && compare_operand (z1, z2);
347 return return_with_debug (ret);
349 case ADDR_EXPR:
351 x1 = TREE_OPERAND (t1, 0);
352 x2 = TREE_OPERAND (t2, 0);
354 ret = compare_operand (x1, x2);
355 return return_with_debug (ret);
357 case SSA_NAME:
359 ret = compare_ssa_name (t1, t2);
361 if (!ret)
362 return return_with_debug (ret);
364 if (SSA_NAME_IS_DEFAULT_DEF (t1))
366 tree b1 = SSA_NAME_VAR (t1);
367 tree b2 = SSA_NAME_VAR (t2);
369 if (b1 == NULL && b2 == NULL)
370 return true;
372 if (b1 == NULL || b2 == NULL || TREE_CODE (b1) != TREE_CODE (b2))
373 return return_false ();
375 switch (TREE_CODE (b1))
377 case VAR_DECL:
378 return return_with_debug (compare_variable_decl (t1, t2));
379 case PARM_DECL:
380 case RESULT_DECL:
381 ret = compare_decl (b1, b2);
382 return return_with_debug (ret);
383 default:
384 return return_false_with_msg ("Unknown TREE code reached");
387 else
388 return true;
390 case INTEGER_CST:
392 ret = compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2))
393 && wi::to_offset (t1) == wi::to_offset (t2);
395 return return_with_debug (ret);
397 case COMPLEX_CST:
398 case VECTOR_CST:
399 case STRING_CST:
400 case REAL_CST:
402 ret = operand_equal_p (t1, t2, OEP_ONLY_CONST);
403 return return_with_debug (ret);
405 case FUNCTION_DECL:
407 ret = compare_function_decl (t1, t2);
408 return return_with_debug (ret);
410 case VAR_DECL:
411 return return_with_debug (compare_variable_decl (t1, t2));
412 case FIELD_DECL:
414 tree offset1 = DECL_FIELD_OFFSET (t1);
415 tree offset2 = DECL_FIELD_OFFSET (t2);
417 tree bit_offset1 = DECL_FIELD_BIT_OFFSET (t1);
418 tree bit_offset2 = DECL_FIELD_BIT_OFFSET (t2);
420 ret = compare_operand (offset1, offset2)
421 && compare_operand (bit_offset1, bit_offset2);
423 return return_with_debug (ret);
425 case LABEL_DECL:
427 int *bb1 = m_label_bb_map.get (t1);
428 int *bb2 = m_label_bb_map.get (t2);
430 return return_with_debug (*bb1 == *bb2);
432 case PARM_DECL:
433 case RESULT_DECL:
434 case CONST_DECL:
435 case BIT_FIELD_REF:
437 ret = compare_decl (t1, t2);
438 return return_with_debug (ret);
440 default:
441 return return_false_with_msg ("Unknown TREE code reached");
445 /* Compares two tree list operands T1 and T2 and returns true if these
446 two trees are semantically equivalent. */
448 bool
449 func_checker::compare_tree_list_operand (tree t1, tree t2)
451 gcc_assert (TREE_CODE (t1) == TREE_LIST);
452 gcc_assert (TREE_CODE (t2) == TREE_LIST);
454 for (; t1; t1 = TREE_CHAIN (t1))
456 if (!t2)
457 return false;
459 if (!compare_operand (TREE_VALUE (t1), TREE_VALUE (t2)))
460 return return_false ();
462 t2 = TREE_CHAIN (t2);
465 if (t2)
466 return return_false ();
468 return true;
471 /* Verifies that trees T1 and T2, representing function declarations
472 are equivalent from perspective of ICF. */
474 bool
475 func_checker::compare_function_decl (tree t1, tree t2)
477 bool ret = false;
479 if (t1 == t2)
480 return true;
482 symtab_node *n1 = symtab_node::get (t1);
483 symtab_node *n2 = symtab_node::get (t2);
485 if (m_ignored_source_nodes != NULL && m_ignored_target_nodes != NULL)
487 ret = m_ignored_source_nodes->contains (n1)
488 && m_ignored_target_nodes->contains (n2);
490 if (ret)
491 return true;
494 /* If function decl is WEAKREF, we compare targets. */
495 cgraph_node *f1 = cgraph_node::get (t1);
496 cgraph_node *f2 = cgraph_node::get (t2);
498 if(f1 && f2 && f1->weakref && f2->weakref)
499 ret = f1->alias_target == f2->alias_target;
501 return ret;
504 /* Verifies that trees T1 and T2 do correspond. */
506 bool
507 func_checker::compare_variable_decl (tree t1, tree t2)
509 bool ret = false;
511 if (t1 == t2)
512 return true;
514 if (TREE_CODE (t1) == VAR_DECL && (DECL_EXTERNAL (t1) || TREE_STATIC (t1)))
516 symtab_node *n1 = symtab_node::get (t1);
517 symtab_node *n2 = symtab_node::get (t2);
519 if (m_ignored_source_nodes != NULL && m_ignored_target_nodes != NULL)
521 ret = m_ignored_source_nodes->contains (n1)
522 && m_ignored_target_nodes->contains (n2);
524 if (ret)
525 return true;
528 ret = compare_decl (t1, t2);
530 return return_with_debug (ret);
534 /* Function visits all gimple labels and creates corresponding
535 mapping between basic blocks and labels. */
537 void
538 func_checker::parse_labels (sem_bb *bb)
540 for (gimple_stmt_iterator gsi = gsi_start_bb (bb->bb); !gsi_end_p (gsi);
541 gsi_next (&gsi))
543 gimple stmt = gsi_stmt (gsi);
545 if (glabel *label_stmt = dyn_cast <glabel *> (stmt))
547 tree t = gimple_label_label (label_stmt);
548 gcc_assert (TREE_CODE (t) == LABEL_DECL);
550 m_label_bb_map.put (t, bb->bb->index);
555 /* Basic block equivalence comparison function that returns true if
556 basic blocks BB1 and BB2 (from functions FUNC1 and FUNC2) correspond.
558 In general, a collection of equivalence dictionaries is built for types
559 like SSA names, declarations (VAR_DECL, PARM_DECL, ..). This infrastructure
560 is utilized by every statement-by-statement comparison function. */
562 bool
563 func_checker::compare_bb (sem_bb *bb1, sem_bb *bb2)
565 gimple_stmt_iterator gsi1, gsi2;
566 gimple s1, s2;
568 gsi1 = gsi_start_bb_nondebug (bb1->bb);
569 gsi2 = gsi_start_bb_nondebug (bb2->bb);
571 while (!gsi_end_p (gsi1))
573 if (gsi_end_p (gsi2))
574 return return_false ();
576 s1 = gsi_stmt (gsi1);
577 s2 = gsi_stmt (gsi2);
579 int eh1 = lookup_stmt_eh_lp_fn
580 (DECL_STRUCT_FUNCTION (m_source_func_decl), s1);
581 int eh2 = lookup_stmt_eh_lp_fn
582 (DECL_STRUCT_FUNCTION (m_target_func_decl), s2);
584 if (eh1 != eh2)
585 return return_false_with_msg ("EH regions are different");
587 if (gimple_code (s1) != gimple_code (s2))
588 return return_false_with_msg ("gimple codes are different");
590 switch (gimple_code (s1))
592 case GIMPLE_CALL:
593 if (!compare_gimple_call (as_a <gcall *> (s1),
594 as_a <gcall *> (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 (as_a <gswitch *> (s1),
607 as_a <gswitch *> (s2)))
608 return return_different_stmts (s1, s2, "GIMPLE_SWITCH");
609 break;
610 case GIMPLE_DEBUG:
611 case GIMPLE_EH_DISPATCH:
612 break;
613 case GIMPLE_RESX:
614 if (!compare_gimple_resx (as_a <gresx *> (s1),
615 as_a <gresx *> (s2)))
616 return return_different_stmts (s1, s2, "GIMPLE_RESX");
617 break;
618 case GIMPLE_LABEL:
619 if (!compare_gimple_label (as_a <glabel *> (s1),
620 as_a <glabel *> (s2)))
621 return return_different_stmts (s1, s2, "GIMPLE_LABEL");
622 break;
623 case GIMPLE_RETURN:
624 if (!compare_gimple_return (as_a <greturn *> (s1),
625 as_a <greturn *> (s2)))
626 return return_different_stmts (s1, s2, "GIMPLE_RETURN");
627 break;
628 case GIMPLE_GOTO:
629 if (!compare_gimple_goto (s1, s2))
630 return return_different_stmts (s1, s2, "GIMPLE_GOTO");
631 break;
632 case GIMPLE_ASM:
633 if (!compare_gimple_asm (as_a <gasm *> (s1),
634 as_a <gasm *> (s2)))
635 return return_different_stmts (s1, s2, "GIMPLE_ASM");
636 break;
637 case GIMPLE_PREDICT:
638 case GIMPLE_NOP:
639 return true;
640 default:
641 return return_false_with_msg ("Unknown GIMPLE code reached");
644 gsi_next_nondebug (&gsi1);
645 gsi_next_nondebug (&gsi2);
648 if (!gsi_end_p (gsi2))
649 return return_false ();
651 return true;
654 /* Verifies for given GIMPLEs S1 and S2 that
655 call statements are semantically equivalent. */
657 bool
658 func_checker::compare_gimple_call (gcall *s1, gcall *s2)
660 unsigned i;
661 tree t1, t2;
663 if (gimple_call_num_args (s1) != gimple_call_num_args (s2))
664 return false;
666 t1 = gimple_call_fn (s1);
667 t2 = gimple_call_fn (s2);
668 if (!compare_operand (t1, t2))
669 return return_false ();
671 /* Compare flags. */
672 if (gimple_call_internal_p (s1) != gimple_call_internal_p (s2)
673 || gimple_call_ctrl_altering_p (s1) != gimple_call_ctrl_altering_p (s2)
674 || gimple_call_tail_p (s1) != gimple_call_tail_p (s2)
675 || gimple_call_return_slot_opt_p (s1) != gimple_call_return_slot_opt_p (s2)
676 || gimple_call_from_thunk_p (s1) != gimple_call_from_thunk_p (s2)
677 || gimple_call_va_arg_pack_p (s1) != gimple_call_va_arg_pack_p (s2)
678 || gimple_call_alloca_for_var_p (s1) != gimple_call_alloca_for_var_p (s2)
679 || gimple_call_with_bounds_p (s1) != gimple_call_with_bounds_p (s2))
680 return false;
682 if (gimple_call_internal_p (s1)
683 && gimple_call_internal_fn (s1) != gimple_call_internal_fn (s2))
684 return false;
686 tree fntype1 = gimple_call_fntype (s1);
687 tree fntype2 = gimple_call_fntype (s2);
688 if ((fntype1 && !fntype2)
689 || (!fntype1 && fntype2)
690 || (fntype1 && !types_compatible_p (fntype1, fntype2)))
691 return return_false_with_msg ("call function types are not compatible");
693 tree chain1 = gimple_call_chain (s1);
694 tree chain2 = gimple_call_chain (s2);
695 if ((chain1 && !chain2)
696 || (!chain1 && chain2)
697 || !compare_operand (chain1, chain2))
698 return return_false_with_msg ("static call chains are different");
700 /* Checking of argument. */
701 for (i = 0; i < gimple_call_num_args (s1); ++i)
703 t1 = gimple_call_arg (s1, i);
704 t2 = gimple_call_arg (s2, i);
706 if (!compare_operand (t1, t2))
707 return false;
710 /* Return value checking. */
711 t1 = gimple_get_lhs (s1);
712 t2 = gimple_get_lhs (s2);
714 return compare_operand (t1, t2);
718 /* Verifies for given GIMPLEs S1 and S2 that
719 assignment statements are semantically equivalent. */
721 bool
722 func_checker::compare_gimple_assign (gimple s1, gimple s2)
724 tree arg1, arg2;
725 tree_code code1, code2;
726 unsigned i;
728 code1 = gimple_expr_code (s1);
729 code2 = gimple_expr_code (s2);
731 if (code1 != code2)
732 return false;
734 code1 = gimple_assign_rhs_code (s1);
735 code2 = gimple_assign_rhs_code (s2);
737 if (code1 != code2)
738 return false;
740 for (i = 0; i < gimple_num_ops (s1); i++)
742 arg1 = gimple_op (s1, i);
743 arg2 = gimple_op (s2, i);
745 if (!compare_operand (arg1, arg2))
746 return false;
750 return true;
753 /* Verifies for given GIMPLEs S1 and S2 that
754 condition statements are semantically equivalent. */
756 bool
757 func_checker::compare_gimple_cond (gimple s1, gimple s2)
759 tree t1, t2;
760 tree_code code1, code2;
762 code1 = gimple_expr_code (s1);
763 code2 = gimple_expr_code (s2);
765 if (code1 != code2)
766 return false;
768 t1 = gimple_cond_lhs (s1);
769 t2 = gimple_cond_lhs (s2);
771 if (!compare_operand (t1, t2))
772 return false;
774 t1 = gimple_cond_rhs (s1);
775 t2 = gimple_cond_rhs (s2);
777 return compare_operand (t1, t2);
780 /* Verifies that tree labels T1 and T2 correspond in FUNC1 and FUNC2. */
782 bool
783 func_checker::compare_tree_ssa_label (tree t1, tree t2)
785 return compare_operand (t1, t2);
788 /* Verifies for given GIMPLE_LABEL stmts S1 and S2 that
789 label statements are semantically equivalent. */
791 bool
792 func_checker::compare_gimple_label (const glabel *g1, const glabel *g2)
794 if (m_ignore_labels)
795 return true;
797 tree t1 = gimple_label_label (g1);
798 tree t2 = gimple_label_label (g2);
800 if (FORCED_LABEL (t1) || FORCED_LABEL (t2))
801 return return_false_with_msg ("FORCED_LABEL");
803 /* As the pass build BB to label mapping, no further check is needed. */
804 return true;
807 /* Verifies for given GIMPLE_SWITCH stmts S1 and S2 that
808 switch statements are semantically equivalent. */
810 bool
811 func_checker::compare_gimple_switch (const gswitch *g1, const gswitch *g2)
813 unsigned lsize1, lsize2, i;
815 lsize1 = gimple_switch_num_labels (g1);
816 lsize2 = gimple_switch_num_labels (g2);
818 if (lsize1 != lsize2)
819 return false;
821 tree t1 = gimple_switch_index (g1);
822 tree t2 = gimple_switch_index (g2);
824 if (!compare_operand (t1, t2))
825 return false;
827 for (i = 0; i < lsize1; i++)
829 tree label1 = gimple_switch_label (g1, i);
830 tree label2 = gimple_switch_label (g2, i);
832 /* Label LOW and HIGH comparison. */
833 tree low1 = CASE_LOW (label1);
834 tree low2 = CASE_LOW (label2);
836 if (!tree_int_cst_equal (low1, low2))
837 return return_false_with_msg ("case low values are different");
839 tree high1 = CASE_HIGH (label1);
840 tree high2 = CASE_HIGH (label2);
842 if (!tree_int_cst_equal (high1, high2))
843 return return_false_with_msg ("case high values are different");
845 if (TREE_CODE (label1) == CASE_LABEL_EXPR
846 && TREE_CODE (label2) == CASE_LABEL_EXPR)
848 label1 = CASE_LABEL (label1);
849 label2 = CASE_LABEL (label2);
851 if (!compare_operand (label1, label2))
852 return return_false_with_msg ("switch label_exprs are different");
854 else if (!tree_int_cst_equal (label1, label2))
855 return return_false_with_msg ("switch labels are different");
858 return true;
861 /* Verifies for given GIMPLE_RETURN stmts S1 and S2 that
862 return statements are semantically equivalent. */
864 bool
865 func_checker::compare_gimple_return (const greturn *g1, const greturn *g2)
867 tree t1, t2;
869 t1 = gimple_return_retval (g1);
870 t2 = gimple_return_retval (g2);
872 /* Void return type. */
873 if (t1 == NULL && t2 == NULL)
874 return true;
875 else
876 return compare_operand (t1, t2);
879 /* Verifies for given GIMPLEs S1 and S2 that
880 goto statements are semantically equivalent. */
882 bool
883 func_checker::compare_gimple_goto (gimple g1, gimple g2)
885 tree dest1, dest2;
887 dest1 = gimple_goto_dest (g1);
888 dest2 = gimple_goto_dest (g2);
890 if (TREE_CODE (dest1) != TREE_CODE (dest2) || TREE_CODE (dest1) != SSA_NAME)
891 return false;
893 return compare_operand (dest1, dest2);
896 /* Verifies for given GIMPLE_RESX stmts S1 and S2 that
897 resx statements are semantically equivalent. */
899 bool
900 func_checker::compare_gimple_resx (const gresx *g1, const gresx *g2)
902 return gimple_resx_region (g1) == gimple_resx_region (g2);
905 /* Verifies for given GIMPLEs S1 and S2 that ASM statements are equivalent.
906 For the beginning, the pass only supports equality for
907 '__asm__ __volatile__ ("", "", "", "memory")'. */
909 bool
910 func_checker::compare_gimple_asm (const gasm *g1, const gasm *g2)
912 if (gimple_asm_volatile_p (g1) != gimple_asm_volatile_p (g2))
913 return false;
915 if (gimple_asm_ninputs (g1) != gimple_asm_ninputs (g2))
916 return false;
918 if (gimple_asm_noutputs (g1) != gimple_asm_noutputs (g2))
919 return false;
921 /* We do not suppport goto ASM statement comparison. */
922 if (gimple_asm_nlabels (g1) || gimple_asm_nlabels (g2))
923 return false;
925 if (gimple_asm_nclobbers (g1) != gimple_asm_nclobbers (g2))
926 return false;
928 if (strcmp (gimple_asm_string (g1), gimple_asm_string (g2)) != 0)
929 return return_false_with_msg ("ASM strings are different");
931 for (unsigned i = 0; i < gimple_asm_ninputs (g1); i++)
933 tree input1 = gimple_asm_input_op (g1, i);
934 tree input2 = gimple_asm_input_op (g2, i);
936 if (!compare_tree_list_operand (input1, input2))
937 return return_false_with_msg ("ASM input is different");
940 for (unsigned i = 0; i < gimple_asm_noutputs (g1); i++)
942 tree output1 = gimple_asm_output_op (g1, i);
943 tree output2 = gimple_asm_output_op (g2, i);
945 if (!compare_tree_list_operand (output1, output2))
946 return return_false_with_msg ("ASM output is different");
949 for (unsigned i = 0; i < gimple_asm_nclobbers (g1); i++)
951 tree clobber1 = gimple_asm_clobber_op (g1, i);
952 tree clobber2 = gimple_asm_clobber_op (g2, i);
954 if (!operand_equal_p (TREE_VALUE (clobber1), TREE_VALUE (clobber2),
955 OEP_ONLY_CONST))
956 return return_false_with_msg ("ASM clobber is different");
959 return true;
962 } // ipa_icf_gimple namespace