ggcplug.c: Shuffle includes to include gcc-plugin.h earlier.
[gcc.git] / gcc / ipa-icf-gimple.c
1 /* Interprocedural Identical Code Folding pass
2 Copyright (C) 2014 Free Software Foundation, Inc.
3
4 Contributed by Jan Hubicka <hubicka@ucw.cz> and Martin Liska <mliska@suse.cz>
5
6 This file is part of GCC.
7
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.
12
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.
17
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/>. */
21
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"
56
57 #include "ipa-icf-gimple.h"
58 #include "ipa-icf.h"
59
60 namespace ipa_icf_gimple {
61
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. */
68
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)
79 {
80 function *source_func = DECL_STRUCT_FUNCTION (source_func_decl);
81 function *target_func = DECL_STRUCT_FUNCTION (target_func_decl);
82
83 unsigned ssa_source = SSANAMES (source_func)->length ();
84 unsigned ssa_target = SSANAMES (target_func)->length ();
85
86 m_source_ssa_names.create (ssa_source);
87 m_target_ssa_names.create (ssa_target);
88
89 for (unsigned i = 0; i < ssa_source; i++)
90 m_source_ssa_names.safe_push (-1);
91
92 for (unsigned i = 0; i < ssa_target; i++)
93 m_target_ssa_names.safe_push (-1);
94 }
95
96 /* Memory release routine. */
97
98 func_checker::~func_checker ()
99 {
100 m_source_ssa_names.release();
101 m_target_ssa_names.release();
102 }
103
104 /* Verifies that trees T1 and T2 are equivalent from perspective of ICF. */
105
106 bool
107 func_checker::compare_ssa_name (tree t1, tree t2)
108 {
109 unsigned i1 = SSA_NAME_VERSION (t1);
110 unsigned i2 = SSA_NAME_VERSION (t2);
111
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;
116
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;
121
122 return true;
123 }
124
125 /* Verification function for edges E1 and E2. */
126
127 bool
128 func_checker::compare_edge (edge e1, edge e2)
129 {
130 if (e1->flags != e2->flags)
131 return false;
132
133 bool existed_p;
134
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;
140
141 /* TODO: filter edge probabilities for profile feedback match. */
142
143 return true;
144 }
145
146 /* Verification function for declaration trees T1 and T2 that
147 come from functions FUNC1 and FUNC2. */
148
149 bool
150 func_checker::compare_decl (tree t1, tree t2)
151 {
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);
155
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");
160
161 if (!compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2),
162 m_compare_polymorphic))
163 return return_false ();
164
165 bool existed_p;
166
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;
172
173 return true;
174 }
175
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)
180 {
181 if (TREE_CODE (t1) != TREE_CODE (t2))
182 return return_false_with_msg ("different tree types");
183
184 if (!types_compatible_p (t1, t2))
185 return return_false_with_msg ("types are not compatible");
186
187 if (get_alias_set (t1) != get_alias_set (t2))
188 return return_false_with_msg ("alias sets are different");
189
190 /* We call contains_polymorphic_type_p with this pointer type. */
191 if (first_argument && TREE_CODE (t1) == POINTER_TYPE)
192 {
193 t1 = TREE_TYPE (t1);
194 t2 = TREE_TYPE (t2);
195 }
196
197 if (compare_polymorphic)
198 if (contains_polymorphic_type_p (t1) || contains_polymorphic_type_p (t2))
199 {
200 if (!contains_polymorphic_type_p (t1) || !contains_polymorphic_type_p (t2))
201 return return_false_with_msg ("one type is not polymorphic");
202
203 if (!types_must_be_same_for_odr (t1, t2))
204 return return_false_with_msg ("types are not same for ODR");
205 }
206
207 return true;
208 }
209
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. */
213
214 bool
215 func_checker::compare_operand (tree t1, tree t2)
216 {
217 tree base1, base2, x1, x2, y1, y2, z1, z2;
218 HOST_WIDE_INT offset1 = 0, offset2 = 0;
219 bool ret;
220
221 if (!t1 && !t2)
222 return true;
223 else if (!t1 || !t2)
224 return false;
225
226 tree tt1 = TREE_TYPE (t1);
227 tree tt2 = TREE_TYPE (t2);
228
229 if (!func_checker::compatible_types_p (tt1, tt2))
230 return false;
231
232 base1 = get_addr_base_and_unit_offset (t1, &offset1);
233 base2 = get_addr_base_and_unit_offset (t2, &offset2);
234
235 if (base1 && base2)
236 {
237 if (offset1 != offset2)
238 return return_false_with_msg ("base offsets are different");
239
240 t1 = base1;
241 t2 = base2;
242 }
243
244 if (TREE_CODE (t1) != TREE_CODE (t2))
245 return return_false ();
246
247 switch (TREE_CODE (t1))
248 {
249 case CONSTRUCTOR:
250 {
251 unsigned length1 = vec_safe_length (CONSTRUCTOR_ELTS (t1));
252 unsigned length2 = vec_safe_length (CONSTRUCTOR_ELTS (t2));
253
254 if (length1 != length2)
255 return return_false ();
256
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();
261
262 return true;
263 }
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);
270
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:
281 {
282 x1 = TREE_OPERAND (t1, 0);
283 x2 = TREE_OPERAND (t2, 0);
284 y1 = TREE_OPERAND (t1, 1);
285 y2 = TREE_OPERAND (t2, 1);
286
287 /* See if operand is an memory access (the test originate from
288 gimple_load_p).
289
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. */
294
295 if (!func_checker::compatible_types_p (TREE_TYPE (x1), TREE_TYPE (x2)))
296 return return_false ();
297
298 if (!compare_operand (x1, x2))
299 return return_false_with_msg ("");
300
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");
303
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");
310
311 /* Type of the offset on MEM_REF does not matter. */
312 return wi::to_offset (y1) == wi::to_offset (y2);
313 }
314 case COMPONENT_REF:
315 {
316 x1 = TREE_OPERAND (t1, 0);
317 x2 = TREE_OPERAND (t2, 0);
318 y1 = TREE_OPERAND (t1, 1);
319 y2 = TREE_OPERAND (t2, 1);
320
321 ret = compare_operand (x1, x2)
322 && compare_operand (y1, y2);
323
324 return return_with_debug (ret);
325 }
326 /* Virtual table call. */
327 case OBJ_TYPE_REF:
328 {
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);
335
336 ret = compare_operand (x1, x2)
337 && compare_operand (y1, y2)
338 && compare_operand (z1, z2);
339
340 return return_with_debug (ret);
341 }
342 case ADDR_EXPR:
343 {
344 x1 = TREE_OPERAND (t1, 0);
345 x2 = TREE_OPERAND (t2, 0);
346
347 ret = compare_operand (x1, x2);
348 return return_with_debug (ret);
349 }
350 case SSA_NAME:
351 {
352 ret = compare_ssa_name (t1, t2);
353
354 if (!ret)
355 return return_with_debug (ret);
356
357 if (SSA_NAME_IS_DEFAULT_DEF (t1))
358 {
359 tree b1 = SSA_NAME_VAR (t1);
360 tree b2 = SSA_NAME_VAR (t2);
361
362 if (b1 == NULL && b2 == NULL)
363 return true;
364
365 if (b1 == NULL || b2 == NULL || TREE_CODE (b1) != TREE_CODE (b2))
366 return return_false ();
367
368 switch (TREE_CODE (b1))
369 {
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");
378 }
379 }
380 else
381 return true;
382 }
383 case INTEGER_CST:
384 {
385 ret = compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2))
386 && wi::to_offset (t1) == wi::to_offset (t2);
387
388 return return_with_debug (ret);
389 }
390 case COMPLEX_CST:
391 case VECTOR_CST:
392 case STRING_CST:
393 case REAL_CST:
394 {
395 ret = operand_equal_p (t1, t2, OEP_ONLY_CONST);
396 return return_with_debug (ret);
397 }
398 case FUNCTION_DECL:
399 {
400 ret = compare_function_decl (t1, t2);
401 return return_with_debug (ret);
402 }
403 case VAR_DECL:
404 return return_with_debug (compare_variable_decl (t1, t2));
405 case FIELD_DECL:
406 {
407 tree offset1 = DECL_FIELD_OFFSET (t1);
408 tree offset2 = DECL_FIELD_OFFSET (t2);
409
410 tree bit_offset1 = DECL_FIELD_BIT_OFFSET (t1);
411 tree bit_offset2 = DECL_FIELD_BIT_OFFSET (t2);
412
413 ret = compare_operand (offset1, offset2)
414 && compare_operand (bit_offset1, bit_offset2);
415
416 return return_with_debug (ret);
417 }
418 case LABEL_DECL:
419 {
420 int *bb1 = m_label_bb_map.get (t1);
421 int *bb2 = m_label_bb_map.get (t2);
422
423 return return_with_debug (*bb1 == *bb2);
424 }
425 case PARM_DECL:
426 case RESULT_DECL:
427 case CONST_DECL:
428 case BIT_FIELD_REF:
429 {
430 ret = compare_decl (t1, t2);
431 return return_with_debug (ret);
432 }
433 default:
434 return return_false_with_msg ("Unknown TREE code reached");
435 }
436 }
437
438 /* Compares two tree list operands T1 and T2 and returns true if these
439 two trees are semantically equivalent. */
440
441 bool
442 func_checker::compare_tree_list_operand (tree t1, tree t2)
443 {
444 gcc_assert (TREE_CODE (t1) == TREE_LIST);
445 gcc_assert (TREE_CODE (t2) == TREE_LIST);
446
447 for (; t1; t1 = TREE_CHAIN (t1))
448 {
449 if (!t2)
450 return false;
451
452 if (!compare_operand (TREE_VALUE (t1), TREE_VALUE (t2)))
453 return return_false ();
454
455 t2 = TREE_CHAIN (t2);
456 }
457
458 if (t2)
459 return return_false ();
460
461 return true;
462 }
463
464 /* Verifies that trees T1 and T2, representing function declarations
465 are equivalent from perspective of ICF. */
466
467 bool
468 func_checker::compare_function_decl (tree t1, tree t2)
469 {
470 bool ret = false;
471
472 if (t1 == t2)
473 return true;
474
475 symtab_node *n1 = symtab_node::get (t1);
476 symtab_node *n2 = symtab_node::get (t2);
477
478 if (m_ignored_source_nodes != NULL && m_ignored_target_nodes != NULL)
479 {
480 ret = m_ignored_source_nodes->contains (n1)
481 && m_ignored_target_nodes->contains (n2);
482
483 if (ret)
484 return true;
485 }
486
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);
490
491 if(f1 && f2 && f1->weakref && f2->weakref)
492 ret = f1->alias_target == f2->alias_target;
493
494 return ret;
495 }
496
497 /* Verifies that trees T1 and T2 do correspond. */
498
499 bool
500 func_checker::compare_variable_decl (tree t1, tree t2)
501 {
502 bool ret = false;
503
504 if (t1 == t2)
505 return true;
506
507 if (TREE_CODE (t1) == VAR_DECL && (DECL_EXTERNAL (t1) || TREE_STATIC (t1)))
508 {
509 symtab_node *n1 = symtab_node::get (t1);
510 symtab_node *n2 = symtab_node::get (t2);
511
512 if (m_ignored_source_nodes != NULL && m_ignored_target_nodes != NULL)
513 {
514 ret = m_ignored_source_nodes->contains (n1)
515 && m_ignored_target_nodes->contains (n2);
516
517 if (ret)
518 return true;
519 }
520 }
521 ret = compare_decl (t1, t2);
522
523 return return_with_debug (ret);
524 }
525
526 void
527 func_checker::parse_labels (sem_bb *bb)
528 {
529 for (gimple_stmt_iterator gsi = gsi_start_bb (bb->bb); !gsi_end_p (gsi);
530 gsi_next (&gsi))
531 {
532 gimple stmt = gsi_stmt (gsi);
533
534 if (gimple_code (stmt) == GIMPLE_LABEL)
535 {
536 tree t = gimple_label_label (stmt);
537 gcc_assert (TREE_CODE (t) == LABEL_DECL);
538
539 m_label_bb_map.put (t, bb->bb->index);
540 }
541 }
542 }
543
544 /* Basic block equivalence comparison function that returns true if
545 basic blocks BB1 and BB2 (from functions FUNC1 and FUNC2) correspond.
546
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. */
550
551 bool
552 func_checker::compare_bb (sem_bb *bb1, sem_bb *bb2)
553 {
554 unsigned i;
555 gimple_stmt_iterator gsi1, gsi2;
556 gimple s1, s2;
557
558 if (bb1->nondbg_stmt_count != bb2->nondbg_stmt_count
559 || bb1->edge_count != bb2->edge_count)
560 return return_false ();
561
562 gsi1 = gsi_start_bb (bb1->bb);
563 gsi2 = gsi_start_bb (bb2->bb);
564
565 for (i = 0; i < bb1->nondbg_stmt_count; i++)
566 {
567 if (is_gimple_debug (gsi_stmt (gsi1)))
568 gsi_next_nondebug (&gsi1);
569
570 if (is_gimple_debug (gsi_stmt (gsi2)))
571 gsi_next_nondebug (&gsi2);
572
573 s1 = gsi_stmt (gsi1);
574 s2 = gsi_stmt (gsi2);
575
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);
580
581 if (eh1 != eh2)
582 return return_false_with_msg ("EH regions are different");
583
584 if (gimple_code (s1) != gimple_code (s2))
585 return return_false_with_msg ("gimple codes are different");
586
587 switch (gimple_code (s1))
588 {
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 (s1, s2))
603 return return_different_stmts (s1, s2, "GIMPLE_SWITCH");
604 break;
605 case GIMPLE_DEBUG:
606 case GIMPLE_EH_DISPATCH:
607 break;
608 case GIMPLE_RESX:
609 if (!compare_gimple_resx (s1, s2))
610 return return_different_stmts (s1, s2, "GIMPLE_RESX");
611 break;
612 case GIMPLE_LABEL:
613 if (!compare_gimple_label (s1, s2))
614 return return_different_stmts (s1, s2, "GIMPLE_LABEL");
615 break;
616 case GIMPLE_RETURN:
617 if (!compare_gimple_return (s1, s2))
618 return return_different_stmts (s1, s2, "GIMPLE_RETURN");
619 break;
620 case GIMPLE_GOTO:
621 if (!compare_gimple_goto (s1, s2))
622 return return_different_stmts (s1, s2, "GIMPLE_GOTO");
623 break;
624 case GIMPLE_ASM:
625 if (!compare_gimple_asm (s1, s2))
626 return return_different_stmts (s1, s2, "GIMPLE_ASM");
627 break;
628 case GIMPLE_PREDICT:
629 case GIMPLE_NOP:
630 return true;
631 default:
632 return return_false_with_msg ("Unknown GIMPLE code reached");
633 }
634
635 gsi_next (&gsi1);
636 gsi_next (&gsi2);
637 }
638
639 return true;
640 }
641
642 /* Verifies for given GIMPLEs S1 and S2 that
643 call statements are semantically equivalent. */
644
645 bool
646 func_checker::compare_gimple_call (gimple s1, gimple s2)
647 {
648 unsigned i;
649 tree t1, t2;
650
651 if (gimple_call_num_args (s1) != gimple_call_num_args (s2))
652 return false;
653
654 t1 = gimple_call_fndecl (s1);
655 t2 = gimple_call_fndecl (s2);
656
657 /* Function pointer variables are not supported yet. */
658 if (!compare_operand (t1, t2))
659 return return_false();
660
661 /* Checking of argument. */
662 for (i = 0; i < gimple_call_num_args (s1); ++i)
663 {
664 t1 = gimple_call_arg (s1, i);
665 t2 = gimple_call_arg (s2, i);
666
667 if (!compare_operand (t1, t2))
668 return false;
669 }
670
671 /* Return value checking. */
672 t1 = gimple_get_lhs (s1);
673 t2 = gimple_get_lhs (s2);
674
675 return compare_operand (t1, t2);
676 }
677
678
679 /* Verifies for given GIMPLEs S1 and S2 that
680 assignment statements are semantically equivalent. */
681
682 bool
683 func_checker::compare_gimple_assign (gimple s1, gimple s2)
684 {
685 tree arg1, arg2;
686 tree_code code1, code2;
687 unsigned i;
688
689 code1 = gimple_expr_code (s1);
690 code2 = gimple_expr_code (s2);
691
692 if (code1 != code2)
693 return false;
694
695 code1 = gimple_assign_rhs_code (s1);
696 code2 = gimple_assign_rhs_code (s2);
697
698 if (code1 != code2)
699 return false;
700
701 for (i = 0; i < gimple_num_ops (s1); i++)
702 {
703 arg1 = gimple_op (s1, i);
704 arg2 = gimple_op (s2, i);
705
706 if (!compare_operand (arg1, arg2))
707 return false;
708 }
709
710
711 return true;
712 }
713
714 /* Verifies for given GIMPLEs S1 and S2 that
715 condition statements are semantically equivalent. */
716
717 bool
718 func_checker::compare_gimple_cond (gimple s1, gimple s2)
719 {
720 tree t1, t2;
721 tree_code code1, code2;
722
723 code1 = gimple_expr_code (s1);
724 code2 = gimple_expr_code (s2);
725
726 if (code1 != code2)
727 return false;
728
729 t1 = gimple_cond_lhs (s1);
730 t2 = gimple_cond_lhs (s2);
731
732 if (!compare_operand (t1, t2))
733 return false;
734
735 t1 = gimple_cond_rhs (s1);
736 t2 = gimple_cond_rhs (s2);
737
738 return compare_operand (t1, t2);
739 }
740
741 /* Verifies that tree labels T1 and T2 correspond in FUNC1 and FUNC2. */
742
743 bool
744 func_checker::compare_tree_ssa_label (tree t1, tree t2)
745 {
746 return compare_operand (t1, t2);
747 }
748
749 /* Verifies for given GIMPLEs S1 and S2 that
750 label statements are semantically equivalent. */
751
752 bool
753 func_checker::compare_gimple_label (gimple g1, gimple g2)
754 {
755 if (m_ignore_labels)
756 return true;
757
758 tree t1 = gimple_label_label (g1);
759 tree t2 = gimple_label_label (g2);
760
761 if (FORCED_LABEL (t1) || FORCED_LABEL (t2))
762 return return_false_with_msg ("FORCED_LABEL");
763
764 return compare_tree_ssa_label (t1, t2);
765 }
766
767 /* Verifies for given GIMPLEs S1 and S2 that
768 switch statements are semantically equivalent. */
769
770 bool
771 func_checker::compare_gimple_switch (gimple g1, gimple g2)
772 {
773 unsigned lsize1, lsize2, i;
774
775 lsize1 = gimple_switch_num_labels (g1);
776 lsize2 = gimple_switch_num_labels (g2);
777
778 if (lsize1 != lsize2)
779 return false;
780
781 tree t1 = gimple_switch_index (g1);
782 tree t2 = gimple_switch_index (g2);
783
784 if (!compare_operand (t1, t2))
785 return false;
786
787 for (i = 0; i < lsize1; i++)
788 {
789 tree label1 = gimple_switch_label (g1, i);
790 tree label2 = gimple_switch_label (g2, i);
791
792 if (TREE_CODE (label1) == CASE_LABEL_EXPR
793 && TREE_CODE (label2) == CASE_LABEL_EXPR)
794 {
795 label1 = CASE_LABEL (label1);
796 label2 = CASE_LABEL (label2);
797
798 if (!compare_operand (label1, label2))
799 return return_false_with_msg ("switch label_exprs are different");
800 }
801 else if (!tree_int_cst_equal (label1, label2))
802 return return_false_with_msg ("switch labels are different");
803 }
804
805 return true;
806 }
807
808 /* Verifies for given GIMPLEs S1 and S2 that
809 return statements are semantically equivalent. */
810
811 bool
812 func_checker::compare_gimple_return (gimple g1, gimple g2)
813 {
814 tree t1, t2;
815
816 t1 = gimple_return_retval (g1);
817 t2 = gimple_return_retval (g2);
818
819 /* Void return type. */
820 if (t1 == NULL && t2 == NULL)
821 return true;
822 else
823 return compare_operand (t1, t2);
824 }
825
826 /* Verifies for given GIMPLEs S1 and S2 that
827 goto statements are semantically equivalent. */
828
829 bool
830 func_checker::compare_gimple_goto (gimple g1, gimple g2)
831 {
832 tree dest1, dest2;
833
834 dest1 = gimple_goto_dest (g1);
835 dest2 = gimple_goto_dest (g2);
836
837 if (TREE_CODE (dest1) != TREE_CODE (dest2) || TREE_CODE (dest1) != SSA_NAME)
838 return false;
839
840 return compare_operand (dest1, dest2);
841 }
842
843 /* Verifies for given GIMPLEs S1 and S2 that
844 resx statements are semantically equivalent. */
845
846 bool
847 func_checker::compare_gimple_resx (gimple g1, gimple g2)
848 {
849 return gimple_resx_region (g1) == gimple_resx_region (g2);
850 }
851
852 /* Verifies for given GIMPLEs S1 and S2 that ASM statements are equivalent.
853 For the beginning, the pass only supports equality for
854 '__asm__ __volatile__ ("", "", "", "memory")'. */
855
856 bool
857 func_checker::compare_gimple_asm (gimple g1, gimple g2)
858 {
859 if (gimple_asm_volatile_p (g1) != gimple_asm_volatile_p (g2))
860 return false;
861
862 if (gimple_asm_ninputs (g1) != gimple_asm_ninputs (g2))
863 return false;
864
865 if (gimple_asm_noutputs (g1) != gimple_asm_noutputs (g2))
866 return false;
867
868 /* We do not suppport goto ASM statement comparison. */
869 if (gimple_asm_nlabels (g1) || gimple_asm_nlabels (g2))
870 return false;
871
872 if (gimple_asm_nclobbers (g1) != gimple_asm_nclobbers (g2))
873 return false;
874
875 if (strcmp (gimple_asm_string (g1), gimple_asm_string (g2)) != 0)
876 return return_false_with_msg ("ASM strings are different");
877
878 for (unsigned i = 0; i < gimple_asm_ninputs (g1); i++)
879 {
880 tree input1 = gimple_asm_input_op (g1, i);
881 tree input2 = gimple_asm_input_op (g2, i);
882
883 if (!compare_tree_list_operand (input1, input2))
884 return return_false_with_msg ("ASM input is different");
885 }
886
887 for (unsigned i = 0; i < gimple_asm_noutputs (g1); i++)
888 {
889 tree output1 = gimple_asm_output_op (g1, i);
890 tree output2 = gimple_asm_output_op (g2, i);
891
892 if (!compare_tree_list_operand (output1, output2))
893 return return_false_with_msg ("ASM output is different");
894 }
895
896 for (unsigned i = 0; i < gimple_asm_nclobbers (g1); i++)
897 {
898 tree clobber1 = gimple_asm_clobber_op (g1, i);
899 tree clobber2 = gimple_asm_clobber_op (g2, i);
900
901 if (!operand_equal_p (TREE_VALUE (clobber1), TREE_VALUE (clobber2),
902 OEP_ONLY_CONST))
903 return return_false_with_msg ("ASM clobber is different");
904 }
905
906 return true;
907 }
908
909 } // ipa_icf_gimple namespace