compiler: don't generate stubs for ambiguous direct interface methods
[official-gcc.git] / gcc / ipa-icf-gimple.cc
blobab398ca051cdf2bbeb3ea671a0597d83ff96ef4a
1 /* Interprocedural Identical Code Folding pass
2 Copyright (C) 2014-2022 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 "backend.h"
26 #include "rtl.h"
27 #include "tree.h"
28 #include "gimple.h"
29 #include "tree-pass.h"
30 #include "ssa.h"
31 #include "cgraph.h"
32 #include "data-streamer.h"
33 #include "gimple-pretty-print.h"
34 #include "fold-const.h"
35 #include "gimple-iterator.h"
36 #include "ipa-utils.h"
37 #include "tree-eh.h"
38 #include "builtins.h"
39 #include "cfgloop.h"
40 #include "attribs.h"
41 #include "gimple-walk.h"
43 #include "tree-ssa-alias-compare.h"
44 #include "ipa-icf-gimple.h"
46 namespace ipa_icf_gimple {
48 /* Initialize internal structures for a given SOURCE_FUNC_DECL and
49 TARGET_FUNC_DECL. Strict polymorphic comparison is processed if
50 an option COMPARE_POLYMORPHIC is true. For special cases, one can
51 set IGNORE_LABELS to skip label comparison.
52 Similarly, IGNORE_SOURCE_DECLS and IGNORE_TARGET_DECLS are sets
53 of declarations that can be skipped. */
55 func_checker::func_checker (tree source_func_decl, tree target_func_decl,
56 bool ignore_labels, bool tbaa,
57 hash_set<symtab_node *> *ignored_source_nodes,
58 hash_set<symtab_node *> *ignored_target_nodes)
59 : m_source_func_decl (source_func_decl), m_target_func_decl (target_func_decl),
60 m_ignored_source_nodes (ignored_source_nodes),
61 m_ignored_target_nodes (ignored_target_nodes),
62 m_ignore_labels (ignore_labels), m_tbaa (tbaa)
64 function *source_func = DECL_STRUCT_FUNCTION (source_func_decl);
65 function *target_func = DECL_STRUCT_FUNCTION (target_func_decl);
67 unsigned ssa_source = SSANAMES (source_func)->length ();
68 unsigned ssa_target = SSANAMES (target_func)->length ();
70 m_source_ssa_names.create (ssa_source);
71 m_target_ssa_names.create (ssa_target);
73 for (unsigned i = 0; i < ssa_source; i++)
74 m_source_ssa_names.safe_push (-1);
76 for (unsigned i = 0; i < ssa_target; i++)
77 m_target_ssa_names.safe_push (-1);
80 /* Memory release routine. */
82 func_checker::~func_checker ()
84 m_source_ssa_names.release();
85 m_target_ssa_names.release();
88 /* Verifies that trees T1 and T2 are equivalent from perspective of ICF. */
90 bool
91 func_checker::compare_ssa_name (const_tree t1, const_tree t2)
93 gcc_assert (TREE_CODE (t1) == SSA_NAME);
94 gcc_assert (TREE_CODE (t2) == SSA_NAME);
96 unsigned i1 = SSA_NAME_VERSION (t1);
97 unsigned i2 = SSA_NAME_VERSION (t2);
99 if (SSA_NAME_IS_DEFAULT_DEF (t1) != SSA_NAME_IS_DEFAULT_DEF (t2))
100 return false;
102 if (m_source_ssa_names[i1] == -1)
103 m_source_ssa_names[i1] = i2;
104 else if (m_source_ssa_names[i1] != (int) i2)
105 return false;
107 if(m_target_ssa_names[i2] == -1)
108 m_target_ssa_names[i2] = i1;
109 else if (m_target_ssa_names[i2] != (int) i1)
110 return false;
112 if (SSA_NAME_IS_DEFAULT_DEF (t1))
114 tree b1 = SSA_NAME_VAR (t1);
115 tree b2 = SSA_NAME_VAR (t2);
117 return compare_operand (b1, b2, OP_NORMAL);
120 return true;
123 /* Verification function for edges E1 and E2. */
125 bool
126 func_checker::compare_edge (edge e1, edge e2)
128 if (e1->flags != e2->flags)
129 return false;
131 bool existed_p;
133 edge &slot = m_edge_map.get_or_insert (e1, &existed_p);
134 if (existed_p)
135 return return_with_debug (slot == e2);
136 else
137 slot = e2;
139 /* TODO: filter edge probabilities for profile feedback match. */
141 return true;
144 /* Verification function for declaration trees T1 and T2 that
145 come from functions FUNC1 and FUNC2. */
147 bool
148 func_checker::compare_decl (const_tree t1, const_tree t2)
150 if (!auto_var_in_fn_p (t1, m_source_func_decl)
151 || !auto_var_in_fn_p (t2, m_target_func_decl))
152 return return_with_debug (t1 == t2);
154 tree_code t = TREE_CODE (t1);
155 if ((t == VAR_DECL || t == PARM_DECL || t == RESULT_DECL)
156 && DECL_BY_REFERENCE (t1) != DECL_BY_REFERENCE (t2))
157 return return_false_with_msg ("DECL_BY_REFERENCE flags are different");
159 /* We do not really need to check types of variables, since they are just
160 blocks of memory and we verify types of the accesses to them.
161 However do compare types of other kinds of decls
162 (parm decls and result decl types may affect ABI convetions). */
163 if (t != VAR_DECL)
165 if (!compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2)))
166 return return_false ();
168 else
170 if (!operand_equal_p (DECL_SIZE (t1), DECL_SIZE (t2),
171 OEP_MATCH_SIDE_EFFECTS))
172 return return_false_with_msg ("DECL_SIZEs are different");
175 bool existed_p;
176 const_tree &slot = m_decl_map.get_or_insert (t1, &existed_p);
177 if (existed_p)
178 return return_with_debug (slot == t2);
179 else
180 slot = t2;
182 return true;
185 /* Return true if T1 and T2 are same for purposes of ipa-polymorphic-call
186 analysis. COMPARE_PTR indicates if types of pointers needs to be
187 considered. */
189 bool
190 func_checker::compatible_polymorphic_types_p (tree t1, tree t2,
191 bool compare_ptr)
193 gcc_assert (TREE_CODE (t1) != FUNCTION_TYPE && TREE_CODE (t1) != METHOD_TYPE);
195 /* Pointer types generally give no information. */
196 if (POINTER_TYPE_P (t1))
198 if (!compare_ptr)
199 return true;
200 return func_checker::compatible_polymorphic_types_p (TREE_TYPE (t1),
201 TREE_TYPE (t2),
202 false);
205 /* If types contain a polymorphic types, match them. */
206 bool c1 = contains_polymorphic_type_p (t1);
207 bool c2 = contains_polymorphic_type_p (t2);
208 if (!c1 && !c2)
209 return true;
210 if (!c1 || !c2)
211 return return_false_with_msg ("one type is not polymorphic");
212 if (!types_must_be_same_for_odr (t1, t2))
213 return return_false_with_msg ("types are not same for ODR");
214 return true;
217 /* Return true if types are compatible from perspective of ICF. */
218 bool
219 func_checker::compatible_types_p (tree t1, tree t2)
221 if (TREE_CODE (t1) != TREE_CODE (t2))
222 return return_false_with_msg ("different tree types");
224 if (TYPE_RESTRICT (t1) != TYPE_RESTRICT (t2))
225 return return_false_with_msg ("restrict flags are different");
227 if (!types_compatible_p (t1, t2))
228 return return_false_with_msg ("types are not compatible");
230 return true;
233 /* Add hash of ARG to HSTATE. FLAGS have same meaning
234 as for operand_equal_p. Works only if operand acces type is OP_NORMAL. */
236 void
237 func_checker::hash_operand (const_tree arg, inchash::hash &hstate,
238 unsigned int flags)
240 if (arg == NULL_TREE)
242 hstate.merge_hash (0);
243 return;
246 switch (TREE_CODE (arg))
248 case PARM_DECL:
250 unsigned int index = 0;
251 if (DECL_CONTEXT (arg))
252 for (tree p = DECL_ARGUMENTS (DECL_CONTEXT (arg));
253 p && index < 32; p = DECL_CHAIN (p), index++)
254 if (p == arg)
255 break;
256 hstate.add_int (PARM_DECL);
257 hstate.add_int (index);
259 return;
260 case FUNCTION_DECL:
261 case VAR_DECL:
262 case LABEL_DECL:
263 case RESULT_DECL:
264 case CONST_DECL:
265 hstate.add_int (TREE_CODE (arg));
266 return;
267 case SSA_NAME:
268 hstate.add_int (SSA_NAME);
269 if (SSA_NAME_IS_DEFAULT_DEF (arg))
270 hash_operand (SSA_NAME_VAR (arg), hstate, flags);
271 return;
272 case FIELD_DECL:
273 inchash::add_expr (DECL_FIELD_OFFSET (arg), hstate, flags);
274 inchash::add_expr (DECL_FIELD_BIT_OFFSET (arg), hstate, flags);
275 return;
276 default:
277 break;
280 /* In gimple all clobbers can be considered equal: while comparaing two
281 gimple clobbers we match the left hand memory accesses. */
282 if (TREE_CLOBBER_P (arg))
284 hstate.add_int (0xc10bbe5);
285 return;
287 gcc_assert (!DECL_P (arg));
288 gcc_assert (!TYPE_P (arg));
290 return operand_compare::hash_operand (arg, hstate, flags);
293 /* Add hash of ARG accesses according to ACCESS to HSTATE.
294 FLAGS have same meaning as for operand_equal_p. */
296 void
297 func_checker::hash_operand (const_tree arg, inchash::hash &hstate,
298 unsigned int flags, operand_access_type access)
300 if (access == OP_MEMORY)
302 ao_ref ref;
303 ao_ref_init (&ref, const_cast <tree> (arg));
304 return hash_ao_ref (&ref, lto_streaming_expected_p (), m_tbaa, hstate);
306 else
307 return hash_operand (arg, hstate, flags);
310 bool
311 func_checker::operand_equal_p (const_tree t1, const_tree t2,
312 unsigned int flags)
314 bool r;
315 if (verify_hash_value (t1, t2, flags, &r))
316 return r;
318 if (t1 == t2)
319 return true;
320 else if (!t1 || !t2)
321 return false;
323 if (TREE_CODE (t1) != TREE_CODE (t2))
324 return return_false ();
326 switch (TREE_CODE (t1))
328 case FUNCTION_DECL:
329 /* All function decls are in the symbol table and known to match
330 before we start comparing bodies. */
331 return true;
332 case VAR_DECL:
333 return return_with_debug (compare_variable_decl (t1, t2));
334 case LABEL_DECL:
336 int *bb1 = m_label_bb_map.get (t1);
337 int *bb2 = m_label_bb_map.get (t2);
338 /* Labels can point to another function (non-local GOTOs). */
339 return return_with_debug (bb1 != NULL && bb2 != NULL && *bb1 == *bb2);
342 case PARM_DECL:
343 case RESULT_DECL:
344 case CONST_DECL:
345 return compare_decl (t1, t2);
346 case SSA_NAME:
347 return compare_ssa_name (t1, t2);
348 default:
349 break;
351 /* In gimple all clobbers can be considered equal. We match the left hand
352 memory accesses. */
353 if (TREE_CLOBBER_P (t1) || TREE_CLOBBER_P (t2))
354 return TREE_CLOBBER_P (t1) == TREE_CLOBBER_P (t2);
356 return operand_compare::operand_equal_p (t1, t2, flags);
359 /* Function responsible for comparison of various operands T1 and T2
360 which are accessed as ACCESS.
361 If these components, from functions FUNC1 and FUNC2, are equal, true
362 is returned. */
364 bool
365 func_checker::compare_operand (tree t1, tree t2, operand_access_type access)
367 if (!t1 && !t2)
368 return true;
369 else if (!t1 || !t2)
370 return false;
371 if (access == OP_MEMORY)
373 ao_ref ref1, ref2;
374 ao_ref_init (&ref1, const_cast <tree> (t1));
375 ao_ref_init (&ref2, const_cast <tree> (t2));
376 int flags = compare_ao_refs (&ref1, &ref2,
377 lto_streaming_expected_p (), m_tbaa);
379 if (!flags)
380 return true;
381 if (flags & SEMANTICS)
382 return return_false_with_msg
383 ("compare_ao_refs failed (semantic difference)");
384 if (flags & BASE_ALIAS_SET)
385 return return_false_with_msg
386 ("compare_ao_refs failed (base alias set difference)");
387 if (flags & REF_ALIAS_SET)
388 return return_false_with_msg
389 ("compare_ao_refs failed (ref alias set difference)");
390 if (flags & ACCESS_PATH)
391 return return_false_with_msg
392 ("compare_ao_refs failed (access path difference)");
393 if (flags & DEPENDENCE_CLIQUE)
394 return return_false_with_msg
395 ("compare_ao_refs failed (dependence clique difference)");
396 gcc_unreachable ();
398 else
400 if (operand_equal_p (t1, t2, OEP_MATCH_SIDE_EFFECTS))
401 return true;
402 return return_false_with_msg
403 ("operand_equal_p failed");
407 bool
408 func_checker::compare_asm_inputs_outputs (tree t1, tree t2,
409 operand_access_type_map *map)
411 gcc_assert (TREE_CODE (t1) == TREE_LIST);
412 gcc_assert (TREE_CODE (t2) == TREE_LIST);
414 for (; t1; t1 = TREE_CHAIN (t1))
416 if (!t2)
417 return false;
419 if (!compare_operand (TREE_VALUE (t1), TREE_VALUE (t2),
420 get_operand_access_type (map, t1)))
421 return return_false ();
423 tree p1 = TREE_PURPOSE (t1);
424 tree p2 = TREE_PURPOSE (t2);
426 gcc_assert (TREE_CODE (p1) == TREE_LIST);
427 gcc_assert (TREE_CODE (p2) == TREE_LIST);
429 if (strcmp (TREE_STRING_POINTER (TREE_VALUE (p1)),
430 TREE_STRING_POINTER (TREE_VALUE (p2))) != 0)
431 return return_false ();
433 t2 = TREE_CHAIN (t2);
436 if (t2)
437 return return_false ();
439 return true;
442 /* Verifies that trees T1 and T2 do correspond. */
444 bool
445 func_checker::compare_variable_decl (const_tree t1, const_tree t2)
447 bool ret = false;
449 if (t1 == t2)
450 return true;
452 if (DECL_ALIGN (t1) != DECL_ALIGN (t2))
453 return return_false_with_msg ("alignments are different");
455 if (DECL_HARD_REGISTER (t1) != DECL_HARD_REGISTER (t2))
456 return return_false_with_msg ("DECL_HARD_REGISTER are different");
458 if (DECL_HARD_REGISTER (t1)
459 && DECL_ASSEMBLER_NAME_RAW (t1) != DECL_ASSEMBLER_NAME_RAW (t2))
460 return return_false_with_msg ("HARD REGISTERS are different");
462 /* Symbol table variables are known to match before we start comparing
463 bodies. */
464 if (decl_in_symtab_p (t1))
465 return decl_in_symtab_p (t2);
466 ret = compare_decl (t1, t2);
468 return return_with_debug (ret);
471 /* Compare loop information for basic blocks BB1 and BB2. */
473 bool
474 func_checker::compare_loops (basic_block bb1, basic_block bb2)
476 if ((bb1->loop_father == NULL) != (bb2->loop_father == NULL))
477 return return_false ();
479 class loop *l1 = bb1->loop_father;
480 class loop *l2 = bb2->loop_father;
481 if (l1 == NULL)
482 return true;
484 if ((bb1 == l1->header) != (bb2 == l2->header))
485 return return_false_with_msg ("header");
486 if ((bb1 == l1->latch) != (bb2 == l2->latch))
487 return return_false_with_msg ("latch");
488 if (l1->simdlen != l2->simdlen)
489 return return_false_with_msg ("simdlen");
490 if (l1->safelen != l2->safelen)
491 return return_false_with_msg ("safelen");
492 if (l1->can_be_parallel != l2->can_be_parallel)
493 return return_false_with_msg ("can_be_parallel");
494 if (l1->dont_vectorize != l2->dont_vectorize)
495 return return_false_with_msg ("dont_vectorize");
496 if (l1->force_vectorize != l2->force_vectorize)
497 return return_false_with_msg ("force_vectorize");
498 if (l1->finite_p != l2->finite_p)
499 return return_false_with_msg ("finite_p");
500 if (l1->unroll != l2->unroll)
501 return return_false_with_msg ("unroll");
502 if (!compare_variable_decl (l1->simduid, l2->simduid))
503 return return_false_with_msg ("simduid");
505 return true;
508 /* Function visits all gimple labels and creates corresponding
509 mapping between basic blocks and labels. */
511 void
512 func_checker::parse_labels (sem_bb *bb)
514 for (gimple_stmt_iterator gsi = gsi_start_bb (bb->bb); !gsi_end_p (gsi);
515 gsi_next (&gsi))
517 gimple *stmt = gsi_stmt (gsi);
519 if (glabel *label_stmt = dyn_cast <glabel *> (stmt))
521 const_tree t = gimple_label_label (label_stmt);
522 gcc_assert (TREE_CODE (t) == LABEL_DECL);
524 m_label_bb_map.put (t, bb->bb->index);
529 /* Basic block equivalence comparison function that returns true if
530 basic blocks BB1 and BB2 (from functions FUNC1 and FUNC2) correspond.
532 In general, a collection of equivalence dictionaries is built for types
533 like SSA names, declarations (VAR_DECL, PARM_DECL, ..). This infrastructure
534 is utilized by every statement-by-statement comparison function. */
536 bool
537 func_checker::compare_bb (sem_bb *bb1, sem_bb *bb2)
539 gimple_stmt_iterator gsi1, gsi2;
540 gimple *s1, *s2;
542 gsi1 = gsi_start_nondebug_bb (bb1->bb);
543 gsi2 = gsi_start_nondebug_bb (bb2->bb);
545 while (!gsi_end_p (gsi1))
547 if (gsi_end_p (gsi2))
548 return return_false ();
550 s1 = gsi_stmt (gsi1);
551 s2 = gsi_stmt (gsi2);
553 int eh1 = lookup_stmt_eh_lp_fn
554 (DECL_STRUCT_FUNCTION (m_source_func_decl), s1);
555 int eh2 = lookup_stmt_eh_lp_fn
556 (DECL_STRUCT_FUNCTION (m_target_func_decl), s2);
558 if (eh1 != eh2)
559 return return_false_with_msg ("EH regions are different");
561 if (gimple_code (s1) != gimple_code (s2))
562 return return_false_with_msg ("gimple codes are different");
564 switch (gimple_code (s1))
566 case GIMPLE_CALL:
567 if (!compare_gimple_call (as_a <gcall *> (s1),
568 as_a <gcall *> (s2)))
569 return return_different_stmts (s1, s2, "GIMPLE_CALL");
570 break;
571 case GIMPLE_ASSIGN:
572 if (!compare_gimple_assign (s1, s2))
573 return return_different_stmts (s1, s2, "GIMPLE_ASSIGN");
574 break;
575 case GIMPLE_COND:
576 if (!compare_gimple_cond (s1, s2))
577 return return_different_stmts (s1, s2, "GIMPLE_COND");
578 break;
579 case GIMPLE_SWITCH:
580 if (!compare_gimple_switch (as_a <gswitch *> (s1),
581 as_a <gswitch *> (s2)))
582 return return_different_stmts (s1, s2, "GIMPLE_SWITCH");
583 break;
584 case GIMPLE_DEBUG:
585 break;
586 case GIMPLE_EH_DISPATCH:
587 if (gimple_eh_dispatch_region (as_a <geh_dispatch *> (s1))
588 != gimple_eh_dispatch_region (as_a <geh_dispatch *> (s2)))
589 return return_different_stmts (s1, s2, "GIMPLE_EH_DISPATCH");
590 break;
591 case GIMPLE_RESX:
592 if (!compare_gimple_resx (as_a <gresx *> (s1),
593 as_a <gresx *> (s2)))
594 return return_different_stmts (s1, s2, "GIMPLE_RESX");
595 break;
596 case GIMPLE_LABEL:
597 if (!compare_gimple_label (as_a <glabel *> (s1),
598 as_a <glabel *> (s2)))
599 return return_different_stmts (s1, s2, "GIMPLE_LABEL");
600 break;
601 case GIMPLE_RETURN:
602 if (!compare_gimple_return (as_a <greturn *> (s1),
603 as_a <greturn *> (s2)))
604 return return_different_stmts (s1, s2, "GIMPLE_RETURN");
605 break;
606 case GIMPLE_GOTO:
607 if (!compare_gimple_goto (s1, s2))
608 return return_different_stmts (s1, s2, "GIMPLE_GOTO");
609 break;
610 case GIMPLE_ASM:
611 if (!compare_gimple_asm (as_a <gasm *> (s1),
612 as_a <gasm *> (s2)))
613 return return_different_stmts (s1, s2, "GIMPLE_ASM");
614 break;
615 case GIMPLE_PREDICT:
616 case GIMPLE_NOP:
617 break;
618 default:
619 return return_false_with_msg ("Unknown GIMPLE code reached");
622 gsi_next_nondebug (&gsi1);
623 gsi_next_nondebug (&gsi2);
626 if (!gsi_end_p (gsi2))
627 return return_false ();
629 if (!compare_loops (bb1->bb, bb2->bb))
630 return return_false ();
632 return true;
635 /* Verifies for given GIMPLEs S1 and S2 that
636 call statements are semantically equivalent. */
638 bool
639 func_checker::compare_gimple_call (gcall *s1, gcall *s2)
641 unsigned i;
642 tree t1, t2;
644 if (gimple_call_num_args (s1) != gimple_call_num_args (s2))
645 return false;
647 operand_access_type_map map (5);
648 classify_operands (s1, &map);
650 t1 = gimple_call_fn (s1);
651 t2 = gimple_call_fn (s2);
652 if (!compare_operand (t1, t2, get_operand_access_type (&map, t1)))
653 return return_false ();
655 /* Compare flags. */
656 if (gimple_call_internal_p (s1) != gimple_call_internal_p (s2)
657 || gimple_call_ctrl_altering_p (s1) != gimple_call_ctrl_altering_p (s2)
658 || gimple_call_tail_p (s1) != gimple_call_tail_p (s2)
659 || gimple_call_return_slot_opt_p (s1) != gimple_call_return_slot_opt_p (s2)
660 || gimple_call_from_thunk_p (s1) != gimple_call_from_thunk_p (s2)
661 || gimple_call_from_new_or_delete (s1) != gimple_call_from_new_or_delete (s2)
662 || gimple_call_va_arg_pack_p (s1) != gimple_call_va_arg_pack_p (s2)
663 || gimple_call_alloca_for_var_p (s1) != gimple_call_alloca_for_var_p (s2))
664 return false;
666 if (gimple_call_internal_p (s1)
667 && gimple_call_internal_fn (s1) != gimple_call_internal_fn (s2))
668 return false;
670 tree fntype1 = gimple_call_fntype (s1);
671 tree fntype2 = gimple_call_fntype (s2);
673 /* For direct calls we verify that types are compatible so if we matched
674 callees, callers must match, too. For indirect calls however verify
675 function type. */
676 if (!gimple_call_fndecl (s1))
678 if ((fntype1 && !fntype2)
679 || (!fntype1 && fntype2)
680 || (fntype1 && !types_compatible_p (fntype1, fntype2)))
681 return return_false_with_msg ("call function types are not compatible");
684 if (fntype1 && fntype2 && comp_type_attributes (fntype1, fntype2) != 1)
685 return return_false_with_msg ("different fntype attributes");
687 tree chain1 = gimple_call_chain (s1);
688 tree chain2 = gimple_call_chain (s2);
689 if ((chain1 && !chain2)
690 || (!chain1 && chain2)
691 || !compare_operand (chain1, chain2,
692 get_operand_access_type (&map, chain1)))
693 return return_false_with_msg ("static call chains are different");
695 /* Checking of argument. */
696 for (i = 0; i < gimple_call_num_args (s1); ++i)
698 t1 = gimple_call_arg (s1, i);
699 t2 = gimple_call_arg (s2, i);
701 if (!compare_operand (t1, t2, get_operand_access_type (&map, t1)))
702 return return_false_with_msg ("GIMPLE call operands are different");
705 /* Return value checking. */
706 t1 = gimple_get_lhs (s1);
707 t2 = gimple_get_lhs (s2);
709 /* For internal calls, lhs types need to be verified, as neither fntype nor
710 callee comparisons can catch that. */
711 if (gimple_call_internal_p (s1)
712 && t1
713 && t2
714 && !compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2)))
715 return return_false_with_msg ("GIMPLE internal call LHS type mismatch");
717 return compare_operand (t1, t2, get_operand_access_type (&map, t1));
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_assign_rhs_code (s1);
732 code2 = gimple_assign_rhs_code (s2);
734 if (code1 != code2)
735 return false;
737 operand_access_type_map map (5);
738 classify_operands (s1, &map);
740 for (i = 0; i < gimple_num_ops (s1); i++)
742 arg1 = gimple_op (s1, i);
743 arg2 = gimple_op (s2, i);
745 /* Compare types for LHS. */
746 if (i == 0 && !gimple_store_p (s1))
748 if (!compatible_types_p (TREE_TYPE (arg1), TREE_TYPE (arg2)))
749 return return_false_with_msg ("GIMPLE LHS type mismatch");
752 if (!compare_operand (arg1, arg2, get_operand_access_type (&map, arg1)))
753 return return_false_with_msg ("GIMPLE assignment operands "
754 "are different");
758 return true;
761 /* Verifies for given GIMPLEs S1 and S2 that
762 condition statements are semantically equivalent. */
764 bool
765 func_checker::compare_gimple_cond (gimple *s1, gimple *s2)
767 tree t1, t2;
768 tree_code code1, code2;
770 code1 = gimple_cond_code (s1);
771 code2 = gimple_cond_code (s2);
773 if (code1 != code2)
774 return false;
776 t1 = gimple_cond_lhs (s1);
777 t2 = gimple_cond_lhs (s2);
779 if (!compare_operand (t1, t2, OP_NORMAL))
780 return false;
782 t1 = gimple_cond_rhs (s1);
783 t2 = gimple_cond_rhs (s2);
785 return compare_operand (t1, t2, OP_NORMAL);
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, OP_NORMAL))
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, OP_NORMAL))
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
877 operand_access_type_map map (3);
878 return compare_operand (t1, t2, get_operand_access_type (&map, t1));
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, OP_NORMAL);
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_input_p (g1) != gimple_asm_input_p (g2))
919 return false;
921 if (gimple_asm_inline_p (g1) != gimple_asm_inline_p (g2))
922 return false;
924 if (gimple_asm_ninputs (g1) != gimple_asm_ninputs (g2))
925 return false;
927 if (gimple_asm_noutputs (g1) != gimple_asm_noutputs (g2))
928 return false;
930 /* We do not suppport goto ASM statement comparison. */
931 if (gimple_asm_nlabels (g1) || gimple_asm_nlabels (g2))
932 return false;
934 if (gimple_asm_nclobbers (g1) != gimple_asm_nclobbers (g2))
935 return false;
937 if (strcmp (gimple_asm_string (g1), gimple_asm_string (g2)) != 0)
938 return return_false_with_msg ("ASM strings are different");
940 operand_access_type_map map (5);
941 classify_operands (g1, &map);
943 for (unsigned i = 0; i < gimple_asm_ninputs (g1); i++)
945 tree input1 = gimple_asm_input_op (g1, i);
946 tree input2 = gimple_asm_input_op (g2, i);
948 if (!compare_asm_inputs_outputs (input1, input2, &map))
949 return return_false_with_msg ("ASM input is different");
952 for (unsigned i = 0; i < gimple_asm_noutputs (g1); i++)
954 tree output1 = gimple_asm_output_op (g1, i);
955 tree output2 = gimple_asm_output_op (g2, i);
957 if (!compare_asm_inputs_outputs (output1, output2, &map))
958 return return_false_with_msg ("ASM output is different");
961 for (unsigned i = 0; i < gimple_asm_nclobbers (g1); i++)
963 tree clobber1 = gimple_asm_clobber_op (g1, i);
964 tree clobber2 = gimple_asm_clobber_op (g2, i);
966 if (!operand_equal_p (TREE_VALUE (clobber1), TREE_VALUE (clobber2),
967 OEP_ONLY_CONST))
968 return return_false_with_msg ("ASM clobber is different");
971 return true;
974 /* Helper for func_checker::classify_operands. Record that T is a load. */
976 static bool
977 visit_load_store (gimple *, tree, tree t, void *data)
979 func_checker::operand_access_type_map *map =
980 (func_checker::operand_access_type_map *) data;
981 map->add (t);
982 return false;
985 /* Compute hash map determining access types of operands. */
987 void
988 func_checker::classify_operands (const gimple *stmt,
989 operand_access_type_map *map)
991 walk_stmt_load_store_ops (const_cast <gimple *> (stmt),
992 (void *)map, visit_load_store, visit_load_store);
995 /* Return access type of a given operand. */
997 func_checker::operand_access_type
998 func_checker::get_operand_access_type (operand_access_type_map *map, tree t)
1000 if (map->contains (t))
1001 return OP_MEMORY;
1002 return OP_NORMAL;
1005 } // ipa_icf_gimple namespace