jit: Add checking for dereference of void *
[official-gcc.git] / gcc / ipa-icf-gimple.c
blob694b0f48e6692593774ce3501ce3142b3a260c2f
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 "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 (TYPE_RESTRICT (t1) != TYPE_RESTRICT (t2))
189 return return_false_with_msg ("restrict flags are different");
191 if (!types_compatible_p (t1, t2))
192 return return_false_with_msg ("types are not compatible");
194 if (get_alias_set (t1) != get_alias_set (t2))
195 return return_false_with_msg ("alias sets are different");
197 /* We call contains_polymorphic_type_p with this pointer type. */
198 if (first_argument && TREE_CODE (t1) == POINTER_TYPE)
200 t1 = TREE_TYPE (t1);
201 t2 = TREE_TYPE (t2);
204 if (compare_polymorphic)
205 if (contains_polymorphic_type_p (t1) || contains_polymorphic_type_p (t2))
207 if (!contains_polymorphic_type_p (t1) || !contains_polymorphic_type_p (t2))
208 return return_false_with_msg ("one type is not polymorphic");
210 if (!types_must_be_same_for_odr (t1, t2))
211 return return_false_with_msg ("types are not same for ODR");
214 return true;
217 /* Function responsible for comparison of handled components T1 and T2.
218 If these components, from functions FUNC1 and FUNC2, are equal, true
219 is returned. */
221 bool
222 func_checker::compare_operand (tree t1, tree t2)
224 tree base1, base2, x1, x2, y1, y2, z1, z2;
225 HOST_WIDE_INT offset1 = 0, offset2 = 0;
226 bool ret;
228 if (!t1 && !t2)
229 return true;
230 else if (!t1 || !t2)
231 return false;
233 tree tt1 = TREE_TYPE (t1);
234 tree tt2 = TREE_TYPE (t2);
236 if (TREE_THIS_VOLATILE (t1) != TREE_THIS_VOLATILE (t2))
237 return return_false_with_msg ("different operand volatility");
239 if (!func_checker::compatible_types_p (tt1, tt2))
240 return false;
242 base1 = get_addr_base_and_unit_offset (t1, &offset1);
243 base2 = get_addr_base_and_unit_offset (t2, &offset2);
245 if (base1 && base2)
247 if (offset1 != offset2)
248 return return_false_with_msg ("base offsets are different");
250 t1 = base1;
251 t2 = base2;
254 if (TREE_CODE (t1) != TREE_CODE (t2))
255 return return_false ();
257 switch (TREE_CODE (t1))
259 case CONSTRUCTOR:
261 unsigned length1 = vec_safe_length (CONSTRUCTOR_ELTS (t1));
262 unsigned length2 = vec_safe_length (CONSTRUCTOR_ELTS (t2));
264 if (length1 != length2)
265 return return_false ();
267 for (unsigned i = 0; i < length1; i++)
268 if (!compare_operand (CONSTRUCTOR_ELT (t1, i)->value,
269 CONSTRUCTOR_ELT (t2, i)->value))
270 return return_false();
272 return true;
274 case ARRAY_REF:
275 case ARRAY_RANGE_REF:
276 x1 = TREE_OPERAND (t1, 0);
277 x2 = TREE_OPERAND (t2, 0);
278 y1 = TREE_OPERAND (t1, 1);
279 y2 = TREE_OPERAND (t2, 1);
281 if (!compare_operand (array_ref_low_bound (t1),
282 array_ref_low_bound (t2)))
283 return return_false_with_msg ("");
284 if (!compare_operand (array_ref_element_size (t1),
285 array_ref_element_size (t2)))
286 return return_false_with_msg ("");
287 if (!compare_operand (x1, x2))
288 return return_false_with_msg ("");
289 return compare_operand (y1, y2);
290 case MEM_REF:
292 x1 = TREE_OPERAND (t1, 0);
293 x2 = TREE_OPERAND (t2, 0);
294 y1 = TREE_OPERAND (t1, 1);
295 y2 = TREE_OPERAND (t2, 1);
297 /* See if operand is an memory access (the test originate from
298 gimple_load_p).
300 In this case the alias set of the function being replaced must
301 be subset of the alias set of the other function. At the moment
302 we seek for equivalency classes, so simply require inclussion in
303 both directions. */
305 if (!func_checker::compatible_types_p (TREE_TYPE (x1), TREE_TYPE (x2)))
306 return return_false ();
308 if (!compare_operand (x1, x2))
309 return return_false_with_msg ("");
311 if (get_alias_set (TREE_TYPE (y1)) != get_alias_set (TREE_TYPE (y2)))
312 return return_false_with_msg ("alias set for MEM_REF offsets are different");
314 ao_ref r1, r2;
315 ao_ref_init (&r1, t1);
316 ao_ref_init (&r2, t2);
317 if (ao_ref_alias_set (&r1) != ao_ref_alias_set (&r2)
318 || ao_ref_base_alias_set (&r1) != ao_ref_base_alias_set (&r2))
319 return return_false_with_msg ("ao alias sets are different");
321 /* Type of the offset on MEM_REF does not matter. */
322 return wi::to_offset (y1) == wi::to_offset (y2);
324 case COMPONENT_REF:
326 x1 = TREE_OPERAND (t1, 0);
327 x2 = TREE_OPERAND (t2, 0);
328 y1 = TREE_OPERAND (t1, 1);
329 y2 = TREE_OPERAND (t2, 1);
331 ret = compare_operand (x1, x2)
332 && compare_operand (y1, y2);
334 return return_with_debug (ret);
336 /* Virtual table call. */
337 case OBJ_TYPE_REF:
339 x1 = TREE_OPERAND (t1, 0);
340 x2 = TREE_OPERAND (t2, 0);
341 y1 = TREE_OPERAND (t1, 1);
342 y2 = TREE_OPERAND (t2, 1);
343 z1 = TREE_OPERAND (t1, 2);
344 z2 = TREE_OPERAND (t2, 2);
346 ret = compare_operand (x1, x2)
347 && compare_operand (y1, y2)
348 && compare_operand (z1, z2);
350 return return_with_debug (ret);
352 case ADDR_EXPR:
354 x1 = TREE_OPERAND (t1, 0);
355 x2 = TREE_OPERAND (t2, 0);
357 ret = compare_operand (x1, x2);
358 return return_with_debug (ret);
360 case SSA_NAME:
362 ret = compare_ssa_name (t1, t2);
364 if (!ret)
365 return return_with_debug (ret);
367 if (SSA_NAME_IS_DEFAULT_DEF (t1))
369 tree b1 = SSA_NAME_VAR (t1);
370 tree b2 = SSA_NAME_VAR (t2);
372 if (b1 == NULL && b2 == NULL)
373 return true;
375 if (b1 == NULL || b2 == NULL || TREE_CODE (b1) != TREE_CODE (b2))
376 return return_false ();
378 switch (TREE_CODE (b1))
380 case VAR_DECL:
381 return return_with_debug (compare_variable_decl (t1, t2));
382 case PARM_DECL:
383 case RESULT_DECL:
384 ret = compare_decl (b1, b2);
385 return return_with_debug (ret);
386 default:
387 return return_false_with_msg ("Unknown TREE code reached");
390 else
391 return true;
393 case INTEGER_CST:
395 ret = compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2))
396 && wi::to_offset (t1) == wi::to_offset (t2);
398 return return_with_debug (ret);
400 case COMPLEX_CST:
401 case VECTOR_CST:
402 case STRING_CST:
403 case REAL_CST:
405 ret = operand_equal_p (t1, t2, OEP_ONLY_CONST);
406 return return_with_debug (ret);
408 case FUNCTION_DECL:
410 ret = compare_function_decl (t1, t2);
411 return return_with_debug (ret);
413 case VAR_DECL:
414 return return_with_debug (compare_variable_decl (t1, t2));
415 case FIELD_DECL:
417 tree offset1 = DECL_FIELD_OFFSET (t1);
418 tree offset2 = DECL_FIELD_OFFSET (t2);
420 tree bit_offset1 = DECL_FIELD_BIT_OFFSET (t1);
421 tree bit_offset2 = DECL_FIELD_BIT_OFFSET (t2);
423 ret = compare_operand (offset1, offset2)
424 && compare_operand (bit_offset1, bit_offset2);
426 return return_with_debug (ret);
428 case LABEL_DECL:
430 int *bb1 = m_label_bb_map.get (t1);
431 int *bb2 = m_label_bb_map.get (t2);
433 return return_with_debug (*bb1 == *bb2);
435 case PARM_DECL:
436 case RESULT_DECL:
437 case CONST_DECL:
438 case BIT_FIELD_REF:
440 ret = compare_decl (t1, t2);
441 return return_with_debug (ret);
443 default:
444 return return_false_with_msg ("Unknown TREE code reached");
448 /* Compares two tree list operands T1 and T2 and returns true if these
449 two trees are semantically equivalent. */
451 bool
452 func_checker::compare_tree_list_operand (tree t1, tree t2)
454 gcc_assert (TREE_CODE (t1) == TREE_LIST);
455 gcc_assert (TREE_CODE (t2) == TREE_LIST);
457 for (; t1; t1 = TREE_CHAIN (t1))
459 if (!t2)
460 return false;
462 if (!compare_operand (TREE_VALUE (t1), TREE_VALUE (t2)))
463 return return_false ();
465 t2 = TREE_CHAIN (t2);
468 if (t2)
469 return return_false ();
471 return true;
474 /* Verifies that trees T1 and T2, representing function declarations
475 are equivalent from perspective of ICF. */
477 bool
478 func_checker::compare_function_decl (tree t1, tree t2)
480 bool ret = false;
482 if (t1 == t2)
483 return true;
485 symtab_node *n1 = symtab_node::get (t1);
486 symtab_node *n2 = symtab_node::get (t2);
488 if (m_ignored_source_nodes != NULL && m_ignored_target_nodes != NULL)
490 ret = m_ignored_source_nodes->contains (n1)
491 && m_ignored_target_nodes->contains (n2);
493 if (ret)
494 return true;
497 /* If function decl is WEAKREF, we compare targets. */
498 cgraph_node *f1 = cgraph_node::get (t1);
499 cgraph_node *f2 = cgraph_node::get (t2);
501 if(f1 && f2 && f1->weakref && f2->weakref)
502 ret = f1->alias_target == f2->alias_target;
504 return ret;
507 /* Verifies that trees T1 and T2 do correspond. */
509 bool
510 func_checker::compare_variable_decl (tree t1, tree t2)
512 bool ret = false;
514 if (t1 == t2)
515 return true;
517 if (TREE_CODE (t1) == VAR_DECL && (DECL_EXTERNAL (t1) || TREE_STATIC (t1)))
519 symtab_node *n1 = symtab_node::get (t1);
520 symtab_node *n2 = symtab_node::get (t2);
522 if (m_ignored_source_nodes != NULL && m_ignored_target_nodes != NULL)
524 ret = m_ignored_source_nodes->contains (n1)
525 && m_ignored_target_nodes->contains (n2);
527 if (ret)
528 return true;
531 ret = compare_decl (t1, t2);
533 return return_with_debug (ret);
537 /* Function visits all gimple labels and creates corresponding
538 mapping between basic blocks and labels. */
540 void
541 func_checker::parse_labels (sem_bb *bb)
543 for (gimple_stmt_iterator gsi = gsi_start_bb (bb->bb); !gsi_end_p (gsi);
544 gsi_next (&gsi))
546 gimple stmt = gsi_stmt (gsi);
548 if (glabel *label_stmt = dyn_cast <glabel *> (stmt))
550 tree t = gimple_label_label (label_stmt);
551 gcc_assert (TREE_CODE (t) == LABEL_DECL);
553 m_label_bb_map.put (t, bb->bb->index);
558 /* Basic block equivalence comparison function that returns true if
559 basic blocks BB1 and BB2 (from functions FUNC1 and FUNC2) correspond.
561 In general, a collection of equivalence dictionaries is built for types
562 like SSA names, declarations (VAR_DECL, PARM_DECL, ..). This infrastructure
563 is utilized by every statement-by-statement comparison function. */
565 bool
566 func_checker::compare_bb (sem_bb *bb1, sem_bb *bb2)
568 gimple_stmt_iterator gsi1, gsi2;
569 gimple s1, s2;
571 gsi1 = gsi_start_bb_nondebug (bb1->bb);
572 gsi2 = gsi_start_bb_nondebug (bb2->bb);
574 while (!gsi_end_p (gsi1))
576 if (gsi_end_p (gsi2))
577 return return_false ();
579 s1 = gsi_stmt (gsi1);
580 s2 = gsi_stmt (gsi2);
582 int eh1 = lookup_stmt_eh_lp_fn
583 (DECL_STRUCT_FUNCTION (m_source_func_decl), s1);
584 int eh2 = lookup_stmt_eh_lp_fn
585 (DECL_STRUCT_FUNCTION (m_target_func_decl), s2);
587 if (eh1 != eh2)
588 return return_false_with_msg ("EH regions are different");
590 if (gimple_code (s1) != gimple_code (s2))
591 return return_false_with_msg ("gimple codes are different");
593 switch (gimple_code (s1))
595 case GIMPLE_CALL:
596 if (!compare_gimple_call (as_a <gcall *> (s1),
597 as_a <gcall *> (s2)))
598 return return_different_stmts (s1, s2, "GIMPLE_CALL");
599 break;
600 case GIMPLE_ASSIGN:
601 if (!compare_gimple_assign (s1, s2))
602 return return_different_stmts (s1, s2, "GIMPLE_ASSIGN");
603 break;
604 case GIMPLE_COND:
605 if (!compare_gimple_cond (s1, s2))
606 return return_different_stmts (s1, s2, "GIMPLE_COND");
607 break;
608 case GIMPLE_SWITCH:
609 if (!compare_gimple_switch (as_a <gswitch *> (s1),
610 as_a <gswitch *> (s2)))
611 return return_different_stmts (s1, s2, "GIMPLE_SWITCH");
612 break;
613 case GIMPLE_DEBUG:
614 case GIMPLE_EH_DISPATCH:
615 break;
616 case GIMPLE_RESX:
617 if (!compare_gimple_resx (as_a <gresx *> (s1),
618 as_a <gresx *> (s2)))
619 return return_different_stmts (s1, s2, "GIMPLE_RESX");
620 break;
621 case GIMPLE_LABEL:
622 if (!compare_gimple_label (as_a <glabel *> (s1),
623 as_a <glabel *> (s2)))
624 return return_different_stmts (s1, s2, "GIMPLE_LABEL");
625 break;
626 case GIMPLE_RETURN:
627 if (!compare_gimple_return (as_a <greturn *> (s1),
628 as_a <greturn *> (s2)))
629 return return_different_stmts (s1, s2, "GIMPLE_RETURN");
630 break;
631 case GIMPLE_GOTO:
632 if (!compare_gimple_goto (s1, s2))
633 return return_different_stmts (s1, s2, "GIMPLE_GOTO");
634 break;
635 case GIMPLE_ASM:
636 if (!compare_gimple_asm (as_a <gasm *> (s1),
637 as_a <gasm *> (s2)))
638 return return_different_stmts (s1, s2, "GIMPLE_ASM");
639 break;
640 case GIMPLE_PREDICT:
641 case GIMPLE_NOP:
642 return true;
643 default:
644 return return_false_with_msg ("Unknown GIMPLE code reached");
647 gsi_next_nondebug (&gsi1);
648 gsi_next_nondebug (&gsi2);
651 if (!gsi_end_p (gsi2))
652 return return_false ();
654 return true;
657 /* Verifies for given GIMPLEs S1 and S2 that
658 call statements are semantically equivalent. */
660 bool
661 func_checker::compare_gimple_call (gcall *s1, gcall *s2)
663 unsigned i;
664 tree t1, t2;
666 if (gimple_call_num_args (s1) != gimple_call_num_args (s2))
667 return false;
669 t1 = gimple_call_fn (s1);
670 t2 = gimple_call_fn (s2);
671 if (!compare_operand (t1, t2))
672 return return_false ();
674 /* Compare flags. */
675 if (gimple_call_internal_p (s1) != gimple_call_internal_p (s2)
676 || gimple_call_ctrl_altering_p (s1) != gimple_call_ctrl_altering_p (s2)
677 || gimple_call_tail_p (s1) != gimple_call_tail_p (s2)
678 || gimple_call_return_slot_opt_p (s1) != gimple_call_return_slot_opt_p (s2)
679 || gimple_call_from_thunk_p (s1) != gimple_call_from_thunk_p (s2)
680 || gimple_call_va_arg_pack_p (s1) != gimple_call_va_arg_pack_p (s2)
681 || gimple_call_alloca_for_var_p (s1) != gimple_call_alloca_for_var_p (s2)
682 || gimple_call_with_bounds_p (s1) != gimple_call_with_bounds_p (s2))
683 return false;
685 if (gimple_call_internal_p (s1)
686 && gimple_call_internal_fn (s1) != gimple_call_internal_fn (s2))
687 return false;
689 tree fntype1 = gimple_call_fntype (s1);
690 tree fntype2 = gimple_call_fntype (s2);
691 if ((fntype1 && !fntype2)
692 || (!fntype1 && fntype2)
693 || (fntype1 && !types_compatible_p (fntype1, fntype2)))
694 return return_false_with_msg ("call function types are not compatible");
696 tree chain1 = gimple_call_chain (s1);
697 tree chain2 = gimple_call_chain (s2);
698 if ((chain1 && !chain2)
699 || (!chain1 && chain2)
700 || !compare_operand (chain1, chain2))
701 return return_false_with_msg ("static call chains are different");
703 /* Checking of argument. */
704 for (i = 0; i < gimple_call_num_args (s1); ++i)
706 t1 = gimple_call_arg (s1, i);
707 t2 = gimple_call_arg (s2, i);
709 if (!compare_operand (t1, t2))
710 return false;
713 /* Return value checking. */
714 t1 = gimple_get_lhs (s1);
715 t2 = gimple_get_lhs (s2);
717 return compare_operand (t1, t2);
721 /* Verifies for given GIMPLEs S1 and S2 that
722 assignment statements are semantically equivalent. */
724 bool
725 func_checker::compare_gimple_assign (gimple s1, gimple s2)
727 tree arg1, arg2;
728 tree_code code1, code2;
729 unsigned i;
731 code1 = gimple_expr_code (s1);
732 code2 = gimple_expr_code (s2);
734 if (code1 != code2)
735 return false;
737 code1 = gimple_assign_rhs_code (s1);
738 code2 = gimple_assign_rhs_code (s2);
740 if (code1 != code2)
741 return false;
743 for (i = 0; i < gimple_num_ops (s1); i++)
745 arg1 = gimple_op (s1, i);
746 arg2 = gimple_op (s2, i);
748 if (!compare_operand (arg1, arg2))
749 return false;
753 return true;
756 /* Verifies for given GIMPLEs S1 and S2 that
757 condition statements are semantically equivalent. */
759 bool
760 func_checker::compare_gimple_cond (gimple s1, gimple s2)
762 tree t1, t2;
763 tree_code code1, code2;
765 code1 = gimple_expr_code (s1);
766 code2 = gimple_expr_code (s2);
768 if (code1 != code2)
769 return false;
771 t1 = gimple_cond_lhs (s1);
772 t2 = gimple_cond_lhs (s2);
774 if (!compare_operand (t1, t2))
775 return false;
777 t1 = gimple_cond_rhs (s1);
778 t2 = gimple_cond_rhs (s2);
780 return compare_operand (t1, t2);
783 /* Verifies that tree labels T1 and T2 correspond in FUNC1 and FUNC2. */
785 bool
786 func_checker::compare_tree_ssa_label (tree t1, tree t2)
788 return compare_operand (t1, t2);
791 /* Verifies for given GIMPLE_LABEL stmts S1 and S2 that
792 label statements are semantically equivalent. */
794 bool
795 func_checker::compare_gimple_label (const glabel *g1, const glabel *g2)
797 if (m_ignore_labels)
798 return true;
800 tree t1 = gimple_label_label (g1);
801 tree t2 = gimple_label_label (g2);
803 if (FORCED_LABEL (t1) || FORCED_LABEL (t2))
804 return return_false_with_msg ("FORCED_LABEL");
806 /* As the pass build BB to label mapping, no further check is needed. */
807 return true;
810 /* Verifies for given GIMPLE_SWITCH stmts S1 and S2 that
811 switch statements are semantically equivalent. */
813 bool
814 func_checker::compare_gimple_switch (const gswitch *g1, const gswitch *g2)
816 unsigned lsize1, lsize2, i;
818 lsize1 = gimple_switch_num_labels (g1);
819 lsize2 = gimple_switch_num_labels (g2);
821 if (lsize1 != lsize2)
822 return false;
824 tree t1 = gimple_switch_index (g1);
825 tree t2 = gimple_switch_index (g2);
827 if (!compare_operand (t1, t2))
828 return false;
830 for (i = 0; i < lsize1; i++)
832 tree label1 = gimple_switch_label (g1, i);
833 tree label2 = gimple_switch_label (g2, i);
835 /* Label LOW and HIGH comparison. */
836 tree low1 = CASE_LOW (label1);
837 tree low2 = CASE_LOW (label2);
839 if (!tree_int_cst_equal (low1, low2))
840 return return_false_with_msg ("case low values are different");
842 tree high1 = CASE_HIGH (label1);
843 tree high2 = CASE_HIGH (label2);
845 if (!tree_int_cst_equal (high1, high2))
846 return return_false_with_msg ("case high values are different");
848 if (TREE_CODE (label1) == CASE_LABEL_EXPR
849 && TREE_CODE (label2) == CASE_LABEL_EXPR)
851 label1 = CASE_LABEL (label1);
852 label2 = CASE_LABEL (label2);
854 if (!compare_operand (label1, label2))
855 return return_false_with_msg ("switch label_exprs are different");
857 else if (!tree_int_cst_equal (label1, label2))
858 return return_false_with_msg ("switch labels are different");
861 return true;
864 /* Verifies for given GIMPLE_RETURN stmts S1 and S2 that
865 return statements are semantically equivalent. */
867 bool
868 func_checker::compare_gimple_return (const greturn *g1, const greturn *g2)
870 tree t1, t2;
872 t1 = gimple_return_retval (g1);
873 t2 = gimple_return_retval (g2);
875 /* Void return type. */
876 if (t1 == NULL && t2 == NULL)
877 return true;
878 else
879 return compare_operand (t1, t2);
882 /* Verifies for given GIMPLEs S1 and S2 that
883 goto statements are semantically equivalent. */
885 bool
886 func_checker::compare_gimple_goto (gimple g1, gimple g2)
888 tree dest1, dest2;
890 dest1 = gimple_goto_dest (g1);
891 dest2 = gimple_goto_dest (g2);
893 if (TREE_CODE (dest1) != TREE_CODE (dest2) || TREE_CODE (dest1) != SSA_NAME)
894 return false;
896 return compare_operand (dest1, dest2);
899 /* Verifies for given GIMPLE_RESX stmts S1 and S2 that
900 resx statements are semantically equivalent. */
902 bool
903 func_checker::compare_gimple_resx (const gresx *g1, const gresx *g2)
905 return gimple_resx_region (g1) == gimple_resx_region (g2);
908 /* Verifies for given GIMPLEs S1 and S2 that ASM statements are equivalent.
909 For the beginning, the pass only supports equality for
910 '__asm__ __volatile__ ("", "", "", "memory")'. */
912 bool
913 func_checker::compare_gimple_asm (const gasm *g1, const gasm *g2)
915 if (gimple_asm_volatile_p (g1) != gimple_asm_volatile_p (g2))
916 return false;
918 if (gimple_asm_ninputs (g1) != gimple_asm_ninputs (g2))
919 return false;
921 if (gimple_asm_noutputs (g1) != gimple_asm_noutputs (g2))
922 return false;
924 /* We do not suppport goto ASM statement comparison. */
925 if (gimple_asm_nlabels (g1) || gimple_asm_nlabels (g2))
926 return false;
928 if (gimple_asm_nclobbers (g1) != gimple_asm_nclobbers (g2))
929 return false;
931 if (strcmp (gimple_asm_string (g1), gimple_asm_string (g2)) != 0)
932 return return_false_with_msg ("ASM strings are different");
934 for (unsigned i = 0; i < gimple_asm_ninputs (g1); i++)
936 tree input1 = gimple_asm_input_op (g1, i);
937 tree input2 = gimple_asm_input_op (g2, i);
939 if (!compare_tree_list_operand (input1, input2))
940 return return_false_with_msg ("ASM input is different");
943 for (unsigned i = 0; i < gimple_asm_noutputs (g1); i++)
945 tree output1 = gimple_asm_output_op (g1, i);
946 tree output2 = gimple_asm_output_op (g2, i);
948 if (!compare_tree_list_operand (output1, output2))
949 return return_false_with_msg ("ASM output is different");
952 for (unsigned i = 0; i < gimple_asm_nclobbers (g1); i++)
954 tree clobber1 = gimple_asm_clobber_op (g1, i);
955 tree clobber2 = gimple_asm_clobber_op (g2, i);
957 if (!operand_equal_p (TREE_VALUE (clobber1), TREE_VALUE (clobber2),
958 OEP_ONLY_CONST))
959 return return_false_with_msg ("ASM clobber is different");
962 return true;
965 } // ipa_icf_gimple namespace