]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/ipa-icf-gimple.c
Merger of git branch "gimple-classes-v2-option-3"
[thirdparty/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 "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"
60
61 #include "ipa-icf-gimple.h"
62 #include "ipa-icf.h"
63
64 namespace ipa_icf_gimple {
65
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. */
72
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)
83 {
84 function *source_func = DECL_STRUCT_FUNCTION (source_func_decl);
85 function *target_func = DECL_STRUCT_FUNCTION (target_func_decl);
86
87 unsigned ssa_source = SSANAMES (source_func)->length ();
88 unsigned ssa_target = SSANAMES (target_func)->length ();
89
90 m_source_ssa_names.create (ssa_source);
91 m_target_ssa_names.create (ssa_target);
92
93 for (unsigned i = 0; i < ssa_source; i++)
94 m_source_ssa_names.safe_push (-1);
95
96 for (unsigned i = 0; i < ssa_target; i++)
97 m_target_ssa_names.safe_push (-1);
98 }
99
100 /* Memory release routine. */
101
102 func_checker::~func_checker ()
103 {
104 m_source_ssa_names.release();
105 m_target_ssa_names.release();
106 }
107
108 /* Verifies that trees T1 and T2 are equivalent from perspective of ICF. */
109
110 bool
111 func_checker::compare_ssa_name (tree t1, tree t2)
112 {
113 unsigned i1 = SSA_NAME_VERSION (t1);
114 unsigned i2 = SSA_NAME_VERSION (t2);
115
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;
120
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;
125
126 return true;
127 }
128
129 /* Verification function for edges E1 and E2. */
130
131 bool
132 func_checker::compare_edge (edge e1, edge e2)
133 {
134 if (e1->flags != e2->flags)
135 return false;
136
137 bool existed_p;
138
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;
144
145 /* TODO: filter edge probabilities for profile feedback match. */
146
147 return true;
148 }
149
150 /* Verification function for declaration trees T1 and T2 that
151 come from functions FUNC1 and FUNC2. */
152
153 bool
154 func_checker::compare_decl (tree t1, tree t2)
155 {
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);
159
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");
164
165 if (!compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2),
166 m_compare_polymorphic))
167 return return_false ();
168
169 bool existed_p;
170
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;
176
177 return true;
178 }
179
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)
184 {
185 if (TREE_CODE (t1) != TREE_CODE (t2))
186 return return_false_with_msg ("different tree types");
187
188 if (!types_compatible_p (t1, t2))
189 return return_false_with_msg ("types are not compatible");
190
191 if (get_alias_set (t1) != get_alias_set (t2))
192 return return_false_with_msg ("alias sets are different");
193
194 /* We call contains_polymorphic_type_p with this pointer type. */
195 if (first_argument && TREE_CODE (t1) == POINTER_TYPE)
196 {
197 t1 = TREE_TYPE (t1);
198 t2 = TREE_TYPE (t2);
199 }
200
201 if (compare_polymorphic)
202 if (contains_polymorphic_type_p (t1) || contains_polymorphic_type_p (t2))
203 {
204 if (!contains_polymorphic_type_p (t1) || !contains_polymorphic_type_p (t2))
205 return return_false_with_msg ("one type is not polymorphic");
206
207 if (!types_must_be_same_for_odr (t1, t2))
208 return return_false_with_msg ("types are not same for ODR");
209 }
210
211 return true;
212 }
213
214 /* Function responsible for comparison of handled components T1 and T2.
215 If these components, from functions FUNC1 and FUNC2, are equal, true
216 is returned. */
217
218 bool
219 func_checker::compare_operand (tree t1, tree t2)
220 {
221 tree base1, base2, x1, x2, y1, y2, z1, z2;
222 HOST_WIDE_INT offset1 = 0, offset2 = 0;
223 bool ret;
224
225 if (!t1 && !t2)
226 return true;
227 else if (!t1 || !t2)
228 return false;
229
230 tree tt1 = TREE_TYPE (t1);
231 tree tt2 = TREE_TYPE (t2);
232
233 if (!func_checker::compatible_types_p (tt1, tt2))
234 return false;
235
236 base1 = get_addr_base_and_unit_offset (t1, &offset1);
237 base2 = get_addr_base_and_unit_offset (t2, &offset2);
238
239 if (base1 && base2)
240 {
241 if (offset1 != offset2)
242 return return_false_with_msg ("base offsets are different");
243
244 t1 = base1;
245 t2 = base2;
246 }
247
248 if (TREE_CODE (t1) != TREE_CODE (t2))
249 return return_false ();
250
251 switch (TREE_CODE (t1))
252 {
253 case CONSTRUCTOR:
254 {
255 unsigned length1 = vec_safe_length (CONSTRUCTOR_ELTS (t1));
256 unsigned length2 = vec_safe_length (CONSTRUCTOR_ELTS (t2));
257
258 if (length1 != length2)
259 return return_false ();
260
261 for (unsigned i = 0; i < length1; i++)
262 if (!compare_operand (CONSTRUCTOR_ELT (t1, i)->value,
263 CONSTRUCTOR_ELT (t2, i)->value))
264 return return_false();
265
266 return true;
267 }
268 case ARRAY_REF:
269 case ARRAY_RANGE_REF:
270 x1 = TREE_OPERAND (t1, 0);
271 x2 = TREE_OPERAND (t2, 0);
272 y1 = TREE_OPERAND (t1, 1);
273 y2 = TREE_OPERAND (t2, 1);
274
275 if (!compare_operand (array_ref_low_bound (t1),
276 array_ref_low_bound (t2)))
277 return return_false_with_msg ("");
278 if (!compare_operand (array_ref_element_size (t1),
279 array_ref_element_size (t2)))
280 return return_false_with_msg ("");
281 if (!compare_operand (x1, x2))
282 return return_false_with_msg ("");
283 return compare_operand (y1, y2);
284 case MEM_REF:
285 {
286 x1 = TREE_OPERAND (t1, 0);
287 x2 = TREE_OPERAND (t2, 0);
288 y1 = TREE_OPERAND (t1, 1);
289 y2 = TREE_OPERAND (t2, 1);
290
291 /* See if operand is an memory access (the test originate from
292 gimple_load_p).
293
294 In this case the alias set of the function being replaced must
295 be subset of the alias set of the other function. At the moment
296 we seek for equivalency classes, so simply require inclussion in
297 both directions. */
298
299 if (!func_checker::compatible_types_p (TREE_TYPE (x1), TREE_TYPE (x2)))
300 return return_false ();
301
302 if (!compare_operand (x1, x2))
303 return return_false_with_msg ("");
304
305 if (get_alias_set (TREE_TYPE (y1)) != get_alias_set (TREE_TYPE (y2)))
306 return return_false_with_msg ("alias set for MEM_REF offsets are different");
307
308 ao_ref r1, r2;
309 ao_ref_init (&r1, t1);
310 ao_ref_init (&r2, t2);
311 if (ao_ref_alias_set (&r1) != ao_ref_alias_set (&r2)
312 || ao_ref_base_alias_set (&r1) != ao_ref_base_alias_set (&r2))
313 return return_false_with_msg ("ao alias sets are different");
314
315 /* Type of the offset on MEM_REF does not matter. */
316 return wi::to_offset (y1) == wi::to_offset (y2);
317 }
318 case COMPONENT_REF:
319 {
320 x1 = TREE_OPERAND (t1, 0);
321 x2 = TREE_OPERAND (t2, 0);
322 y1 = TREE_OPERAND (t1, 1);
323 y2 = TREE_OPERAND (t2, 1);
324
325 ret = compare_operand (x1, x2)
326 && compare_operand (y1, y2);
327
328 return return_with_debug (ret);
329 }
330 /* Virtual table call. */
331 case OBJ_TYPE_REF:
332 {
333 x1 = TREE_OPERAND (t1, 0);
334 x2 = TREE_OPERAND (t2, 0);
335 y1 = TREE_OPERAND (t1, 1);
336 y2 = TREE_OPERAND (t2, 1);
337 z1 = TREE_OPERAND (t1, 2);
338 z2 = TREE_OPERAND (t2, 2);
339
340 ret = compare_operand (x1, x2)
341 && compare_operand (y1, y2)
342 && compare_operand (z1, z2);
343
344 return return_with_debug (ret);
345 }
346 case ADDR_EXPR:
347 {
348 x1 = TREE_OPERAND (t1, 0);
349 x2 = TREE_OPERAND (t2, 0);
350
351 ret = compare_operand (x1, x2);
352 return return_with_debug (ret);
353 }
354 case SSA_NAME:
355 {
356 ret = compare_ssa_name (t1, t2);
357
358 if (!ret)
359 return return_with_debug (ret);
360
361 if (SSA_NAME_IS_DEFAULT_DEF (t1))
362 {
363 tree b1 = SSA_NAME_VAR (t1);
364 tree b2 = SSA_NAME_VAR (t2);
365
366 if (b1 == NULL && b2 == NULL)
367 return true;
368
369 if (b1 == NULL || b2 == NULL || TREE_CODE (b1) != TREE_CODE (b2))
370 return return_false ();
371
372 switch (TREE_CODE (b1))
373 {
374 case VAR_DECL:
375 return return_with_debug (compare_variable_decl (t1, t2));
376 case PARM_DECL:
377 case RESULT_DECL:
378 ret = compare_decl (b1, b2);
379 return return_with_debug (ret);
380 default:
381 return return_false_with_msg ("Unknown TREE code reached");
382 }
383 }
384 else
385 return true;
386 }
387 case INTEGER_CST:
388 {
389 ret = compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2))
390 && wi::to_offset (t1) == wi::to_offset (t2);
391
392 return return_with_debug (ret);
393 }
394 case COMPLEX_CST:
395 case VECTOR_CST:
396 case STRING_CST:
397 case REAL_CST:
398 {
399 ret = operand_equal_p (t1, t2, OEP_ONLY_CONST);
400 return return_with_debug (ret);
401 }
402 case FUNCTION_DECL:
403 {
404 ret = compare_function_decl (t1, t2);
405 return return_with_debug (ret);
406 }
407 case VAR_DECL:
408 return return_with_debug (compare_variable_decl (t1, t2));
409 case FIELD_DECL:
410 {
411 tree offset1 = DECL_FIELD_OFFSET (t1);
412 tree offset2 = DECL_FIELD_OFFSET (t2);
413
414 tree bit_offset1 = DECL_FIELD_BIT_OFFSET (t1);
415 tree bit_offset2 = DECL_FIELD_BIT_OFFSET (t2);
416
417 ret = compare_operand (offset1, offset2)
418 && compare_operand (bit_offset1, bit_offset2);
419
420 return return_with_debug (ret);
421 }
422 case LABEL_DECL:
423 {
424 int *bb1 = m_label_bb_map.get (t1);
425 int *bb2 = m_label_bb_map.get (t2);
426
427 return return_with_debug (*bb1 == *bb2);
428 }
429 case PARM_DECL:
430 case RESULT_DECL:
431 case CONST_DECL:
432 case BIT_FIELD_REF:
433 {
434 ret = compare_decl (t1, t2);
435 return return_with_debug (ret);
436 }
437 default:
438 return return_false_with_msg ("Unknown TREE code reached");
439 }
440 }
441
442 /* Compares two tree list operands T1 and T2 and returns true if these
443 two trees are semantically equivalent. */
444
445 bool
446 func_checker::compare_tree_list_operand (tree t1, tree t2)
447 {
448 gcc_assert (TREE_CODE (t1) == TREE_LIST);
449 gcc_assert (TREE_CODE (t2) == TREE_LIST);
450
451 for (; t1; t1 = TREE_CHAIN (t1))
452 {
453 if (!t2)
454 return false;
455
456 if (!compare_operand (TREE_VALUE (t1), TREE_VALUE (t2)))
457 return return_false ();
458
459 t2 = TREE_CHAIN (t2);
460 }
461
462 if (t2)
463 return return_false ();
464
465 return true;
466 }
467
468 /* Verifies that trees T1 and T2, representing function declarations
469 are equivalent from perspective of ICF. */
470
471 bool
472 func_checker::compare_function_decl (tree t1, tree t2)
473 {
474 bool ret = false;
475
476 if (t1 == t2)
477 return true;
478
479 symtab_node *n1 = symtab_node::get (t1);
480 symtab_node *n2 = symtab_node::get (t2);
481
482 if (m_ignored_source_nodes != NULL && m_ignored_target_nodes != NULL)
483 {
484 ret = m_ignored_source_nodes->contains (n1)
485 && m_ignored_target_nodes->contains (n2);
486
487 if (ret)
488 return true;
489 }
490
491 /* If function decl is WEAKREF, we compare targets. */
492 cgraph_node *f1 = cgraph_node::get (t1);
493 cgraph_node *f2 = cgraph_node::get (t2);
494
495 if(f1 && f2 && f1->weakref && f2->weakref)
496 ret = f1->alias_target == f2->alias_target;
497
498 return ret;
499 }
500
501 /* Verifies that trees T1 and T2 do correspond. */
502
503 bool
504 func_checker::compare_variable_decl (tree t1, tree t2)
505 {
506 bool ret = false;
507
508 if (t1 == t2)
509 return true;
510
511 if (TREE_CODE (t1) == VAR_DECL && (DECL_EXTERNAL (t1) || TREE_STATIC (t1)))
512 {
513 symtab_node *n1 = symtab_node::get (t1);
514 symtab_node *n2 = symtab_node::get (t2);
515
516 if (m_ignored_source_nodes != NULL && m_ignored_target_nodes != NULL)
517 {
518 ret = m_ignored_source_nodes->contains (n1)
519 && m_ignored_target_nodes->contains (n2);
520
521 if (ret)
522 return true;
523 }
524 }
525 ret = compare_decl (t1, t2);
526
527 return return_with_debug (ret);
528 }
529
530
531 /* Function visits all gimple labels and creates corresponding
532 mapping between basic blocks and labels. */
533
534 void
535 func_checker::parse_labels (sem_bb *bb)
536 {
537 for (gimple_stmt_iterator gsi = gsi_start_bb (bb->bb); !gsi_end_p (gsi);
538 gsi_next (&gsi))
539 {
540 gimple stmt = gsi_stmt (gsi);
541
542 if (glabel *label_stmt = dyn_cast <glabel *> (stmt))
543 {
544 tree t = gimple_label_label (label_stmt);
545 gcc_assert (TREE_CODE (t) == LABEL_DECL);
546
547 m_label_bb_map.put (t, bb->bb->index);
548 }
549 }
550 }
551
552 /* Basic block equivalence comparison function that returns true if
553 basic blocks BB1 and BB2 (from functions FUNC1 and FUNC2) correspond.
554
555 In general, a collection of equivalence dictionaries is built for types
556 like SSA names, declarations (VAR_DECL, PARM_DECL, ..). This infrastructure
557 is utilized by every statement-by-statement comparison function. */
558
559 bool
560 func_checker::compare_bb (sem_bb *bb1, sem_bb *bb2)
561 {
562 unsigned i;
563 gimple_stmt_iterator gsi1, gsi2;
564 gimple s1, s2;
565
566 if (bb1->nondbg_stmt_count != bb2->nondbg_stmt_count
567 || bb1->edge_count != bb2->edge_count)
568 return return_false ();
569
570 gsi1 = gsi_start_bb (bb1->bb);
571 gsi2 = gsi_start_bb (bb2->bb);
572
573 for (i = 0; i < bb1->nondbg_stmt_count; i++)
574 {
575 if (is_gimple_debug (gsi_stmt (gsi1)))
576 gsi_next_nondebug (&gsi1);
577
578 if (is_gimple_debug (gsi_stmt (gsi2)))
579 gsi_next_nondebug (&gsi2);
580
581 s1 = gsi_stmt (gsi1);
582 s2 = gsi_stmt (gsi2);
583
584 int eh1 = lookup_stmt_eh_lp_fn
585 (DECL_STRUCT_FUNCTION (m_source_func_decl), s1);
586 int eh2 = lookup_stmt_eh_lp_fn
587 (DECL_STRUCT_FUNCTION (m_target_func_decl), s2);
588
589 if (eh1 != eh2)
590 return return_false_with_msg ("EH regions are different");
591
592 if (gimple_code (s1) != gimple_code (s2))
593 return return_false_with_msg ("gimple codes are different");
594
595 switch (gimple_code (s1))
596 {
597 case GIMPLE_CALL:
598 if (!compare_gimple_call (as_a <gcall *> (s1),
599 as_a <gcall *> (s2)))
600 return return_different_stmts (s1, s2, "GIMPLE_CALL");
601 break;
602 case GIMPLE_ASSIGN:
603 if (!compare_gimple_assign (s1, s2))
604 return return_different_stmts (s1, s2, "GIMPLE_ASSIGN");
605 break;
606 case GIMPLE_COND:
607 if (!compare_gimple_cond (s1, s2))
608 return return_different_stmts (s1, s2, "GIMPLE_COND");
609 break;
610 case GIMPLE_SWITCH:
611 if (!compare_gimple_switch (as_a <gswitch *> (s1),
612 as_a <gswitch *> (s2)))
613 return return_different_stmts (s1, s2, "GIMPLE_SWITCH");
614 break;
615 case GIMPLE_DEBUG:
616 case GIMPLE_EH_DISPATCH:
617 break;
618 case GIMPLE_RESX:
619 if (!compare_gimple_resx (as_a <gresx *> (s1),
620 as_a <gresx *> (s2)))
621 return return_different_stmts (s1, s2, "GIMPLE_RESX");
622 break;
623 case GIMPLE_LABEL:
624 if (!compare_gimple_label (as_a <glabel *> (s1),
625 as_a <glabel *> (s2)))
626 return return_different_stmts (s1, s2, "GIMPLE_LABEL");
627 break;
628 case GIMPLE_RETURN:
629 if (!compare_gimple_return (as_a <greturn *> (s1),
630 as_a <greturn *> (s2)))
631 return return_different_stmts (s1, s2, "GIMPLE_RETURN");
632 break;
633 case GIMPLE_GOTO:
634 if (!compare_gimple_goto (s1, s2))
635 return return_different_stmts (s1, s2, "GIMPLE_GOTO");
636 break;
637 case GIMPLE_ASM:
638 if (!compare_gimple_asm (as_a <gasm *> (s1),
639 as_a <gasm *> (s2)))
640 return return_different_stmts (s1, s2, "GIMPLE_ASM");
641 break;
642 case GIMPLE_PREDICT:
643 case GIMPLE_NOP:
644 return true;
645 default:
646 return return_false_with_msg ("Unknown GIMPLE code reached");
647 }
648
649 gsi_next (&gsi1);
650 gsi_next (&gsi2);
651 }
652
653 return true;
654 }
655
656 /* Verifies for given GIMPLEs S1 and S2 that
657 call statements are semantically equivalent. */
658
659 bool
660 func_checker::compare_gimple_call (gcall *s1, gcall *s2)
661 {
662 unsigned i;
663 tree t1, t2;
664
665 if (gimple_call_num_args (s1) != gimple_call_num_args (s2))
666 return false;
667
668 t1 = gimple_call_fn (s1);
669 t2 = gimple_call_fn (s2);
670 if (!compare_operand (t1, t2))
671 return return_false ();
672
673 /* Compare flags. */
674 if (gimple_call_internal_p (s1) != gimple_call_internal_p (s2)
675 || gimple_call_ctrl_altering_p (s1) != gimple_call_ctrl_altering_p (s2)
676 || gimple_call_tail_p (s1) != gimple_call_tail_p (s2)
677 || gimple_call_return_slot_opt_p (s1) != gimple_call_return_slot_opt_p (s2)
678 || gimple_call_from_thunk_p (s1) != gimple_call_from_thunk_p (s2)
679 || gimple_call_va_arg_pack_p (s1) != gimple_call_va_arg_pack_p (s2)
680 || gimple_call_alloca_for_var_p (s1) != gimple_call_alloca_for_var_p (s2)
681 || gimple_call_with_bounds_p (s1) != gimple_call_with_bounds_p (s2))
682 return false;
683
684 if (gimple_call_internal_p (s1)
685 && gimple_call_internal_fn (s1) != gimple_call_internal_fn (s2))
686 return false;
687
688 tree fntype1 = gimple_call_fntype (s1);
689 tree fntype2 = gimple_call_fntype (s2);
690 if ((fntype1 && !fntype2)
691 || (!fntype1 && fntype2)
692 || (fntype1 && !types_compatible_p (fntype1, fntype2)))
693 return return_false_with_msg ("call function types are not compatible");
694
695 tree chain1 = gimple_call_chain (s1);
696 tree chain2 = gimple_call_chain (s2);
697 if ((chain1 && !chain2)
698 || (!chain1 && chain2)
699 || !compare_operand (chain1, chain2))
700 return return_false_with_msg ("static call chains are different");
701
702 /* Checking of argument. */
703 for (i = 0; i < gimple_call_num_args (s1); ++i)
704 {
705 t1 = gimple_call_arg (s1, i);
706 t2 = gimple_call_arg (s2, i);
707
708 if (!compare_operand (t1, t2))
709 return false;
710 }
711
712 /* Return value checking. */
713 t1 = gimple_get_lhs (s1);
714 t2 = gimple_get_lhs (s2);
715
716 return compare_operand (t1, t2);
717 }
718
719
720 /* Verifies for given GIMPLEs S1 and S2 that
721 assignment statements are semantically equivalent. */
722
723 bool
724 func_checker::compare_gimple_assign (gimple s1, gimple s2)
725 {
726 tree arg1, arg2;
727 tree_code code1, code2;
728 unsigned i;
729
730 code1 = gimple_expr_code (s1);
731 code2 = gimple_expr_code (s2);
732
733 if (code1 != code2)
734 return false;
735
736 code1 = gimple_assign_rhs_code (s1);
737 code2 = gimple_assign_rhs_code (s2);
738
739 if (code1 != code2)
740 return false;
741
742 for (i = 0; i < gimple_num_ops (s1); i++)
743 {
744 arg1 = gimple_op (s1, i);
745 arg2 = gimple_op (s2, i);
746
747 if (!compare_operand (arg1, arg2))
748 return false;
749 }
750
751
752 return true;
753 }
754
755 /* Verifies for given GIMPLEs S1 and S2 that
756 condition statements are semantically equivalent. */
757
758 bool
759 func_checker::compare_gimple_cond (gimple s1, gimple s2)
760 {
761 tree t1, t2;
762 tree_code code1, code2;
763
764 code1 = gimple_expr_code (s1);
765 code2 = gimple_expr_code (s2);
766
767 if (code1 != code2)
768 return false;
769
770 t1 = gimple_cond_lhs (s1);
771 t2 = gimple_cond_lhs (s2);
772
773 if (!compare_operand (t1, t2))
774 return false;
775
776 t1 = gimple_cond_rhs (s1);
777 t2 = gimple_cond_rhs (s2);
778
779 return compare_operand (t1, t2);
780 }
781
782 /* Verifies that tree labels T1 and T2 correspond in FUNC1 and FUNC2. */
783
784 bool
785 func_checker::compare_tree_ssa_label (tree t1, tree t2)
786 {
787 return compare_operand (t1, t2);
788 }
789
790 /* Verifies for given GIMPLE_LABEL stmts S1 and S2 that
791 label statements are semantically equivalent. */
792
793 bool
794 func_checker::compare_gimple_label (const glabel *g1, const glabel *g2)
795 {
796 if (m_ignore_labels)
797 return true;
798
799 tree t1 = gimple_label_label (g1);
800 tree t2 = gimple_label_label (g2);
801
802 if (FORCED_LABEL (t1) || FORCED_LABEL (t2))
803 return return_false_with_msg ("FORCED_LABEL");
804
805 /* As the pass build BB to label mapping, no further check is needed. */
806 return true;
807 }
808
809 /* Verifies for given GIMPLE_SWITCH stmts S1 and S2 that
810 switch statements are semantically equivalent. */
811
812 bool
813 func_checker::compare_gimple_switch (const gswitch *g1, const gswitch *g2)
814 {
815 unsigned lsize1, lsize2, i;
816
817 lsize1 = gimple_switch_num_labels (g1);
818 lsize2 = gimple_switch_num_labels (g2);
819
820 if (lsize1 != lsize2)
821 return false;
822
823 tree t1 = gimple_switch_index (g1);
824 tree t2 = gimple_switch_index (g2);
825
826 if (!compare_operand (t1, t2))
827 return false;
828
829 for (i = 0; i < lsize1; i++)
830 {
831 tree label1 = gimple_switch_label (g1, i);
832 tree label2 = gimple_switch_label (g2, i);
833
834 /* Label LOW and HIGH comparison. */
835 tree low1 = CASE_LOW (label1);
836 tree low2 = CASE_LOW (label2);
837
838 if (!tree_int_cst_equal (low1, low2))
839 return return_false_with_msg ("case low values are different");
840
841 tree high1 = CASE_HIGH (label1);
842 tree high2 = CASE_HIGH (label2);
843
844 if (!tree_int_cst_equal (high1, high2))
845 return return_false_with_msg ("case high values are different");
846
847 if (TREE_CODE (label1) == CASE_LABEL_EXPR
848 && TREE_CODE (label2) == CASE_LABEL_EXPR)
849 {
850 label1 = CASE_LABEL (label1);
851 label2 = CASE_LABEL (label2);
852
853 if (!compare_operand (label1, label2))
854 return return_false_with_msg ("switch label_exprs are different");
855 }
856 else if (!tree_int_cst_equal (label1, label2))
857 return return_false_with_msg ("switch labels are different");
858 }
859
860 return true;
861 }
862
863 /* Verifies for given GIMPLE_RETURN stmts S1 and S2 that
864 return statements are semantically equivalent. */
865
866 bool
867 func_checker::compare_gimple_return (const greturn *g1, const greturn *g2)
868 {
869 tree t1, t2;
870
871 t1 = gimple_return_retval (g1);
872 t2 = gimple_return_retval (g2);
873
874 /* Void return type. */
875 if (t1 == NULL && t2 == NULL)
876 return true;
877 else
878 return compare_operand (t1, t2);
879 }
880
881 /* Verifies for given GIMPLEs S1 and S2 that
882 goto statements are semantically equivalent. */
883
884 bool
885 func_checker::compare_gimple_goto (gimple g1, gimple g2)
886 {
887 tree dest1, dest2;
888
889 dest1 = gimple_goto_dest (g1);
890 dest2 = gimple_goto_dest (g2);
891
892 if (TREE_CODE (dest1) != TREE_CODE (dest2) || TREE_CODE (dest1) != SSA_NAME)
893 return false;
894
895 return compare_operand (dest1, dest2);
896 }
897
898 /* Verifies for given GIMPLE_RESX stmts S1 and S2 that
899 resx statements are semantically equivalent. */
900
901 bool
902 func_checker::compare_gimple_resx (const gresx *g1, const gresx *g2)
903 {
904 return gimple_resx_region (g1) == gimple_resx_region (g2);
905 }
906
907 /* Verifies for given GIMPLEs S1 and S2 that ASM statements are equivalent.
908 For the beginning, the pass only supports equality for
909 '__asm__ __volatile__ ("", "", "", "memory")'. */
910
911 bool
912 func_checker::compare_gimple_asm (const gasm *g1, const gasm *g2)
913 {
914 if (gimple_asm_volatile_p (g1) != gimple_asm_volatile_p (g2))
915 return false;
916
917 if (gimple_asm_ninputs (g1) != gimple_asm_ninputs (g2))
918 return false;
919
920 if (gimple_asm_noutputs (g1) != gimple_asm_noutputs (g2))
921 return false;
922
923 /* We do not suppport goto ASM statement comparison. */
924 if (gimple_asm_nlabels (g1) || gimple_asm_nlabels (g2))
925 return false;
926
927 if (gimple_asm_nclobbers (g1) != gimple_asm_nclobbers (g2))
928 return false;
929
930 if (strcmp (gimple_asm_string (g1), gimple_asm_string (g2)) != 0)
931 return return_false_with_msg ("ASM strings are different");
932
933 for (unsigned i = 0; i < gimple_asm_ninputs (g1); i++)
934 {
935 tree input1 = gimple_asm_input_op (g1, i);
936 tree input2 = gimple_asm_input_op (g2, i);
937
938 if (!compare_tree_list_operand (input1, input2))
939 return return_false_with_msg ("ASM input is different");
940 }
941
942 for (unsigned i = 0; i < gimple_asm_noutputs (g1); i++)
943 {
944 tree output1 = gimple_asm_output_op (g1, i);
945 tree output2 = gimple_asm_output_op (g2, i);
946
947 if (!compare_tree_list_operand (output1, output2))
948 return return_false_with_msg ("ASM output is different");
949 }
950
951 for (unsigned i = 0; i < gimple_asm_nclobbers (g1); i++)
952 {
953 tree clobber1 = gimple_asm_clobber_op (g1, i);
954 tree clobber2 = gimple_asm_clobber_op (g2, i);
955
956 if (!operand_equal_p (TREE_VALUE (clobber1), TREE_VALUE (clobber2),
957 OEP_ONLY_CONST))
958 return return_false_with_msg ("ASM clobber is different");
959 }
960
961 return true;
962 }
963
964 } // ipa_icf_gimple namespace