Fix the build after the merge from trunk
[official-gcc.git] / gcc / ipa-icf-gimple.c
blob9ebef25772e4ad5df89047c32d18f4457aac3687
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 "data-streamer.h"
52 #include "ipa-utils.h"
53 #include <list>
54 #include "tree-ssanames.h"
55 #include "tree-eh.h"
57 #include "ipa-icf-gimple.h"
58 #include "ipa-icf.h"
60 namespace ipa_icf_gimple {
62 /* Initialize internal structures for a given SOURCE_FUNC_DECL and
63 TARGET_FUNC_DECL. Strict polymorphic comparison is processed if
64 an option COMPARE_POLYMORPHIC is true. For special cases, one can
65 set IGNORE_LABELS to skip label comparison.
66 Similarly, IGNORE_SOURCE_DECLS and IGNORE_TARGET_DECLS are sets
67 of declarations that can be skipped. */
69 func_checker::func_checker (tree source_func_decl, tree target_func_decl,
70 bool compare_polymorphic,
71 bool ignore_labels,
72 hash_set<symtab_node *> *ignored_source_nodes,
73 hash_set<symtab_node *> *ignored_target_nodes)
74 : m_source_func_decl (source_func_decl), m_target_func_decl (target_func_decl),
75 m_ignored_source_nodes (ignored_source_nodes),
76 m_ignored_target_nodes (ignored_target_nodes),
77 m_compare_polymorphic (compare_polymorphic),
78 m_ignore_labels (ignore_labels)
80 function *source_func = DECL_STRUCT_FUNCTION (source_func_decl);
81 function *target_func = DECL_STRUCT_FUNCTION (target_func_decl);
83 unsigned ssa_source = SSANAMES (source_func)->length ();
84 unsigned ssa_target = SSANAMES (target_func)->length ();
86 m_source_ssa_names.create (ssa_source);
87 m_target_ssa_names.create (ssa_target);
89 for (unsigned i = 0; i < ssa_source; i++)
90 m_source_ssa_names.safe_push (-1);
92 for (unsigned i = 0; i < ssa_target; i++)
93 m_target_ssa_names.safe_push (-1);
96 /* Memory release routine. */
98 func_checker::~func_checker ()
100 m_source_ssa_names.release();
101 m_target_ssa_names.release();
104 /* Verifies that trees T1 and T2 are equivalent from perspective of ICF. */
106 bool
107 func_checker::compare_ssa_name (tree t1, tree t2)
109 unsigned i1 = SSA_NAME_VERSION (t1);
110 unsigned i2 = SSA_NAME_VERSION (t2);
112 if (m_source_ssa_names[i1] == -1)
113 m_source_ssa_names[i1] = i2;
114 else if (m_source_ssa_names[i1] != (int) i2)
115 return false;
117 if(m_target_ssa_names[i2] == -1)
118 m_target_ssa_names[i2] = i1;
119 else if (m_target_ssa_names[i2] != (int) i1)
120 return false;
122 return true;
125 /* Verification function for edges E1 and E2. */
127 bool
128 func_checker::compare_edge (edge e1, edge e2)
130 if (e1->flags != e2->flags)
131 return false;
133 bool existed_p;
135 edge &slot = m_edge_map.get_or_insert (e1, &existed_p);
136 if (existed_p)
137 return return_with_debug (slot == e2);
138 else
139 slot = e2;
141 /* TODO: filter edge probabilities for profile feedback match. */
143 return true;
146 /* Verification function for declaration trees T1 and T2 that
147 come from functions FUNC1 and FUNC2. */
149 bool
150 func_checker::compare_decl (tree t1, tree t2)
152 if (!auto_var_in_fn_p (t1, m_source_func_decl)
153 || !auto_var_in_fn_p (t2, m_target_func_decl))
154 return return_with_debug (t1 == t2);
156 tree_code t = TREE_CODE (t1);
157 if ((t == VAR_DECL || t == PARM_DECL || t == RESULT_DECL)
158 && DECL_BY_REFERENCE (t1) != DECL_BY_REFERENCE (t2))
159 return return_false_with_msg ("DECL_BY_REFERENCE flags are different");
161 if (!compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2),
162 m_compare_polymorphic))
163 return return_false ();
165 bool existed_p;
167 tree &slot = m_decl_map.get_or_insert (t1, &existed_p);
168 if (existed_p)
169 return return_with_debug (slot == t2);
170 else
171 slot = t2;
173 return true;
176 /* Return true if types are compatible from perspective of ICF. */
177 bool func_checker::compatible_types_p (tree t1, tree t2,
178 bool compare_polymorphic,
179 bool first_argument)
181 if (TREE_CODE (t1) != TREE_CODE (t2))
182 return return_false_with_msg ("different tree types");
184 if (!types_compatible_p (t1, t2))
185 return return_false_with_msg ("types are not compatible");
187 if (get_alias_set (t1) != get_alias_set (t2))
188 return return_false_with_msg ("alias sets are different");
190 /* We call contains_polymorphic_type_p with this pointer type. */
191 if (first_argument && TREE_CODE (t1) == POINTER_TYPE)
193 t1 = TREE_TYPE (t1);
194 t2 = TREE_TYPE (t2);
197 if (compare_polymorphic)
198 if (contains_polymorphic_type_p (t1) || contains_polymorphic_type_p (t2))
200 if (!contains_polymorphic_type_p (t1) || !contains_polymorphic_type_p (t2))
201 return return_false_with_msg ("one type is not polymorphic");
203 if (!types_must_be_same_for_odr (t1, t2))
204 return return_false_with_msg ("types are not same for ODR");
207 return true;
210 /* Function responsible for comparison of handled components T1 and T2.
211 If these components, from functions FUNC1 and FUNC2, are equal, true
212 is returned. */
214 bool
215 func_checker::compare_operand (tree t1, tree t2)
217 tree base1, base2, x1, x2, y1, y2, z1, z2;
218 HOST_WIDE_INT offset1 = 0, offset2 = 0;
219 bool ret;
221 if (!t1 && !t2)
222 return true;
223 else if (!t1 || !t2)
224 return false;
226 tree tt1 = TREE_TYPE (t1);
227 tree tt2 = TREE_TYPE (t2);
229 if (!func_checker::compatible_types_p (tt1, tt2))
230 return false;
232 base1 = get_addr_base_and_unit_offset (t1, &offset1);
233 base2 = get_addr_base_and_unit_offset (t2, &offset2);
235 if (base1 && base2)
237 if (offset1 != offset2)
238 return return_false_with_msg ("base offsets are different");
240 t1 = base1;
241 t2 = base2;
244 if (TREE_CODE (t1) != TREE_CODE (t2))
245 return return_false ();
247 switch (TREE_CODE (t1))
249 case CONSTRUCTOR:
251 unsigned length1 = vec_safe_length (CONSTRUCTOR_ELTS (t1));
252 unsigned length2 = vec_safe_length (CONSTRUCTOR_ELTS (t2));
254 if (length1 != length2)
255 return return_false ();
257 for (unsigned i = 0; i < length1; i++)
258 if (!compare_operand (CONSTRUCTOR_ELT (t1, i)->value,
259 CONSTRUCTOR_ELT (t2, i)->value))
260 return return_false();
262 return true;
264 case ARRAY_REF:
265 case ARRAY_RANGE_REF:
266 x1 = TREE_OPERAND (t1, 0);
267 x2 = TREE_OPERAND (t2, 0);
268 y1 = TREE_OPERAND (t1, 1);
269 y2 = TREE_OPERAND (t2, 1);
271 if (!compare_operand (array_ref_low_bound (t1),
272 array_ref_low_bound (t2)))
273 return return_false_with_msg ("");
274 if (!compare_operand (array_ref_element_size (t1),
275 array_ref_element_size (t2)))
276 return return_false_with_msg ("");
277 if (!compare_operand (x1, x2))
278 return return_false_with_msg ("");
279 return compare_operand (y1, y2);
280 case MEM_REF:
282 x1 = TREE_OPERAND (t1, 0);
283 x2 = TREE_OPERAND (t2, 0);
284 y1 = TREE_OPERAND (t1, 1);
285 y2 = TREE_OPERAND (t2, 1);
287 /* See if operand is an memory access (the test originate from
288 gimple_load_p).
290 In this case the alias set of the function being replaced must
291 be subset of the alias set of the other function. At the moment
292 we seek for equivalency classes, so simply require inclussion in
293 both directions. */
295 if (!func_checker::compatible_types_p (TREE_TYPE (x1), TREE_TYPE (x2)))
296 return return_false ();
298 if (!compare_operand (x1, x2))
299 return return_false_with_msg ("");
301 if (get_alias_set (TREE_TYPE (y1)) != get_alias_set (TREE_TYPE (y2)))
302 return return_false_with_msg ("alias set for MEM_REF offsets are different");
304 ao_ref r1, r2;
305 ao_ref_init (&r1, t1);
306 ao_ref_init (&r2, t2);
307 if (ao_ref_alias_set (&r1) != ao_ref_alias_set (&r2)
308 || ao_ref_base_alias_set (&r1) != ao_ref_base_alias_set (&r2))
309 return return_false_with_msg ("ao alias sets are different");
311 /* Type of the offset on MEM_REF does not matter. */
312 return wi::to_offset (y1) == wi::to_offset (y2);
314 case COMPONENT_REF:
316 x1 = TREE_OPERAND (t1, 0);
317 x2 = TREE_OPERAND (t2, 0);
318 y1 = TREE_OPERAND (t1, 1);
319 y2 = TREE_OPERAND (t2, 1);
321 ret = compare_operand (x1, x2)
322 && compare_operand (y1, y2);
324 return return_with_debug (ret);
326 /* Virtual table call. */
327 case OBJ_TYPE_REF:
329 x1 = TREE_OPERAND (t1, 0);
330 x2 = TREE_OPERAND (t2, 0);
331 y1 = TREE_OPERAND (t1, 1);
332 y2 = TREE_OPERAND (t2, 1);
333 z1 = TREE_OPERAND (t1, 2);
334 z2 = TREE_OPERAND (t2, 2);
336 ret = compare_operand (x1, x2)
337 && compare_operand (y1, y2)
338 && compare_operand (z1, z2);
340 return return_with_debug (ret);
342 case ADDR_EXPR:
344 x1 = TREE_OPERAND (t1, 0);
345 x2 = TREE_OPERAND (t2, 0);
347 ret = compare_operand (x1, x2);
348 return return_with_debug (ret);
350 case SSA_NAME:
352 ret = compare_ssa_name (t1, t2);
354 if (!ret)
355 return return_with_debug (ret);
357 if (SSA_NAME_IS_DEFAULT_DEF (t1))
359 tree b1 = SSA_NAME_VAR (t1);
360 tree b2 = SSA_NAME_VAR (t2);
362 if (b1 == NULL && b2 == NULL)
363 return true;
365 if (b1 == NULL || b2 == NULL || TREE_CODE (b1) != TREE_CODE (b2))
366 return return_false ();
368 switch (TREE_CODE (b1))
370 case VAR_DECL:
371 return return_with_debug (compare_variable_decl (t1, t2));
372 case PARM_DECL:
373 case RESULT_DECL:
374 ret = compare_decl (b1, b2);
375 return return_with_debug (ret);
376 default:
377 return return_false_with_msg ("Unknown TREE code reached");
380 else
381 return true;
383 case INTEGER_CST:
385 ret = compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2))
386 && wi::to_offset (t1) == wi::to_offset (t2);
388 return return_with_debug (ret);
390 case COMPLEX_CST:
391 case VECTOR_CST:
392 case STRING_CST:
393 case REAL_CST:
395 ret = operand_equal_p (t1, t2, OEP_ONLY_CONST);
396 return return_with_debug (ret);
398 case FUNCTION_DECL:
400 ret = compare_function_decl (t1, t2);
401 return return_with_debug (ret);
403 case VAR_DECL:
404 return return_with_debug (compare_variable_decl (t1, t2));
405 case FIELD_DECL:
407 tree offset1 = DECL_FIELD_OFFSET (t1);
408 tree offset2 = DECL_FIELD_OFFSET (t2);
410 tree bit_offset1 = DECL_FIELD_BIT_OFFSET (t1);
411 tree bit_offset2 = DECL_FIELD_BIT_OFFSET (t2);
413 ret = compare_operand (offset1, offset2)
414 && compare_operand (bit_offset1, bit_offset2);
416 return return_with_debug (ret);
418 case LABEL_DECL:
420 int *bb1 = m_label_bb_map.get (t1);
421 int *bb2 = m_label_bb_map.get (t2);
423 return return_with_debug (*bb1 == *bb2);
425 case PARM_DECL:
426 case RESULT_DECL:
427 case CONST_DECL:
428 case BIT_FIELD_REF:
430 ret = compare_decl (t1, t2);
431 return return_with_debug (ret);
433 default:
434 return return_false_with_msg ("Unknown TREE code reached");
438 /* Compares two tree list operands T1 and T2 and returns true if these
439 two trees are semantically equivalent. */
441 bool
442 func_checker::compare_tree_list_operand (tree t1, tree t2)
444 gcc_assert (TREE_CODE (t1) == TREE_LIST);
445 gcc_assert (TREE_CODE (t2) == TREE_LIST);
447 for (; t1; t1 = TREE_CHAIN (t1))
449 if (!t2)
450 return false;
452 if (!compare_operand (TREE_VALUE (t1), TREE_VALUE (t2)))
453 return return_false ();
455 t2 = TREE_CHAIN (t2);
458 if (t2)
459 return return_false ();
461 return true;
464 /* Verifies that trees T1 and T2, representing function declarations
465 are equivalent from perspective of ICF. */
467 bool
468 func_checker::compare_function_decl (tree t1, tree t2)
470 bool ret = false;
472 if (t1 == t2)
473 return true;
475 symtab_node *n1 = symtab_node::get (t1);
476 symtab_node *n2 = symtab_node::get (t2);
478 if (m_ignored_source_nodes != NULL && m_ignored_target_nodes != NULL)
480 ret = m_ignored_source_nodes->contains (n1)
481 && m_ignored_target_nodes->contains (n2);
483 if (ret)
484 return true;
487 /* If function decl is WEAKREF, we compare targets. */
488 cgraph_node *f1 = cgraph_node::get (t1);
489 cgraph_node *f2 = cgraph_node::get (t2);
491 if(f1 && f2 && f1->weakref && f2->weakref)
492 ret = f1->alias_target == f2->alias_target;
494 return ret;
497 /* Verifies that trees T1 and T2 do correspond. */
499 bool
500 func_checker::compare_variable_decl (tree t1, tree t2)
502 bool ret = false;
504 if (t1 == t2)
505 return true;
507 if (TREE_CODE (t1) == VAR_DECL && (DECL_EXTERNAL (t1) || TREE_STATIC (t1)))
509 symtab_node *n1 = symtab_node::get (t1);
510 symtab_node *n2 = symtab_node::get (t2);
512 if (m_ignored_source_nodes != NULL && m_ignored_target_nodes != NULL)
514 ret = m_ignored_source_nodes->contains (n1)
515 && m_ignored_target_nodes->contains (n2);
517 if (ret)
518 return true;
521 ret = compare_decl (t1, t2);
523 return return_with_debug (ret);
526 void
527 func_checker::parse_labels (sem_bb *bb)
529 for (gimple_stmt_iterator gsi = gsi_start_bb (bb->bb); !gsi_end_p (gsi);
530 gsi_next (&gsi))
532 gimple stmt = gsi_stmt (gsi);
534 if (glabel *label_stmt = dyn_cast <glabel *> (stmt))
536 tree t = gimple_label_label (label_stmt);
537 gcc_assert (TREE_CODE (t) == LABEL_DECL);
539 m_label_bb_map.put (t, bb->bb->index);
544 /* Basic block equivalence comparison function that returns true if
545 basic blocks BB1 and BB2 (from functions FUNC1 and FUNC2) correspond.
547 In general, a collection of equivalence dictionaries is built for types
548 like SSA names, declarations (VAR_DECL, PARM_DECL, ..). This infrastructure
549 is utilized by every statement-by-stament comparison function. */
551 bool
552 func_checker::compare_bb (sem_bb *bb1, sem_bb *bb2)
554 unsigned i;
555 gimple_stmt_iterator gsi1, gsi2;
556 gimple s1, s2;
558 if (bb1->nondbg_stmt_count != bb2->nondbg_stmt_count
559 || bb1->edge_count != bb2->edge_count)
560 return return_false ();
562 gsi1 = gsi_start_bb (bb1->bb);
563 gsi2 = gsi_start_bb (bb2->bb);
565 for (i = 0; i < bb1->nondbg_stmt_count; i++)
567 if (is_gimple_debug (gsi_stmt (gsi1)))
568 gsi_next_nondebug (&gsi1);
570 if (is_gimple_debug (gsi_stmt (gsi2)))
571 gsi_next_nondebug (&gsi2);
573 s1 = gsi_stmt (gsi1);
574 s2 = gsi_stmt (gsi2);
576 int eh1 = lookup_stmt_eh_lp_fn
577 (DECL_STRUCT_FUNCTION (m_source_func_decl), s1);
578 int eh2 = lookup_stmt_eh_lp_fn
579 (DECL_STRUCT_FUNCTION (m_target_func_decl), s2);
581 if (eh1 != eh2)
582 return return_false_with_msg ("EH regions are different");
584 if (gimple_code (s1) != gimple_code (s2))
585 return return_false_with_msg ("gimple codes are different");
587 switch (gimple_code (s1))
589 case GIMPLE_CALL:
590 if (!compare_gimple_call (s1, s2))
591 return return_different_stmts (s1, s2, "GIMPLE_CALL");
592 break;
593 case GIMPLE_ASSIGN:
594 if (!compare_gimple_assign (s1, s2))
595 return return_different_stmts (s1, s2, "GIMPLE_ASSIGN");
596 break;
597 case GIMPLE_COND:
598 if (!compare_gimple_cond (s1, s2))
599 return return_different_stmts (s1, s2, "GIMPLE_COND");
600 break;
601 case GIMPLE_SWITCH:
602 if (!compare_gimple_switch (as_a <gswitch *> (s1),
603 as_a <gswitch *> (s2)))
604 return return_different_stmts (s1, s2, "GIMPLE_SWITCH");
605 break;
606 case GIMPLE_DEBUG:
607 case GIMPLE_EH_DISPATCH:
608 break;
609 case GIMPLE_RESX:
610 if (!compare_gimple_resx (as_a <gresx *> (s1),
611 as_a <gresx *> (s2)))
612 return return_different_stmts (s1, s2, "GIMPLE_RESX");
613 break;
614 case GIMPLE_LABEL:
615 if (!compare_gimple_label (as_a <glabel *> (s1),
616 as_a <glabel *> (s2)))
617 return return_different_stmts (s1, s2, "GIMPLE_LABEL");
618 break;
619 case GIMPLE_RETURN:
620 if (!compare_gimple_return (as_a <greturn *> (s1),
621 as_a <greturn *> (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 (as_a <gasm *> (s1),
630 as_a <gasm *> (s2)))
631 return return_different_stmts (s1, s2, "GIMPLE_ASM");
632 break;
633 case GIMPLE_PREDICT:
634 case GIMPLE_NOP:
635 return true;
636 default:
637 return return_false_with_msg ("Unknown GIMPLE code reached");
640 gsi_next (&gsi1);
641 gsi_next (&gsi2);
644 return true;
647 /* Verifies for given GIMPLEs S1 and S2 that
648 call statements are semantically equivalent. */
650 bool
651 func_checker::compare_gimple_call (gimple s1, gimple s2)
653 unsigned i;
654 tree t1, t2;
656 if (gimple_call_num_args (s1) != gimple_call_num_args (s2))
657 return false;
659 t1 = gimple_call_fndecl (s1);
660 t2 = gimple_call_fndecl (s2);
662 /* Function pointer variables are not supported yet. */
663 if (!compare_operand (t1, t2))
664 return return_false();
666 /* Checking of argument. */
667 for (i = 0; i < gimple_call_num_args (s1); ++i)
669 t1 = gimple_call_arg (s1, i);
670 t2 = gimple_call_arg (s2, i);
672 if (!compare_operand (t1, t2))
673 return false;
676 /* Return value checking. */
677 t1 = gimple_get_lhs (s1);
678 t2 = gimple_get_lhs (s2);
680 return compare_operand (t1, t2);
684 /* Verifies for given GIMPLEs S1 and S2 that
685 assignment statements are semantically equivalent. */
687 bool
688 func_checker::compare_gimple_assign (gimple s1, gimple s2)
690 tree arg1, arg2;
691 tree_code code1, code2;
692 unsigned i;
694 code1 = gimple_expr_code (s1);
695 code2 = gimple_expr_code (s2);
697 if (code1 != code2)
698 return false;
700 code1 = gimple_assign_rhs_code (s1);
701 code2 = gimple_assign_rhs_code (s2);
703 if (code1 != code2)
704 return false;
706 for (i = 0; i < gimple_num_ops (s1); i++)
708 arg1 = gimple_op (s1, i);
709 arg2 = gimple_op (s2, i);
711 if (!compare_operand (arg1, arg2))
712 return false;
716 return true;
719 /* Verifies for given GIMPLEs S1 and S2 that
720 condition statements are semantically equivalent. */
722 bool
723 func_checker::compare_gimple_cond (gimple s1, gimple s2)
725 tree t1, t2;
726 tree_code code1, code2;
728 code1 = gimple_expr_code (s1);
729 code2 = gimple_expr_code (s2);
731 if (code1 != code2)
732 return false;
734 t1 = gimple_cond_lhs (s1);
735 t2 = gimple_cond_lhs (s2);
737 if (!compare_operand (t1, t2))
738 return false;
740 t1 = gimple_cond_rhs (s1);
741 t2 = gimple_cond_rhs (s2);
743 return compare_operand (t1, t2);
746 /* Verifies that tree labels T1 and T2 correspond in FUNC1 and FUNC2. */
748 bool
749 func_checker::compare_tree_ssa_label (tree t1, tree t2)
751 return compare_operand (t1, t2);
754 /* Verifies for given GIMPLE_LABEL stmts S1 and S2 that
755 label statements are semantically equivalent. */
757 bool
758 func_checker::compare_gimple_label (const glabel *g1, const glabel *g2)
760 if (m_ignore_labels)
761 return true;
763 tree t1 = gimple_label_label (g1);
764 tree t2 = gimple_label_label (g2);
766 if (FORCED_LABEL (t1) || FORCED_LABEL (t2))
767 return return_false_with_msg ("FORCED_LABEL");
769 return compare_tree_ssa_label (t1, t2);
772 /* Verifies for given GIMPLE_SWITCH stmts S1 and S2 that
773 switch statements are semantically equivalent. */
775 bool
776 func_checker::compare_gimple_switch (const gswitch *g1, const gswitch *g2)
778 unsigned lsize1, lsize2, i;
780 lsize1 = gimple_switch_num_labels (g1);
781 lsize2 = gimple_switch_num_labels (g2);
783 if (lsize1 != lsize2)
784 return false;
786 tree t1 = gimple_switch_index (g1);
787 tree t2 = gimple_switch_index (g2);
789 if (!compare_operand (t1, t2))
790 return false;
792 for (i = 0; i < lsize1; i++)
794 tree label1 = gimple_switch_label (g1, i);
795 tree label2 = gimple_switch_label (g2, i);
797 if (TREE_CODE (label1) == CASE_LABEL_EXPR
798 && TREE_CODE (label2) == CASE_LABEL_EXPR)
800 label1 = CASE_LABEL (label1);
801 label2 = CASE_LABEL (label2);
803 if (!compare_operand (label1, label2))
804 return return_false_with_msg ("switch label_exprs are different");
806 else if (!tree_int_cst_equal (label1, label2))
807 return return_false_with_msg ("switch labels are different");
810 return true;
813 /* Verifies for given GIMPLE_RETURN stmts S1 and S2 that
814 return statements are semantically equivalent. */
816 bool
817 func_checker::compare_gimple_return (const greturn *g1, const greturn *g2)
819 tree t1, t2;
821 t1 = gimple_return_retval (g1);
822 t2 = gimple_return_retval (g2);
824 /* Void return type. */
825 if (t1 == NULL && t2 == NULL)
826 return true;
827 else
828 return compare_operand (t1, t2);
831 /* Verifies for given GIMPLEs S1 and S2 that
832 goto statements are semantically equivalent. */
834 bool
835 func_checker::compare_gimple_goto (gimple g1, gimple g2)
837 tree dest1, dest2;
839 dest1 = gimple_goto_dest (g1);
840 dest2 = gimple_goto_dest (g2);
842 if (TREE_CODE (dest1) != TREE_CODE (dest2) || TREE_CODE (dest1) != SSA_NAME)
843 return false;
845 return compare_operand (dest1, dest2);
848 /* Verifies for given GIMPLE_RESX stmts S1 and S2 that
849 resx statements are semantically equivalent. */
851 bool
852 func_checker::compare_gimple_resx (const gresx *g1, const gresx *g2)
854 return gimple_resx_region (g1) == gimple_resx_region (g2);
857 /* Verifies for given GIMPLEs S1 and S2 that ASM statements are equivalent.
858 For the beginning, the pass only supports equality for
859 '__asm__ __volatile__ ("", "", "", "memory")'. */
861 bool
862 func_checker::compare_gimple_asm (const gasm *g1, const gasm *g2)
864 if (gimple_asm_volatile_p (g1) != gimple_asm_volatile_p (g2))
865 return false;
867 if (gimple_asm_ninputs (g1) != gimple_asm_ninputs (g2))
868 return false;
870 if (gimple_asm_noutputs (g1) != gimple_asm_noutputs (g2))
871 return false;
873 /* We do not suppport goto ASM statement comparison. */
874 if (gimple_asm_nlabels (g1) || gimple_asm_nlabels (g2))
875 return false;
877 if (gimple_asm_nclobbers (g1) != gimple_asm_nclobbers (g2))
878 return false;
880 if (strcmp (gimple_asm_string (g1), gimple_asm_string (g2)) != 0)
881 return return_false_with_msg ("ASM strings are different");
883 for (unsigned i = 0; i < gimple_asm_ninputs (g1); i++)
885 tree input1 = gimple_asm_input_op (g1, i);
886 tree input2 = gimple_asm_input_op (g2, i);
888 if (!compare_tree_list_operand (input1, input2))
889 return return_false_with_msg ("ASM input is different");
892 for (unsigned i = 0; i < gimple_asm_noutputs (g1); i++)
894 tree output1 = gimple_asm_output_op (g1, i);
895 tree output2 = gimple_asm_output_op (g2, i);
897 if (!compare_tree_list_operand (output1, output2))
898 return return_false_with_msg ("ASM output is different");
901 for (unsigned i = 0; i < gimple_asm_nclobbers (g1); i++)
903 tree clobber1 = gimple_asm_clobber_op (g1, i);
904 tree clobber2 = gimple_asm_clobber_op (g2, i);
906 if (!operand_equal_p (TREE_VALUE (clobber1), TREE_VALUE (clobber2),
907 OEP_ONLY_CONST))
908 return return_false_with_msg ("ASM clobber is different");
911 return true;
914 } // ipa_icf_gimple namespace