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