1 /* Interprocedural Identical Code Folding pass
2 Copyright (C) 2014-2019 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 "backend.h"
26 #include "rtl.h"
27 #include "tree.h"
28 #include "gimple.h"
29 #include "tree-pass.h"
30 #include "ssa.h"
31 #include "cgraph.h"
32 #include "data-streamer.h"
33 #include "gimple-pretty-print.h"
34 #include "alias.h"
35 #include "fold-const.h"
36 #include "gimple-iterator.h"
37 #include "ipa-utils.h"
38 #include "tree-eh.h"
39 #include "builtins.h"
40 #include "attribs.h"
41
42 #include "ipa-icf-gimple.h"
43
44 namespace 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
func_checker(tree source_func_decl,tree target_func_decl,bool compare_polymorphic,bool ignore_labels,hash_set<symtab_node * > * ignored_source_nodes,hash_set<symtab_node * > * ignored_target_nodes)53 func_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
~func_checker()82 func_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
90 bool
compare_ssa_name(tree t1,tree t2)91 func_checker::compare_ssa_name (tree t1, tree t2)
92 {
93 gcc_assert (TREE_CODE (t1) == SSA_NAME);
94 gcc_assert (TREE_CODE (t2) == SSA_NAME);
95
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
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
123 return true;
124 }
125
126 /* Verification function for edges E1 and E2. */
127
128 bool
compare_edge(edge e1,edge e2)129 func_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
150 bool
compare_decl(tree t1,tree t2)151 func_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
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))
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
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
195 bool
compatible_polymorphic_types_p(tree t1,tree t2,bool compare_ptr)196 func_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
223 /* Return true if types are compatible from perspective of ICF. */
224 bool
compatible_types_p(tree t1,tree t2)225 func_checker::compatible_types_p (tree t1, tree t2)
226 {
227 if (TREE_CODE (t1) != TREE_CODE (t2))
228 return return_false_with_msg ("different tree types");
229
230 if (TYPE_RESTRICT (t1) != TYPE_RESTRICT (t2))
231 return return_false_with_msg ("restrict flags are different");
232
233 if (!types_compatible_p (t1, t2))
234 return return_false_with_msg ("types are not compatible");
235
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))
245 return return_false_with_msg ("alias sets are different");
246
247 return true;
248 }
249
250 /* Function compare for equality given memory operands T1 and T2. */
251
252 bool
compare_memory_operand(tree t1,tree t2)253 func_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 {
278 if (TREE_THIS_VOLATILE (t1) != TREE_THIS_VOLATILE (t2))
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");
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");
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");
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
327 bool
compare_cst_or_decl(tree t1,tree t2)328 func_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:
345 /* All function decls are in the symbol table and known to match
346 before we start comparing bodies. */
347 return true;
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 {
365 if (t1 == t2)
366 return true;
367
368 int *bb1 = m_label_bb_map.get (t1);
369 int *bb2 = m_label_bb_map.get (t2);
370
371 /* Labels can point to another function (non-local GOTOs). */
372 return return_with_debug (bb1 != NULL && bb2 != NULL && *bb1 == *bb2);
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.
387 If these components, from functions FUNC1 and FUNC2, are equal, true
388 is returned. */
389
390 bool
compare_operand(tree t1,tree t2)391 func_checker::compare_operand (tree t1, tree t2)
392 {
393 tree x1, x2, y1, y2, z1, z2;
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
407 if (TREE_CODE (t1) != TREE_CODE (t2))
408 return return_false ();
409
410 switch (TREE_CODE (t1))
411 {
412 case CONSTRUCTOR:
413 {
414 unsigned length1 = CONSTRUCTOR_NELTS (t1);
415 unsigned length2 = CONSTRUCTOR_NELTS (t2);
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 }
427 case ARRAY_REF:
428 case ARRAY_RANGE_REF:
429 /* First argument is the array, second is the index. */
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 ("");
441
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
466 /* Type of the offset on MEM_REF does not matter. */
467 return known_eq (wi::to_poly_offset (y1), wi::to_poly_offset (y2));
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)
477 && compare_cst_or_decl (y1, y2);
478
479 return return_with_debug (ret);
480 }
481 /* Virtual table call. */
482 case OBJ_TYPE_REF:
483 {
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");
495 if (!compare_operand (OBJ_TYPE_REF_OBJECT (t1),
496 OBJ_TYPE_REF_OBJECT (t2)))
497 return return_false_with_msg ("OBJ_TYPE_REF object mismatch");
498 }
499
500 return return_with_debug (true);
501 }
502 case IMAGPART_EXPR:
503 case REALPART_EXPR:
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 }
512 case BIT_FIELD_REF:
513 {
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
525 return return_with_debug (ret);
526 }
527 case SSA_NAME:
528 return compare_ssa_name (t1, t2);
529 case INTEGER_CST:
530 case COMPLEX_CST:
531 case VECTOR_CST:
532 case STRING_CST:
533 case REAL_CST:
534 case FUNCTION_DECL:
535 case VAR_DECL:
536 case FIELD_DECL:
537 case LABEL_DECL:
538 case PARM_DECL:
539 case RESULT_DECL:
540 case CONST_DECL:
541 return compare_cst_or_decl (t1, t2);
542 default:
543 return return_false_with_msg ("Unknown TREE code reached");
544 }
545 }
546
547 bool
compare_asm_inputs_outputs(tree t1,tree t2)548 func_checker::compare_asm_inputs_outputs (tree t1, tree t2)
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
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
571 t2 = TREE_CHAIN (t2);
572 }
573
574 if (t2)
575 return return_false ();
576
577 return true;
578 }
579
580 /* Verifies that trees T1 and T2 do correspond. */
581
582 bool
compare_variable_decl(tree t1,tree t2)583 func_checker::compare_variable_decl (tree t1, tree t2)
584 {
585 bool ret = false;
586
587 if (t1 == t2)
588 return true;
589
590 if (DECL_ALIGN (t1) != DECL_ALIGN (t2))
591 return return_false_with_msg ("alignments are different");
592
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
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);
604 ret = compare_decl (t1, t2);
605
606 return return_with_debug (ret);
607 }
608
609
610 /* Function visits all gimple labels and creates corresponding
611 mapping between basic blocks and labels. */
612
613 void
parse_labels(sem_bb * bb)614 func_checker::parse_labels (sem_bb *bb)
615 {
616 for (gimple_stmt_iterator gsi = gsi_start_bb (bb->bb); !gsi_end_p (gsi);
617 gsi_next (&gsi))
618 {
619 gimple *stmt = gsi_stmt (gsi);
620
621 if (glabel *label_stmt = dyn_cast <glabel *> (stmt))
622 {
623 tree t = gimple_label_label (label_stmt);
624 gcc_assert (TREE_CODE (t) == LABEL_DECL);
625
626 m_label_bb_map.put (t, bb->bb->index);
627 }
628 }
629 }
630
631 /* Basic block equivalence comparison function that returns true if
632 basic blocks BB1 and BB2 (from functions FUNC1 and FUNC2) correspond.
633
634 In general, a collection of equivalence dictionaries is built for types
635 like SSA names, declarations (VAR_DECL, PARM_DECL, ..). This infrastructure
636 is utilized by every statement-by-statement comparison function. */
637
638 bool
compare_bb(sem_bb * bb1,sem_bb * bb2)639 func_checker::compare_bb (sem_bb *bb1, sem_bb *bb2)
640 {
641 gimple_stmt_iterator gsi1, gsi2;
642 gimple *s1, *s2;
643
644 gsi1 = gsi_start_nondebug_bb (bb1->bb);
645 gsi2 = gsi_start_nondebug_bb (bb2->bb);
646
647 while (!gsi_end_p (gsi1))
648 {
649 if (gsi_end_p (gsi2))
650 return return_false ();
651
652 s1 = gsi_stmt (gsi1);
653 s2 = gsi_stmt (gsi2);
654
655 int eh1 = lookup_stmt_eh_lp_fn
656 (DECL_STRUCT_FUNCTION (m_source_func_decl), s1);
657 int eh2 = lookup_stmt_eh_lp_fn
658 (DECL_STRUCT_FUNCTION (m_target_func_decl), s2);
659
660 if (eh1 != eh2)
661 return return_false_with_msg ("EH regions are different");
662
663 if (gimple_code (s1) != gimple_code (s2))
664 return return_false_with_msg ("gimple codes are different");
665
666 switch (gimple_code (s1))
667 {
668 case GIMPLE_CALL:
669 if (!compare_gimple_call (as_a <gcall *> (s1),
670 as_a <gcall *> (s2)))
671 return return_different_stmts (s1, s2, "GIMPLE_CALL");
672 break;
673 case GIMPLE_ASSIGN:
674 if (!compare_gimple_assign (s1, s2))
675 return return_different_stmts (s1, s2, "GIMPLE_ASSIGN");
676 break;
677 case GIMPLE_COND:
678 if (!compare_gimple_cond (s1, s2))
679 return return_different_stmts (s1, s2, "GIMPLE_COND");
680 break;
681 case GIMPLE_SWITCH:
682 if (!compare_gimple_switch (as_a <gswitch *> (s1),
683 as_a <gswitch *> (s2)))
684 return return_different_stmts (s1, s2, "GIMPLE_SWITCH");
685 break;
686 case GIMPLE_DEBUG:
687 break;
688 case GIMPLE_EH_DISPATCH:
689 if (gimple_eh_dispatch_region (as_a <geh_dispatch *> (s1))
690 != gimple_eh_dispatch_region (as_a <geh_dispatch *> (s2)))
691 return return_different_stmts (s1, s2, "GIMPLE_EH_DISPATCH");
692 break;
693 case GIMPLE_RESX:
694 if (!compare_gimple_resx (as_a <gresx *> (s1),
695 as_a <gresx *> (s2)))
696 return return_different_stmts (s1, s2, "GIMPLE_RESX");
697 break;
698 case GIMPLE_LABEL:
699 if (!compare_gimple_label (as_a <glabel *> (s1),
700 as_a <glabel *> (s2)))
701 return return_different_stmts (s1, s2, "GIMPLE_LABEL");
702 break;
703 case GIMPLE_RETURN:
704 if (!compare_gimple_return (as_a <greturn *> (s1),
705 as_a <greturn *> (s2)))
706 return return_different_stmts (s1, s2, "GIMPLE_RETURN");
707 break;
708 case GIMPLE_GOTO:
709 if (!compare_gimple_goto (s1, s2))
710 return return_different_stmts (s1, s2, "GIMPLE_GOTO");
711 break;
712 case GIMPLE_ASM:
713 if (!compare_gimple_asm (as_a <gasm *> (s1),
714 as_a <gasm *> (s2)))
715 return return_different_stmts (s1, s2, "GIMPLE_ASM");
716 break;
717 case GIMPLE_PREDICT:
718 case GIMPLE_NOP:
719 break;
720 default:
721 return return_false_with_msg ("Unknown GIMPLE code reached");
722 }
723
724 gsi_next_nondebug (&gsi1);
725 gsi_next_nondebug (&gsi2);
726 }
727
728 if (!gsi_end_p (gsi2))
729 return return_false ();
730
731 return true;
732 }
733
734 /* Verifies for given GIMPLEs S1 and S2 that
735 call statements are semantically equivalent. */
736
737 bool
compare_gimple_call(gcall * s1,gcall * s2)738 func_checker::compare_gimple_call (gcall *s1, gcall *s2)
739 {
740 unsigned i;
741 tree t1, t2;
742
743 if (gimple_call_num_args (s1) != gimple_call_num_args (s2))
744 return false;
745
746 t1 = gimple_call_fn (s1);
747 t2 = gimple_call_fn (s2);
748 if (!compare_operand (t1, t2))
749 return return_false ();
750
751 /* Compare flags. */
752 if (gimple_call_internal_p (s1) != gimple_call_internal_p (s2)
753 || gimple_call_ctrl_altering_p (s1) != gimple_call_ctrl_altering_p (s2)
754 || gimple_call_tail_p (s1) != gimple_call_tail_p (s2)
755 || gimple_call_return_slot_opt_p (s1) != gimple_call_return_slot_opt_p (s2)
756 || gimple_call_from_thunk_p (s1) != gimple_call_from_thunk_p (s2)
757 || gimple_call_va_arg_pack_p (s1) != gimple_call_va_arg_pack_p (s2)
758 || gimple_call_alloca_for_var_p (s1) != gimple_call_alloca_for_var_p (s2))
759 return false;
760
761 if (gimple_call_internal_p (s1)
762 && gimple_call_internal_fn (s1) != gimple_call_internal_fn (s2))
763 return false;
764
765 tree fntype1 = gimple_call_fntype (s1);
766 tree fntype2 = gimple_call_fntype (s2);
767 if ((fntype1 && !fntype2)
768 || (!fntype1 && fntype2)
769 || (fntype1 && !types_compatible_p (fntype1, fntype2)))
770 return return_false_with_msg ("call function types are not compatible");
771
772 if (fntype1 && fntype2 && comp_type_attributes (fntype1, fntype2) != 1)
773 return return_false_with_msg ("different fntype attributes");
774
775 tree chain1 = gimple_call_chain (s1);
776 tree chain2 = gimple_call_chain (s2);
777 if ((chain1 && !chain2)
778 || (!chain1 && chain2)
779 || !compare_operand (chain1, chain2))
780 return return_false_with_msg ("static call chains are different");
781
782 /* Checking of argument. */
783 for (i = 0; i < gimple_call_num_args (s1); ++i)
784 {
785 t1 = gimple_call_arg (s1, i);
786 t2 = gimple_call_arg (s2, i);
787
788 if (!compare_memory_operand (t1, t2))
789 return return_false_with_msg ("memory operands are different");
790 }
791
792 /* Return value checking. */
793 t1 = gimple_get_lhs (s1);
794 t2 = gimple_get_lhs (s2);
795
796 return compare_memory_operand (t1, t2);
797 }
798
799
800 /* Verifies for given GIMPLEs S1 and S2 that
801 assignment statements are semantically equivalent. */
802
803 bool
compare_gimple_assign(gimple * s1,gimple * s2)804 func_checker::compare_gimple_assign (gimple *s1, gimple *s2)
805 {
806 tree arg1, arg2;
807 tree_code code1, code2;
808 unsigned i;
809
810 code1 = gimple_expr_code (s1);
811 code2 = gimple_expr_code (s2);
812
813 if (code1 != code2)
814 return false;
815
816 code1 = gimple_assign_rhs_code (s1);
817 code2 = gimple_assign_rhs_code (s2);
818
819 if (code1 != code2)
820 return false;
821
822 for (i = 0; i < gimple_num_ops (s1); i++)
823 {
824 arg1 = gimple_op (s1, i);
825 arg2 = gimple_op (s2, i);
826
827 if (!compare_memory_operand (arg1, arg2))
828 return return_false_with_msg ("memory operands are different");
829 }
830
831
832 return true;
833 }
834
835 /* Verifies for given GIMPLEs S1 and S2 that
836 condition statements are semantically equivalent. */
837
838 bool
compare_gimple_cond(gimple * s1,gimple * s2)839 func_checker::compare_gimple_cond (gimple *s1, gimple *s2)
840 {
841 tree t1, t2;
842 tree_code code1, code2;
843
844 code1 = gimple_expr_code (s1);
845 code2 = gimple_expr_code (s2);
846
847 if (code1 != code2)
848 return false;
849
850 t1 = gimple_cond_lhs (s1);
851 t2 = gimple_cond_lhs (s2);
852
853 if (!compare_operand (t1, t2))
854 return false;
855
856 t1 = gimple_cond_rhs (s1);
857 t2 = gimple_cond_rhs (s2);
858
859 return compare_operand (t1, t2);
860 }
861
862 /* Verifies that tree labels T1 and T2 correspond in FUNC1 and FUNC2. */
863
864 bool
compare_tree_ssa_label(tree t1,tree t2)865 func_checker::compare_tree_ssa_label (tree t1, tree t2)
866 {
867 return compare_operand (t1, t2);
868 }
869
870 /* Verifies for given GIMPLE_LABEL stmts S1 and S2 that
871 label statements are semantically equivalent. */
872
873 bool
compare_gimple_label(const glabel * g1,const glabel * g2)874 func_checker::compare_gimple_label (const glabel *g1, const glabel *g2)
875 {
876 if (m_ignore_labels)
877 return true;
878
879 tree t1 = gimple_label_label (g1);
880 tree t2 = gimple_label_label (g2);
881
882 if (FORCED_LABEL (t1) || FORCED_LABEL (t2))
883 return return_false_with_msg ("FORCED_LABEL");
884
885 /* As the pass build BB to label mapping, no further check is needed. */
886 return true;
887 }
888
889 /* Verifies for given GIMPLE_SWITCH stmts S1 and S2 that
890 switch statements are semantically equivalent. */
891
892 bool
compare_gimple_switch(const gswitch * g1,const gswitch * g2)893 func_checker::compare_gimple_switch (const gswitch *g1, const gswitch *g2)
894 {
895 unsigned lsize1, lsize2, i;
896
897 lsize1 = gimple_switch_num_labels (g1);
898 lsize2 = gimple_switch_num_labels (g2);
899
900 if (lsize1 != lsize2)
901 return false;
902
903 tree t1 = gimple_switch_index (g1);
904 tree t2 = gimple_switch_index (g2);
905
906 if (!compare_operand (t1, t2))
907 return false;
908
909 for (i = 0; i < lsize1; i++)
910 {
911 tree label1 = gimple_switch_label (g1, i);
912 tree label2 = gimple_switch_label (g2, i);
913
914 /* Label LOW and HIGH comparison. */
915 tree low1 = CASE_LOW (label1);
916 tree low2 = CASE_LOW (label2);
917
918 if (!tree_int_cst_equal (low1, low2))
919 return return_false_with_msg ("case low values are different");
920
921 tree high1 = CASE_HIGH (label1);
922 tree high2 = CASE_HIGH (label2);
923
924 if (!tree_int_cst_equal (high1, high2))
925 return return_false_with_msg ("case high values are different");
926
927 if (TREE_CODE (label1) == CASE_LABEL_EXPR
928 && TREE_CODE (label2) == CASE_LABEL_EXPR)
929 {
930 label1 = CASE_LABEL (label1);
931 label2 = CASE_LABEL (label2);
932
933 if (!compare_operand (label1, label2))
934 return return_false_with_msg ("switch label_exprs are different");
935 }
936 else if (!tree_int_cst_equal (label1, label2))
937 return return_false_with_msg ("switch labels are different");
938 }
939
940 return true;
941 }
942
943 /* Verifies for given GIMPLE_RETURN stmts S1 and S2 that
944 return statements are semantically equivalent. */
945
946 bool
compare_gimple_return(const greturn * g1,const greturn * g2)947 func_checker::compare_gimple_return (const greturn *g1, const greturn *g2)
948 {
949 tree t1, t2;
950
951 t1 = gimple_return_retval (g1);
952 t2 = gimple_return_retval (g2);
953
954 /* Void return type. */
955 if (t1 == NULL && t2 == NULL)
956 return true;
957 else
958 return compare_operand (t1, t2);
959 }
960
961 /* Verifies for given GIMPLEs S1 and S2 that
962 goto statements are semantically equivalent. */
963
964 bool
compare_gimple_goto(gimple * g1,gimple * g2)965 func_checker::compare_gimple_goto (gimple *g1, gimple *g2)
966 {
967 tree dest1, dest2;
968
969 dest1 = gimple_goto_dest (g1);
970 dest2 = gimple_goto_dest (g2);
971
972 if (TREE_CODE (dest1) != TREE_CODE (dest2) || TREE_CODE (dest1) != SSA_NAME)
973 return false;
974
975 return compare_operand (dest1, dest2);
976 }
977
978 /* Verifies for given GIMPLE_RESX stmts S1 and S2 that
979 resx statements are semantically equivalent. */
980
981 bool
compare_gimple_resx(const gresx * g1,const gresx * g2)982 func_checker::compare_gimple_resx (const gresx *g1, const gresx *g2)
983 {
984 return gimple_resx_region (g1) == gimple_resx_region (g2);
985 }
986
987 /* Verifies for given GIMPLEs S1 and S2 that ASM statements are equivalent.
988 For the beginning, the pass only supports equality for
989 '__asm__ __volatile__ ("", "", "", "memory")'. */
990
991 bool
compare_gimple_asm(const gasm * g1,const gasm * g2)992 func_checker::compare_gimple_asm (const gasm *g1, const gasm *g2)
993 {
994 if (gimple_asm_volatile_p (g1) != gimple_asm_volatile_p (g2))
995 return false;
996
997 if (gimple_asm_input_p (g1) != gimple_asm_input_p (g2))
998 return false;
999
1000 if (gimple_asm_inline_p (g1) != gimple_asm_inline_p (g2))
1001 return false;
1002
1003 if (gimple_asm_ninputs (g1) != gimple_asm_ninputs (g2))
1004 return false;
1005
1006 if (gimple_asm_noutputs (g1) != gimple_asm_noutputs (g2))
1007 return false;
1008
1009 /* We do not suppport goto ASM statement comparison. */
1010 if (gimple_asm_nlabels (g1) || gimple_asm_nlabels (g2))
1011 return false;
1012
1013 if (gimple_asm_nclobbers (g1) != gimple_asm_nclobbers (g2))
1014 return false;
1015
1016 if (strcmp (gimple_asm_string (g1), gimple_asm_string (g2)) != 0)
1017 return return_false_with_msg ("ASM strings are different");
1018
1019 for (unsigned i = 0; i < gimple_asm_ninputs (g1); i++)
1020 {
1021 tree input1 = gimple_asm_input_op (g1, i);
1022 tree input2 = gimple_asm_input_op (g2, i);
1023
1024 if (!compare_asm_inputs_outputs (input1, input2))
1025 return return_false_with_msg ("ASM input is different");
1026 }
1027
1028 for (unsigned i = 0; i < gimple_asm_noutputs (g1); i++)
1029 {
1030 tree output1 = gimple_asm_output_op (g1, i);
1031 tree output2 = gimple_asm_output_op (g2, i);
1032
1033 if (!compare_asm_inputs_outputs (output1, output2))
1034 return return_false_with_msg ("ASM output is different");
1035 }
1036
1037 for (unsigned i = 0; i < gimple_asm_nclobbers (g1); i++)
1038 {
1039 tree clobber1 = gimple_asm_clobber_op (g1, i);
1040 tree clobber2 = gimple_asm_clobber_op (g2, i);
1041
1042 if (!operand_equal_p (TREE_VALUE (clobber1), TREE_VALUE (clobber2),
1043 OEP_ONLY_CONST))
1044 return return_false_with_msg ("ASM clobber is different");
1045 }
1046
1047 return true;
1048 }
1049
1050 } // ipa_icf_gimple namespace
1051