]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ipa-icf-gimple.c
[PATCH 1/2] (header usage fix) remove unused system header includes
[thirdparty/gcc.git] / gcc / ipa-icf-gimple.c
CommitLineData
52200d03 1/* Interprocedural Identical Code Folding pass
f1717362 2 Copyright (C) 2014-2016 Free Software Foundation, Inc.
52200d03 3
4 Contributed by Jan Hubicka <hubicka@ucw.cz> and Martin Liska <mliska@suse.cz>
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 3, or (at your option) any later
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
19along 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"
9ef16211 25#include "backend.h"
7c29e30e 26#include "rtl.h"
b20a8bb4 27#include "tree.h"
52200d03 28#include "gimple.h"
7c29e30e 29#include "tree-pass.h"
9ef16211 30#include "ssa.h"
7c29e30e 31#include "cgraph.h"
32#include "data-streamer.h"
33#include "gimple-pretty-print.h"
34#include "alias.h"
9ef16211 35#include "fold-const.h"
52200d03 36#include "gimple-iterator.h"
52200d03 37#include "ipa-utils.h"
52200d03 38#include "tree-eh.h"
fbbe5f6b 39#include "builtins.h"
52200d03 40
41#include "ipa-icf-gimple.h"
52200d03 42
43namespace ipa_icf_gimple {
44
45/* Initialize internal structures for a given SOURCE_FUNC_DECL and
46 TARGET_FUNC_DECL. Strict polymorphic comparison is processed if
47 an option COMPARE_POLYMORPHIC is true. For special cases, one can
48 set IGNORE_LABELS to skip label comparison.
49 Similarly, IGNORE_SOURCE_DECLS and IGNORE_TARGET_DECLS are sets
50 of declarations that can be skipped. */
51
52func_checker::func_checker (tree source_func_decl, tree target_func_decl,
53 bool compare_polymorphic,
54 bool ignore_labels,
55 hash_set<symtab_node *> *ignored_source_nodes,
56 hash_set<symtab_node *> *ignored_target_nodes)
57 : m_source_func_decl (source_func_decl), m_target_func_decl (target_func_decl),
58 m_ignored_source_nodes (ignored_source_nodes),
59 m_ignored_target_nodes (ignored_target_nodes),
60 m_compare_polymorphic (compare_polymorphic),
61 m_ignore_labels (ignore_labels)
62{
63 function *source_func = DECL_STRUCT_FUNCTION (source_func_decl);
64 function *target_func = DECL_STRUCT_FUNCTION (target_func_decl);
65
66 unsigned ssa_source = SSANAMES (source_func)->length ();
67 unsigned ssa_target = SSANAMES (target_func)->length ();
68
69 m_source_ssa_names.create (ssa_source);
70 m_target_ssa_names.create (ssa_target);
71
72 for (unsigned i = 0; i < ssa_source; i++)
73 m_source_ssa_names.safe_push (-1);
74
75 for (unsigned i = 0; i < ssa_target; i++)
76 m_target_ssa_names.safe_push (-1);
77}
78
79/* Memory release routine. */
80
81func_checker::~func_checker ()
82{
83 m_source_ssa_names.release();
84 m_target_ssa_names.release();
85}
86
87/* Verifies that trees T1 and T2 are equivalent from perspective of ICF. */
88
89bool
90func_checker::compare_ssa_name (tree t1, tree t2)
91{
05e3f053 92 gcc_assert (TREE_CODE (t1) == SSA_NAME);
93 gcc_assert (TREE_CODE (t2) == SSA_NAME);
94
52200d03 95 unsigned i1 = SSA_NAME_VERSION (t1);
96 unsigned i2 = SSA_NAME_VERSION (t2);
97
98 if (m_source_ssa_names[i1] == -1)
99 m_source_ssa_names[i1] = i2;
100 else if (m_source_ssa_names[i1] != (int) i2)
101 return false;
102
103 if(m_target_ssa_names[i2] == -1)
104 m_target_ssa_names[i2] = i1;
105 else if (m_target_ssa_names[i2] != (int) i1)
106 return false;
107
05e3f053 108 if (SSA_NAME_IS_DEFAULT_DEF (t1))
109 {
110 tree b1 = SSA_NAME_VAR (t1);
111 tree b2 = SSA_NAME_VAR (t2);
112
113 if (b1 == NULL && b2 == NULL)
114 return true;
115
116 if (b1 == NULL || b2 == NULL || TREE_CODE (b1) != TREE_CODE (b2))
117 return return_false ();
118
119 return compare_cst_or_decl (b1, b2);
120 }
121
52200d03 122 return true;
123}
124
125/* Verification function for edges E1 and E2. */
126
127bool
128func_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
149bool
150func_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
9f27b0ca 161 if (!compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2)))
162 return return_false ();
163
164 /* TODO: we are actually too strict here. We only need to compare if
165 T1 can be used in polymorphic call. */
166 if (TREE_ADDRESSABLE (t1)
167 && m_compare_polymorphic
168 && !compatible_polymorphic_types_p (TREE_TYPE (t1), TREE_TYPE (t2),
169 false))
170 return return_false ();
171
172 if ((t == VAR_DECL || t == PARM_DECL || t == RESULT_DECL)
173 && DECL_BY_REFERENCE (t1)
174 && m_compare_polymorphic
175 && !compatible_polymorphic_types_p (TREE_TYPE (t1), TREE_TYPE (t2),
176 true))
52200d03 177 return return_false ();
178
179 bool existed_p;
180
181 tree &slot = m_decl_map.get_or_insert (t1, &existed_p);
182 if (existed_p)
183 return return_with_debug (slot == t2);
184 else
185 slot = t2;
186
187 return true;
188}
189
9f27b0ca 190/* Return true if T1 and T2 are same for purposes of ipa-polymorphic-call
191 analysis. COMPARE_PTR indicates if types of pointers needs to be
192 considered. */
193
194bool
195func_checker::compatible_polymorphic_types_p (tree t1, tree t2,
196 bool compare_ptr)
197{
198 gcc_assert (TREE_CODE (t1) != FUNCTION_TYPE && TREE_CODE (t1) != METHOD_TYPE);
199
200 /* Pointer types generally give no information. */
201 if (POINTER_TYPE_P (t1))
202 {
203 if (!compare_ptr)
204 return true;
205 return func_checker::compatible_polymorphic_types_p (TREE_TYPE (t1),
206 TREE_TYPE (t2),
207 false);
208 }
209
210 /* If types contain a polymorphic types, match them. */
211 bool c1 = contains_polymorphic_type_p (t1);
212 bool c2 = contains_polymorphic_type_p (t2);
213 if (!c1 && !c2)
214 return true;
215 if (!c1 || !c2)
216 return return_false_with_msg ("one type is not polymorphic");
217 if (!types_must_be_same_for_odr (t1, t2))
218 return return_false_with_msg ("types are not same for ODR");
219 return true;
220}
221
52200d03 222/* Return true if types are compatible from perspective of ICF. */
05e3f053 223bool
9f27b0ca 224func_checker::compatible_types_p (tree t1, tree t2)
52200d03 225{
226 if (TREE_CODE (t1) != TREE_CODE (t2))
227 return return_false_with_msg ("different tree types");
228
62cd13c3 229 if (TYPE_RESTRICT (t1) != TYPE_RESTRICT (t2))
230 return return_false_with_msg ("restrict flags are different");
231
52200d03 232 if (!types_compatible_p (t1, t2))
233 return return_false_with_msg ("types are not compatible");
234
b3af74d7 235 /* We do a lot of unnecesary matching of types that are not being
236 accessed and thus do not need to be compatible. In longer term we should
237 remove these checks on all types which are not accessed as memory
238 locations.
239
240 For time being just avoid calling get_alias_set on types that are not
241 having alias sets defined at all. */
242 if (type_with_alias_set_p (t1) && type_with_alias_set_p (t2)
243 && get_alias_set (t1) != get_alias_set (t2))
52200d03 244 return return_false_with_msg ("alias sets are different");
245
52200d03 246 return true;
247}
248
05e3f053 249/* Function compare for equality given memory operands T1 and T2. */
250
251bool
252func_checker::compare_memory_operand (tree t1, tree t2)
253{
254 if (!t1 && !t2)
255 return true;
256 else if (!t1 || !t2)
257 return false;
258
259 ao_ref r1, r2;
260 ao_ref_init (&r1, t1);
261 ao_ref_init (&r2, t2);
262
263 tree b1 = ao_ref_base (&r1);
264 tree b2 = ao_ref_base (&r2);
265
266 bool source_is_memop = DECL_P (b1) || INDIRECT_REF_P (b1)
267 || TREE_CODE (b1) == MEM_REF
268 || TREE_CODE (b1) == TARGET_MEM_REF;
269
270 bool target_is_memop = DECL_P (b2) || INDIRECT_REF_P (b2)
271 || TREE_CODE (b2) == MEM_REF
272 || TREE_CODE (b2) == TARGET_MEM_REF;
273
274 /* Compare alias sets for memory operands. */
275 if (source_is_memop && target_is_memop)
276 {
810430af 277 if (TREE_THIS_VOLATILE (t1) != TREE_THIS_VOLATILE (t2))
05e3f053 278 return return_false_with_msg ("different operand volatility");
279
280 if (ao_ref_alias_set (&r1) != ao_ref_alias_set (&r2)
281 || ao_ref_base_alias_set (&r1) != ao_ref_base_alias_set (&r2))
282 return return_false_with_msg ("ao alias sets are different");
fbbe5f6b 283
284 /* We can't simply use get_object_alignment_1 on the full
285 reference as for accesses with variable indexes this reports
286 too conservative alignment. We also can't use the ao_ref_base
287 base objects as ao_ref_base happily strips MEM_REFs around
288 decls even though that may carry alignment info. */
289 b1 = t1;
290 while (handled_component_p (b1))
291 b1 = TREE_OPERAND (b1, 0);
292 b2 = t2;
293 while (handled_component_p (b2))
294 b2 = TREE_OPERAND (b2, 0);
295 unsigned int align1, align2;
296 unsigned HOST_WIDE_INT tem;
297 get_object_alignment_1 (b1, &align1, &tem);
298 get_object_alignment_1 (b2, &align2, &tem);
299 if (align1 != align2)
300 return return_false_with_msg ("different access alignment");
6b1460de 301
302 /* Similarly we have to compare dependence info where equality
303 tells us we are safe (even some unequal values would be safe
304 but then we have to maintain a map of bases and cliques). */
305 unsigned short clique1 = 0, base1 = 0, clique2 = 0, base2 = 0;
306 if (TREE_CODE (b1) == MEM_REF)
307 {
308 clique1 = MR_DEPENDENCE_CLIQUE (b1);
309 base1 = MR_DEPENDENCE_BASE (b1);
310 }
311 if (TREE_CODE (b2) == MEM_REF)
312 {
313 clique2 = MR_DEPENDENCE_CLIQUE (b2);
314 base2 = MR_DEPENDENCE_BASE (b2);
315 }
316 if (clique1 != clique2 || base1 != base2)
317 return return_false_with_msg ("different dependence info");
05e3f053 318 }
319
320 return compare_operand (t1, t2);
321}
322
323/* Function compare for equality given trees T1 and T2 which
324 can be either a constant or a declaration type. */
325
326bool
327func_checker::compare_cst_or_decl (tree t1, tree t2)
328{
329 bool ret;
330
331 switch (TREE_CODE (t1))
332 {
333 case INTEGER_CST:
334 case COMPLEX_CST:
335 case VECTOR_CST:
336 case STRING_CST:
337 case REAL_CST:
338 {
339 ret = compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2))
340 && operand_equal_p (t1, t2, OEP_ONLY_CONST);
341 return return_with_debug (ret);
342 }
343 case FUNCTION_DECL:
7fb15fe8 344 /* All function decls are in the symbol table and known to match
345 before we start comparing bodies. */
346 return true;
05e3f053 347 case VAR_DECL:
348 return return_with_debug (compare_variable_decl (t1, t2));
349 case FIELD_DECL:
350 {
351 tree offset1 = DECL_FIELD_OFFSET (t1);
352 tree offset2 = DECL_FIELD_OFFSET (t2);
353
354 tree bit_offset1 = DECL_FIELD_BIT_OFFSET (t1);
355 tree bit_offset2 = DECL_FIELD_BIT_OFFSET (t2);
356
357 ret = compare_operand (offset1, offset2)
358 && compare_operand (bit_offset1, bit_offset2);
359
360 return return_with_debug (ret);
361 }
362 case LABEL_DECL:
363 {
364 int *bb1 = m_label_bb_map.get (t1);
365 int *bb2 = m_label_bb_map.get (t2);
366
367 return return_with_debug (*bb1 == *bb2);
368 }
369 case PARM_DECL:
370 case RESULT_DECL:
371 case CONST_DECL:
372 {
373 ret = compare_decl (t1, t2);
374 return return_with_debug (ret);
375 }
376 default:
377 gcc_unreachable ();
378 }
379}
380
381/* Function responsible for comparison of various operands T1 and T2.
52200d03 382 If these components, from functions FUNC1 and FUNC2, are equal, true
383 is returned. */
384
385bool
386func_checker::compare_operand (tree t1, tree t2)
387{
05e3f053 388 tree x1, x2, y1, y2, z1, z2;
52200d03 389 bool ret;
390
391 if (!t1 && !t2)
392 return true;
393 else if (!t1 || !t2)
394 return false;
395
396 tree tt1 = TREE_TYPE (t1);
397 tree tt2 = TREE_TYPE (t2);
398
399 if (!func_checker::compatible_types_p (tt1, tt2))
400 return false;
401
52200d03 402 if (TREE_CODE (t1) != TREE_CODE (t2))
403 return return_false ();
404
405 switch (TREE_CODE (t1))
406 {
407 case CONSTRUCTOR:
a000165c 408 {
409 unsigned length1 = vec_safe_length (CONSTRUCTOR_ELTS (t1));
410 unsigned length2 = vec_safe_length (CONSTRUCTOR_ELTS (t2));
411
412 if (length1 != length2)
413 return return_false ();
414
415 for (unsigned i = 0; i < length1; i++)
416 if (!compare_operand (CONSTRUCTOR_ELT (t1, i)->value,
417 CONSTRUCTOR_ELT (t2, i)->value))
418 return return_false();
419
420 return true;
421 }
52200d03 422 case ARRAY_REF:
423 case ARRAY_RANGE_REF:
05e3f053 424 /* First argument is the array, second is the index. */
52200d03 425 x1 = TREE_OPERAND (t1, 0);
426 x2 = TREE_OPERAND (t2, 0);
427 y1 = TREE_OPERAND (t1, 1);
428 y2 = TREE_OPERAND (t2, 1);
429
430 if (!compare_operand (array_ref_low_bound (t1),
431 array_ref_low_bound (t2)))
432 return return_false_with_msg ("");
433 if (!compare_operand (array_ref_element_size (t1),
434 array_ref_element_size (t2)))
435 return return_false_with_msg ("");
05e3f053 436
52200d03 437 if (!compare_operand (x1, x2))
438 return return_false_with_msg ("");
439 return compare_operand (y1, y2);
440 case MEM_REF:
441 {
442 x1 = TREE_OPERAND (t1, 0);
443 x2 = TREE_OPERAND (t2, 0);
444 y1 = TREE_OPERAND (t1, 1);
445 y2 = TREE_OPERAND (t2, 1);
446
447 /* See if operand is an memory access (the test originate from
448 gimple_load_p).
449
450 In this case the alias set of the function being replaced must
451 be subset of the alias set of the other function. At the moment
452 we seek for equivalency classes, so simply require inclussion in
453 both directions. */
454
455 if (!func_checker::compatible_types_p (TREE_TYPE (x1), TREE_TYPE (x2)))
456 return return_false ();
457
458 if (!compare_operand (x1, x2))
459 return return_false_with_msg ("");
460
52200d03 461 /* Type of the offset on MEM_REF does not matter. */
462 return wi::to_offset (y1) == wi::to_offset (y2);
463 }
464 case COMPONENT_REF:
465 {
466 x1 = TREE_OPERAND (t1, 0);
467 x2 = TREE_OPERAND (t2, 0);
468 y1 = TREE_OPERAND (t1, 1);
469 y2 = TREE_OPERAND (t2, 1);
470
471 ret = compare_operand (x1, x2)
05e3f053 472 && compare_cst_or_decl (y1, y2);
52200d03 473
474 return return_with_debug (ret);
475 }
476 /* Virtual table call. */
477 case OBJ_TYPE_REF:
478 {
2f51f5cb 479 if (!compare_ssa_name (OBJ_TYPE_REF_EXPR (t1), OBJ_TYPE_REF_EXPR (t2)))
480 return return_false ();
481 if (opt_for_fn (m_source_func_decl, flag_devirtualize)
482 && virtual_method_call_p (t1))
483 {
484 if (tree_to_uhwi (OBJ_TYPE_REF_TOKEN (t1))
485 != tree_to_uhwi (OBJ_TYPE_REF_TOKEN (t2)))
486 return return_false_with_msg ("OBJ_TYPE_REF token mismatch");
487 if (!types_same_for_odr (obj_type_ref_class (t1),
488 obj_type_ref_class (t2)))
489 return return_false_with_msg ("OBJ_TYPE_REF OTR type mismatch");
905be4e6 490 if (!compare_operand (OBJ_TYPE_REF_OBJECT (t1),
491 OBJ_TYPE_REF_OBJECT (t2)))
2f51f5cb 492 return return_false_with_msg ("OBJ_TYPE_REF object mismatch");
493 }
494
495 return return_with_debug (true);
52200d03 496 }
cadb17da 497 case IMAGPART_EXPR:
498 case REALPART_EXPR:
52200d03 499 case ADDR_EXPR:
500 {
501 x1 = TREE_OPERAND (t1, 0);
502 x2 = TREE_OPERAND (t2, 0);
503
504 ret = compare_operand (x1, x2);
505 return return_with_debug (ret);
506 }
05e3f053 507 case BIT_FIELD_REF:
52200d03 508 {
cadb17da 509 x1 = TREE_OPERAND (t1, 0);
510 x2 = TREE_OPERAND (t2, 0);
511 y1 = TREE_OPERAND (t1, 1);
512 y2 = TREE_OPERAND (t2, 1);
513 z1 = TREE_OPERAND (t1, 2);
514 z2 = TREE_OPERAND (t2, 2);
515
516 ret = compare_operand (x1, x2)
517 && compare_cst_or_decl (y1, y2)
518 && compare_cst_or_decl (z1, z2);
519
52200d03 520 return return_with_debug (ret);
521 }
05e3f053 522 case SSA_NAME:
523 return compare_ssa_name (t1, t2);
524 case INTEGER_CST:
52200d03 525 case COMPLEX_CST:
526 case VECTOR_CST:
527 case STRING_CST:
528 case REAL_CST:
52200d03 529 case FUNCTION_DECL:
52200d03 530 case VAR_DECL:
52200d03 531 case FIELD_DECL:
52200d03 532 case LABEL_DECL:
52200d03 533 case PARM_DECL:
534 case RESULT_DECL:
535 case CONST_DECL:
05e3f053 536 return compare_cst_or_decl (t1, t2);
52200d03 537 default:
538 return return_false_with_msg ("Unknown TREE code reached");
539 }
540}
541
542/* Compares two tree list operands T1 and T2 and returns true if these
543 two trees are semantically equivalent. */
544
545bool
546func_checker::compare_tree_list_operand (tree t1, tree t2)
547{
548 gcc_assert (TREE_CODE (t1) == TREE_LIST);
549 gcc_assert (TREE_CODE (t2) == TREE_LIST);
550
551 for (; t1; t1 = TREE_CHAIN (t1))
552 {
553 if (!t2)
554 return false;
555
556 if (!compare_operand (TREE_VALUE (t1), TREE_VALUE (t2)))
557 return return_false ();
558
559 t2 = TREE_CHAIN (t2);
560 }
561
562 if (t2)
563 return return_false ();
564
565 return true;
566}
567
52200d03 568/* Verifies that trees T1 and T2 do correspond. */
569
570bool
571func_checker::compare_variable_decl (tree t1, tree t2)
572{
573 bool ret = false;
574
575 if (t1 == t2)
576 return true;
577
2f3662f2 578 if (DECL_ALIGN (t1) != DECL_ALIGN (t2))
579 return return_false_with_msg ("alignments are different");
580
819a768f 581 if (DECL_HARD_REGISTER (t1) != DECL_HARD_REGISTER (t2))
582 return return_false_with_msg ("DECL_HARD_REGISTER are different");
583
584 if (DECL_HARD_REGISTER (t1)
585 && DECL_ASSEMBLER_NAME (t1) != DECL_ASSEMBLER_NAME (t2))
586 return return_false_with_msg ("HARD REGISTERS are different");
587
7fb15fe8 588 /* Symbol table variables are known to match before we start comparing
589 bodies. */
590 if (decl_in_symtab_p (t1))
591 return decl_in_symtab_p (t2);
52200d03 592 ret = compare_decl (t1, t2);
593
594 return return_with_debug (ret);
595}
596
b2e8d25e 597
598/* Function visits all gimple labels and creates corresponding
599 mapping between basic blocks and labels. */
600
52200d03 601void
602func_checker::parse_labels (sem_bb *bb)
603{
604 for (gimple_stmt_iterator gsi = gsi_start_bb (bb->bb); !gsi_end_p (gsi);
605 gsi_next (&gsi))
606 {
42acab1c 607 gimple *stmt = gsi_stmt (gsi);
52200d03 608
1a91d914 609 if (glabel *label_stmt = dyn_cast <glabel *> (stmt))
52200d03 610 {
1a91d914 611 tree t = gimple_label_label (label_stmt);
52200d03 612 gcc_assert (TREE_CODE (t) == LABEL_DECL);
613
614 m_label_bb_map.put (t, bb->bb->index);
615 }
616 }
617}
618
619/* Basic block equivalence comparison function that returns true if
620 basic blocks BB1 and BB2 (from functions FUNC1 and FUNC2) correspond.
621
622 In general, a collection of equivalence dictionaries is built for types
623 like SSA names, declarations (VAR_DECL, PARM_DECL, ..). This infrastructure
b1707571 624 is utilized by every statement-by-statement comparison function. */
52200d03 625
626bool
627func_checker::compare_bb (sem_bb *bb1, sem_bb *bb2)
628{
52200d03 629 gimple_stmt_iterator gsi1, gsi2;
42acab1c 630 gimple *s1, *s2;
52200d03 631
92e59323 632 gsi1 = gsi_start_bb_nondebug (bb1->bb);
633 gsi2 = gsi_start_bb_nondebug (bb2->bb);
52200d03 634
92e59323 635 while (!gsi_end_p (gsi1))
52200d03 636 {
92e59323 637 if (gsi_end_p (gsi2))
638 return return_false ();
52200d03 639
640 s1 = gsi_stmt (gsi1);
641 s2 = gsi_stmt (gsi2);
642
643 int eh1 = lookup_stmt_eh_lp_fn
644 (DECL_STRUCT_FUNCTION (m_source_func_decl), s1);
645 int eh2 = lookup_stmt_eh_lp_fn
646 (DECL_STRUCT_FUNCTION (m_target_func_decl), s2);
647
648 if (eh1 != eh2)
649 return return_false_with_msg ("EH regions are different");
650
651 if (gimple_code (s1) != gimple_code (s2))
652 return return_false_with_msg ("gimple codes are different");
653
654 switch (gimple_code (s1))
655 {
656 case GIMPLE_CALL:
1a91d914 657 if (!compare_gimple_call (as_a <gcall *> (s1),
658 as_a <gcall *> (s2)))
52200d03 659 return return_different_stmts (s1, s2, "GIMPLE_CALL");
660 break;
661 case GIMPLE_ASSIGN:
662 if (!compare_gimple_assign (s1, s2))
663 return return_different_stmts (s1, s2, "GIMPLE_ASSIGN");
664 break;
665 case GIMPLE_COND:
666 if (!compare_gimple_cond (s1, s2))
667 return return_different_stmts (s1, s2, "GIMPLE_COND");
668 break;
669 case GIMPLE_SWITCH:
1a91d914 670 if (!compare_gimple_switch (as_a <gswitch *> (s1),
671 as_a <gswitch *> (s2)))
52200d03 672 return return_different_stmts (s1, s2, "GIMPLE_SWITCH");
673 break;
674 case GIMPLE_DEBUG:
1c543545 675 break;
52200d03 676 case GIMPLE_EH_DISPATCH:
1c543545 677 if (gimple_eh_dispatch_region (as_a <geh_dispatch *> (s1))
678 != gimple_eh_dispatch_region (as_a <geh_dispatch *> (s2)))
679 return return_different_stmts (s1, s2, "GIMPLE_EH_DISPATCH");
52200d03 680 break;
681 case GIMPLE_RESX:
1a91d914 682 if (!compare_gimple_resx (as_a <gresx *> (s1),
683 as_a <gresx *> (s2)))
52200d03 684 return return_different_stmts (s1, s2, "GIMPLE_RESX");
685 break;
686 case GIMPLE_LABEL:
1a91d914 687 if (!compare_gimple_label (as_a <glabel *> (s1),
688 as_a <glabel *> (s2)))
52200d03 689 return return_different_stmts (s1, s2, "GIMPLE_LABEL");
690 break;
691 case GIMPLE_RETURN:
1a91d914 692 if (!compare_gimple_return (as_a <greturn *> (s1),
693 as_a <greturn *> (s2)))
52200d03 694 return return_different_stmts (s1, s2, "GIMPLE_RETURN");
695 break;
696 case GIMPLE_GOTO:
697 if (!compare_gimple_goto (s1, s2))
698 return return_different_stmts (s1, s2, "GIMPLE_GOTO");
699 break;
700 case GIMPLE_ASM:
1a91d914 701 if (!compare_gimple_asm (as_a <gasm *> (s1),
702 as_a <gasm *> (s2)))
52200d03 703 return return_different_stmts (s1, s2, "GIMPLE_ASM");
704 break;
705 case GIMPLE_PREDICT:
706 case GIMPLE_NOP:
1c543545 707 break;
52200d03 708 default:
709 return return_false_with_msg ("Unknown GIMPLE code reached");
710 }
711
92e59323 712 gsi_next_nondebug (&gsi1);
713 gsi_next_nondebug (&gsi2);
52200d03 714 }
715
92e59323 716 if (!gsi_end_p (gsi2))
717 return return_false ();
718
52200d03 719 return true;
720}
721
722/* Verifies for given GIMPLEs S1 and S2 that
723 call statements are semantically equivalent. */
724
725bool
1a91d914 726func_checker::compare_gimple_call (gcall *s1, gcall *s2)
52200d03 727{
728 unsigned i;
729 tree t1, t2;
730
731 if (gimple_call_num_args (s1) != gimple_call_num_args (s2))
732 return false;
733
b1707571 734 t1 = gimple_call_fn (s1);
735 t2 = gimple_call_fn (s2);
52200d03 736 if (!compare_operand (t1, t2))
b1707571 737 return return_false ();
738
739 /* Compare flags. */
740 if (gimple_call_internal_p (s1) != gimple_call_internal_p (s2)
741 || gimple_call_ctrl_altering_p (s1) != gimple_call_ctrl_altering_p (s2)
742 || gimple_call_tail_p (s1) != gimple_call_tail_p (s2)
743 || gimple_call_return_slot_opt_p (s1) != gimple_call_return_slot_opt_p (s2)
744 || gimple_call_from_thunk_p (s1) != gimple_call_from_thunk_p (s2)
745 || gimple_call_va_arg_pack_p (s1) != gimple_call_va_arg_pack_p (s2)
746 || gimple_call_alloca_for_var_p (s1) != gimple_call_alloca_for_var_p (s2)
747 || gimple_call_with_bounds_p (s1) != gimple_call_with_bounds_p (s2))
748 return false;
749
750 if (gimple_call_internal_p (s1)
751 && gimple_call_internal_fn (s1) != gimple_call_internal_fn (s2))
752 return false;
753
754 tree fntype1 = gimple_call_fntype (s1);
755 tree fntype2 = gimple_call_fntype (s2);
756 if ((fntype1 && !fntype2)
757 || (!fntype1 && fntype2)
758 || (fntype1 && !types_compatible_p (fntype1, fntype2)))
759 return return_false_with_msg ("call function types are not compatible");
760
761 tree chain1 = gimple_call_chain (s1);
762 tree chain2 = gimple_call_chain (s2);
763 if ((chain1 && !chain2)
764 || (!chain1 && chain2)
765 || !compare_operand (chain1, chain2))
766 return return_false_with_msg ("static call chains are different");
52200d03 767
768 /* Checking of argument. */
769 for (i = 0; i < gimple_call_num_args (s1); ++i)
770 {
771 t1 = gimple_call_arg (s1, i);
772 t2 = gimple_call_arg (s2, i);
773
05e3f053 774 if (!compare_memory_operand (t1, t2))
775 return return_false_with_msg ("memory operands are different");
52200d03 776 }
777
778 /* Return value checking. */
779 t1 = gimple_get_lhs (s1);
780 t2 = gimple_get_lhs (s2);
781
05e3f053 782 return compare_memory_operand (t1, t2);
52200d03 783}
784
785
786/* Verifies for given GIMPLEs S1 and S2 that
787 assignment statements are semantically equivalent. */
788
789bool
42acab1c 790func_checker::compare_gimple_assign (gimple *s1, gimple *s2)
52200d03 791{
792 tree arg1, arg2;
793 tree_code code1, code2;
794 unsigned i;
795
796 code1 = gimple_expr_code (s1);
797 code2 = gimple_expr_code (s2);
798
799 if (code1 != code2)
800 return false;
801
802 code1 = gimple_assign_rhs_code (s1);
803 code2 = gimple_assign_rhs_code (s2);
804
805 if (code1 != code2)
806 return false;
807
808 for (i = 0; i < gimple_num_ops (s1); i++)
809 {
810 arg1 = gimple_op (s1, i);
811 arg2 = gimple_op (s2, i);
812
05e3f053 813 if (!compare_memory_operand (arg1, arg2))
814 return return_false_with_msg ("memory operands are different");
52200d03 815 }
816
817
818 return true;
819}
820
821/* Verifies for given GIMPLEs S1 and S2 that
822 condition statements are semantically equivalent. */
823
824bool
42acab1c 825func_checker::compare_gimple_cond (gimple *s1, gimple *s2)
52200d03 826{
827 tree t1, t2;
828 tree_code code1, code2;
829
830 code1 = gimple_expr_code (s1);
831 code2 = gimple_expr_code (s2);
832
833 if (code1 != code2)
834 return false;
835
836 t1 = gimple_cond_lhs (s1);
837 t2 = gimple_cond_lhs (s2);
838
839 if (!compare_operand (t1, t2))
840 return false;
841
842 t1 = gimple_cond_rhs (s1);
843 t2 = gimple_cond_rhs (s2);
844
845 return compare_operand (t1, t2);
846}
847
848/* Verifies that tree labels T1 and T2 correspond in FUNC1 and FUNC2. */
849
850bool
851func_checker::compare_tree_ssa_label (tree t1, tree t2)
852{
853 return compare_operand (t1, t2);
854}
855
1a91d914 856/* Verifies for given GIMPLE_LABEL stmts S1 and S2 that
52200d03 857 label statements are semantically equivalent. */
858
859bool
1a91d914 860func_checker::compare_gimple_label (const glabel *g1, const glabel *g2)
52200d03 861{
862 if (m_ignore_labels)
863 return true;
864
865 tree t1 = gimple_label_label (g1);
866 tree t2 = gimple_label_label (g2);
867
868 if (FORCED_LABEL (t1) || FORCED_LABEL (t2))
869 return return_false_with_msg ("FORCED_LABEL");
870
b2e8d25e 871 /* As the pass build BB to label mapping, no further check is needed. */
872 return true;
52200d03 873}
874
1a91d914 875/* Verifies for given GIMPLE_SWITCH stmts S1 and S2 that
52200d03 876 switch statements are semantically equivalent. */
877
878bool
1a91d914 879func_checker::compare_gimple_switch (const gswitch *g1, const gswitch *g2)
52200d03 880{
881 unsigned lsize1, lsize2, i;
882
883 lsize1 = gimple_switch_num_labels (g1);
884 lsize2 = gimple_switch_num_labels (g2);
885
886 if (lsize1 != lsize2)
887 return false;
888
889 tree t1 = gimple_switch_index (g1);
890 tree t2 = gimple_switch_index (g2);
891
892 if (!compare_operand (t1, t2))
893 return false;
894
895 for (i = 0; i < lsize1; i++)
896 {
897 tree label1 = gimple_switch_label (g1, i);
898 tree label2 = gimple_switch_label (g2, i);
899
b90dc9e9 900 /* Label LOW and HIGH comparison. */
901 tree low1 = CASE_LOW (label1);
902 tree low2 = CASE_LOW (label2);
903
904 if (!tree_int_cst_equal (low1, low2))
905 return return_false_with_msg ("case low values are different");
906
907 tree high1 = CASE_HIGH (label1);
908 tree high2 = CASE_HIGH (label2);
909
910 if (!tree_int_cst_equal (high1, high2))
911 return return_false_with_msg ("case high values are different");
912
52200d03 913 if (TREE_CODE (label1) == CASE_LABEL_EXPR
914 && TREE_CODE (label2) == CASE_LABEL_EXPR)
915 {
916 label1 = CASE_LABEL (label1);
917 label2 = CASE_LABEL (label2);
918
919 if (!compare_operand (label1, label2))
920 return return_false_with_msg ("switch label_exprs are different");
921 }
922 else if (!tree_int_cst_equal (label1, label2))
923 return return_false_with_msg ("switch labels are different");
924 }
925
926 return true;
927}
928
1a91d914 929/* Verifies for given GIMPLE_RETURN stmts S1 and S2 that
52200d03 930 return statements are semantically equivalent. */
931
932bool
1a91d914 933func_checker::compare_gimple_return (const greturn *g1, const greturn *g2)
52200d03 934{
935 tree t1, t2;
936
937 t1 = gimple_return_retval (g1);
938 t2 = gimple_return_retval (g2);
939
940 /* Void return type. */
941 if (t1 == NULL && t2 == NULL)
942 return true;
943 else
944 return compare_operand (t1, t2);
945}
946
947/* Verifies for given GIMPLEs S1 and S2 that
948 goto statements are semantically equivalent. */
949
950bool
42acab1c 951func_checker::compare_gimple_goto (gimple *g1, gimple *g2)
52200d03 952{
953 tree dest1, dest2;
954
955 dest1 = gimple_goto_dest (g1);
956 dest2 = gimple_goto_dest (g2);
957
958 if (TREE_CODE (dest1) != TREE_CODE (dest2) || TREE_CODE (dest1) != SSA_NAME)
959 return false;
960
961 return compare_operand (dest1, dest2);
962}
963
1a91d914 964/* Verifies for given GIMPLE_RESX stmts S1 and S2 that
52200d03 965 resx statements are semantically equivalent. */
966
967bool
1a91d914 968func_checker::compare_gimple_resx (const gresx *g1, const gresx *g2)
52200d03 969{
970 return gimple_resx_region (g1) == gimple_resx_region (g2);
971}
972
973/* Verifies for given GIMPLEs S1 and S2 that ASM statements are equivalent.
974 For the beginning, the pass only supports equality for
975 '__asm__ __volatile__ ("", "", "", "memory")'. */
976
977bool
1a91d914 978func_checker::compare_gimple_asm (const gasm *g1, const gasm *g2)
52200d03 979{
980 if (gimple_asm_volatile_p (g1) != gimple_asm_volatile_p (g2))
981 return false;
982
d96a7a49 983 if (gimple_asm_input_p (g1) != gimple_asm_input_p (g2))
984 return false;
985
52200d03 986 if (gimple_asm_ninputs (g1) != gimple_asm_ninputs (g2))
987 return false;
988
989 if (gimple_asm_noutputs (g1) != gimple_asm_noutputs (g2))
990 return false;
991
992 /* We do not suppport goto ASM statement comparison. */
993 if (gimple_asm_nlabels (g1) || gimple_asm_nlabels (g2))
994 return false;
995
996 if (gimple_asm_nclobbers (g1) != gimple_asm_nclobbers (g2))
997 return false;
998
12030b45 999 if (strcmp (gimple_asm_string (g1), gimple_asm_string (g2)) != 0)
1000 return return_false_with_msg ("ASM strings are different");
1001
52200d03 1002 for (unsigned i = 0; i < gimple_asm_ninputs (g1); i++)
1003 {
1004 tree input1 = gimple_asm_input_op (g1, i);
1005 tree input2 = gimple_asm_input_op (g2, i);
1006
1007 if (!compare_tree_list_operand (input1, input2))
1008 return return_false_with_msg ("ASM input is different");
1009 }
1010
1011 for (unsigned i = 0; i < gimple_asm_noutputs (g1); i++)
1012 {
1013 tree output1 = gimple_asm_output_op (g1, i);
1014 tree output2 = gimple_asm_output_op (g2, i);
1015
1016 if (!compare_tree_list_operand (output1, output2))
1017 return return_false_with_msg ("ASM output is different");
1018 }
1019
1020 for (unsigned i = 0; i < gimple_asm_nclobbers (g1); i++)
1021 {
1022 tree clobber1 = gimple_asm_clobber_op (g1, i);
1023 tree clobber2 = gimple_asm_clobber_op (g2, i);
1024
1025 if (!operand_equal_p (TREE_VALUE (clobber1), TREE_VALUE (clobber2),
1026 OEP_ONLY_CONST))
1027 return return_false_with_msg ("ASM clobber is different");
1028 }
1029
1030 return true;
1031}
1032
1033} // ipa_icf_gimple namespace