]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ipa-icf.c
Daily bump.
[thirdparty/gcc.git] / gcc / ipa-icf.c
CommitLineData
b84d4347 1/* Interprocedural Identical Code Folding pass
5624e564 2 Copyright (C) 2014-2015 Free Software Foundation, Inc.
b84d4347
ML
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/* Interprocedural Identical Code Folding for functions and
23 read-only variables.
24
25 The goal of this transformation is to discover functions and read-only
26 variables which do have exactly the same semantics.
27
28 In case of functions,
29 we could either create a virtual clone or do a simple function wrapper
30 that will call equivalent function. If the function is just locally visible,
31 all function calls can be redirected. For read-only variables, we create
32 aliases if possible.
33
34 Optimization pass arranges as follows:
35 1) All functions and read-only variables are visited and internal
36 data structure, either sem_function or sem_variables is created.
37 2) For every symbol from the previous step, VAR_DECL and FUNCTION_DECL are
38 saved and matched to corresponding sem_items.
39 3) These declaration are ignored for equality check and are solved
40 by Value Numbering algorithm published by Alpert, Zadeck in 1992.
41 4) We compute hash value for each symbol.
42 5) Congruence classes are created based on hash value. If hash value are
43 equal, equals function is called and symbols are deeply compared.
44 We must prove that all SSA names, declarations and other items
45 correspond.
46 6) Value Numbering is executed for these classes. At the end of the process
47 all symbol members in remaining classes can be merged.
48 7) Merge operation creates alias in case of read-only variables. For
49 callgraph node, we must decide if we can redirect local calls,
50 create an alias or a thunk.
51
52*/
53
54#include "config.h"
55#include "system.h"
56#include "coretypes.h"
60393bbc
AM
57#include "hash-set.h"
58#include "machmode.h"
40e23961
MC
59#include "vec.h"
60#include "double-int.h"
61#include "input.h"
62#include "alias.h"
63#include "symtab.h"
64#include "options.h"
65#include "wide-int.h"
66#include "inchash.h"
67#include "tree.h"
68#include "fold-const.h"
69#include "predict.h"
60393bbc
AM
70#include "tm.h"
71#include "hard-reg-set.h"
60393bbc
AM
72#include "function.h"
73#include "dominance.h"
74#include "cfg.h"
b84d4347
ML
75#include "basic-block.h"
76#include "tree-ssa-alias.h"
77#include "internal-fn.h"
78#include "gimple-expr.h"
79#include "is-a.h"
80#include "gimple.h"
36566b39
PK
81#include "hashtab.h"
82#include "rtl.h"
83#include "flags.h"
84#include "statistics.h"
85#include "real.h"
86#include "fixed-value.h"
87#include "insn-config.h"
88#include "expmed.h"
89#include "dojump.h"
90#include "explow.h"
91#include "calls.h"
92#include "emit-rtl.h"
93#include "varasm.h"
94#include "stmt.h"
b84d4347
ML
95#include "expr.h"
96#include "gimple-iterator.h"
97#include "gimple-ssa.h"
98#include "tree-cfg.h"
99#include "tree-phinodes.h"
100#include "stringpool.h"
101#include "tree-ssanames.h"
102#include "tree-dfa.h"
103#include "tree-pass.h"
104#include "gimple-pretty-print.h"
c582198b
AM
105#include "hash-map.h"
106#include "plugin-api.h"
107#include "ipa-ref.h"
108#include "cgraph.h"
109#include "alloc-pool.h"
dd912cb8 110#include "symbol-summary.h"
c582198b 111#include "ipa-prop.h"
b84d4347
ML
112#include "ipa-inline.h"
113#include "cfgloop.h"
114#include "except.h"
115#include "hash-table.h"
116#include "coverage.h"
117#include "attribs.h"
118#include "print-tree.h"
119#include "lto-streamer.h"
120#include "data-streamer.h"
121#include "ipa-utils.h"
122#include <list>
123#include "ipa-icf-gimple.h"
124#include "ipa-icf.h"
125
126using namespace ipa_icf_gimple;
127
128namespace ipa_icf {
5ebd0e61
ML
129
130/* Constructor. */
131
132symbol_compare_collection::symbol_compare_collection (symtab_node *node)
133{
134 m_references.create (0);
135 m_interposables.create (0);
136
137 ipa_ref *ref;
138
139 if (is_a <varpool_node *> (node) && DECL_VIRTUAL_P (node->decl))
140 return;
141
142 for (unsigned i = 0; i < node->num_references (); i++)
143 {
144 ref = node->iterate_reference (i, ref);
145 if (ref->address_matters_p ())
146 m_references.safe_push (ref->referred);
147
148 if (ref->referred->get_availability () <= AVAIL_INTERPOSABLE)
149 {
0a7246ee 150 if (ref->address_matters_p ())
5ebd0e61
ML
151 m_references.safe_push (ref->referred);
152 else
153 m_interposables.safe_push (ref->referred);
154 }
155 }
156
157 if (is_a <cgraph_node *> (node))
158 {
159 cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
160
161 for (cgraph_edge *e = cnode->callees; e; e = e->next_callee)
162 if (e->callee->get_availability () <= AVAIL_INTERPOSABLE)
163 m_interposables.safe_push (e->callee);
164 }
165}
166
b84d4347
ML
167/* Constructor for key value pair, where _ITEM is key and _INDEX is a target. */
168
169sem_usage_pair::sem_usage_pair (sem_item *_item, unsigned int _index):
170 item (_item), index (_index)
171{
172}
173
174/* Semantic item constructor for a node of _TYPE, where STACK is used
175 for bitmap memory allocation. */
176
177sem_item::sem_item (sem_item_type _type,
178 bitmap_obstack *stack): type(_type), hash(0)
179{
180 setup (stack);
181}
182
183/* Semantic item constructor for a node of _TYPE, where STACK is used
184 for bitmap memory allocation. The item is based on symtab node _NODE
185 with computed _HASH. */
186
187sem_item::sem_item (sem_item_type _type, symtab_node *_node,
188 hashval_t _hash, bitmap_obstack *stack): type(_type),
189 node (_node), hash (_hash)
190{
191 decl = node->decl;
192 setup (stack);
193}
194
195/* Add reference to a semantic TARGET. */
196
197void
198sem_item::add_reference (sem_item *target)
199{
200 refs.safe_push (target);
201 unsigned index = refs.length ();
202 target->usages.safe_push (new sem_usage_pair(this, index));
203 bitmap_set_bit (target->usage_index_bitmap, index);
204 refs_set.add (target->node);
205}
206
207/* Initialize internal data structures. Bitmap STACK is used for
208 bitmap memory allocation process. */
209
210void
211sem_item::setup (bitmap_obstack *stack)
212{
213 gcc_checking_assert (node);
214
215 refs.create (0);
216 tree_refs.create (0);
217 usages.create (0);
218 usage_index_bitmap = BITMAP_ALLOC (stack);
219}
220
221sem_item::~sem_item ()
222{
223 for (unsigned i = 0; i < usages.length (); i++)
224 delete usages[i];
225
226 refs.release ();
227 tree_refs.release ();
228 usages.release ();
229
230 BITMAP_FREE (usage_index_bitmap);
231}
232
233/* Dump function for debugging purpose. */
234
235DEBUG_FUNCTION void
236sem_item::dump (void)
237{
238 if (dump_file)
239 {
240 fprintf (dump_file, "[%s] %s (%u) (tree:%p)\n", type == FUNC ? "func" : "var",
241 name(), node->order, (void *) node->decl);
242 fprintf (dump_file, " hash: %u\n", get_hash ());
243 fprintf (dump_file, " references: ");
244
245 for (unsigned i = 0; i < refs.length (); i++)
246 fprintf (dump_file, "%s%s ", refs[i]->name (),
247 i < refs.length() - 1 ? "," : "");
248
249 fprintf (dump_file, "\n");
250 }
251}
252
f657d665
ML
253/* Return true if target supports alias symbols. */
254
255bool
256sem_item::target_supports_symbol_aliases_p (void)
257{
258#if !defined (ASM_OUTPUT_DEF) || (!defined(ASM_OUTPUT_WEAK_ALIAS) && !defined (ASM_WEAKEN_DECL))
259 return false;
260#else
261 return true;
262#endif
263}
264
b84d4347
ML
265/* Semantic function constructor that uses STACK as bitmap memory stack. */
266
267sem_function::sem_function (bitmap_obstack *stack): sem_item (FUNC, stack),
268 m_checker (NULL), m_compared_func (NULL)
269{
270 arg_types.create (0);
271 bb_sizes.create (0);
272 bb_sorted.create (0);
273}
274
275/* Constructor based on callgraph node _NODE with computed hash _HASH.
276 Bitmap STACK is used for memory allocation. */
277sem_function::sem_function (cgraph_node *node, hashval_t hash,
278 bitmap_obstack *stack):
279 sem_item (FUNC, node, hash, stack),
280 m_checker (NULL), m_compared_func (NULL)
281{
282 arg_types.create (0);
283 bb_sizes.create (0);
284 bb_sorted.create (0);
285}
286
287sem_function::~sem_function ()
288{
289 for (unsigned i = 0; i < bb_sorted.length (); i++)
e27d328a 290 delete (bb_sorted[i]);
b84d4347
ML
291
292 arg_types.release ();
293 bb_sizes.release ();
294 bb_sorted.release ();
295}
296
297/* Calculates hash value based on a BASIC_BLOCK. */
298
299hashval_t
300sem_function::get_bb_hash (const sem_bb *basic_block)
301{
302 inchash::hash hstate;
303
304 hstate.add_int (basic_block->nondbg_stmt_count);
305 hstate.add_int (basic_block->edge_count);
306
307 return hstate.end ();
308}
309
310/* References independent hash function. */
311
312hashval_t
313sem_function::get_hash (void)
314{
315 if(!hash)
316 {
317 inchash::hash hstate;
318 hstate.add_int (177454); /* Random number for function type. */
319
320 hstate.add_int (arg_count);
321 hstate.add_int (cfg_checksum);
322 hstate.add_int (gcode_hash);
323
324 for (unsigned i = 0; i < bb_sorted.length (); i++)
325 hstate.merge_hash (get_bb_hash (bb_sorted[i]));
326
327 for (unsigned i = 0; i < bb_sizes.length (); i++)
328 hstate.add_int (bb_sizes[i]);
329
330 hash = hstate.end ();
331 }
332
333 return hash;
334}
335
336/* For a given symbol table nodes N1 and N2, we check that FUNCTION_DECLs
337 point to a same function. Comparison can be skipped if IGNORED_NODES
b6cddc7f 338 contains these nodes. ADDRESS indicate if address is taken. */
b84d4347
ML
339
340bool
b6cddc7f
ML
341sem_function::compare_cgraph_references (
342 hash_map <symtab_node *, sem_item *> &ignored_nodes,
343 symtab_node *n1, symtab_node *n2, bool address)
b84d4347 344{
b6cddc7f
ML
345 enum availability avail1, avail2;
346
347 if (address && n1->equal_address_to (n2) == 1)
348 return true;
349 if (!address && n1->semantically_equivalent_p (n2))
b84d4347
ML
350 return true;
351
b6cddc7f
ML
352 n1 = n1->ultimate_alias_target (&avail1);
353 n2 = n2->ultimate_alias_target (&avail2);
354
355 if (avail1 >= AVAIL_INTERPOSABLE && ignored_nodes.get (n1)
356 && avail2 >= AVAIL_INTERPOSABLE && ignored_nodes.get (n2))
357 return true;
b84d4347
ML
358
359 return return_false_with_msg ("different references");
360}
361
362/* If cgraph edges E1 and E2 are indirect calls, verify that
363 ECF flags are the same. */
364
365bool sem_function::compare_edge_flags (cgraph_edge *e1, cgraph_edge *e2)
366{
367 if (e1->indirect_info && e2->indirect_info)
368 {
369 int e1_flags = e1->indirect_info->ecf_flags;
370 int e2_flags = e2->indirect_info->ecf_flags;
371
372 if (e1_flags != e2_flags)
373 return return_false_with_msg ("ICF flags are different");
374 }
375 else if (e1->indirect_info || e2->indirect_info)
376 return false;
377
378 return true;
379}
380
381/* Fast equality function based on knowledge known in WPA. */
382
383bool
384sem_function::equals_wpa (sem_item *item,
385 hash_map <symtab_node *, sem_item *> &ignored_nodes)
386{
387 gcc_assert (item->type == FUNC);
388
389 m_compared_func = static_cast<sem_function *> (item);
390
391 if (arg_types.length () != m_compared_func->arg_types.length ())
392 return return_false_with_msg ("different number of arguments");
393
394 /* Checking types of arguments. */
395 for (unsigned i = 0; i < arg_types.length (); i++)
396 {
397 /* This guard is here for function pointer with attributes (pr59927.c). */
398 if (!arg_types[i] || !m_compared_func->arg_types[i])
399 return return_false_with_msg ("NULL argument type");
400
401 /* Polymorphic comparison is executed just for non-leaf functions. */
1c928ddc
ML
402 bool is_not_leaf = get_node ()->callees != NULL
403 || get_node ()->indirect_calls != NULL;
b84d4347
ML
404
405 if (!func_checker::compatible_types_p (arg_types[i],
406 m_compared_func->arg_types[i],
407 is_not_leaf, i == 0))
408 return return_false_with_msg ("argument type is different");
409 }
410
411 /* Result type checking. */
412 if (!func_checker::compatible_types_p (result_type,
413 m_compared_func->result_type))
414 return return_false_with_msg ("result types are different");
415
416 if (node->num_references () != item->node->num_references ())
417 return return_false_with_msg ("different number of references");
418
419 ipa_ref *ref = NULL, *ref2 = NULL;
420 for (unsigned i = 0; node->iterate_reference (i, ref); i++)
421 {
422 item->node->iterate_reference (i, ref2);
423
b6cddc7f
ML
424 if (!compare_cgraph_references (ignored_nodes, ref->referred,
425 ref2->referred,
426 ref->address_matters_p ()))
b84d4347
ML
427 return false;
428 }
429
430 cgraph_edge *e1 = dyn_cast <cgraph_node *> (node)->callees;
431 cgraph_edge *e2 = dyn_cast <cgraph_node *> (item->node)->callees;
432
433 while (e1 && e2)
434 {
b6cddc7f
ML
435 if (!compare_cgraph_references (ignored_nodes, e1->callee,
436 e2->callee, false))
b84d4347
ML
437 return false;
438
439 e1 = e1->next_callee;
440 e2 = e2->next_callee;
441 }
442
443 if (e1 || e2)
444 return return_false_with_msg ("different number of edges");
445
446 return true;
447}
448
449/* Returns true if the item equals to ITEM given as argument. */
450
451bool
452sem_function::equals (sem_item *item,
453 hash_map <symtab_node *, sem_item *> &ignored_nodes)
454{
455 gcc_assert (item->type == FUNC);
456 bool eq = equals_private (item, ignored_nodes);
457
458 if (m_checker != NULL)
459 {
460 delete m_checker;
461 m_checker = NULL;
462 }
463
464 if (dump_file && (dump_flags & TDF_DETAILS))
465 fprintf (dump_file,
466 "Equals called for:%s:%s (%u:%u) (%s:%s) with result: %s\n\n",
467 name(), item->name (), node->order, item->node->order, asm_name (),
468 item->asm_name (), eq ? "true" : "false");
469
470 return eq;
471}
472
473/* Processes function equality comparison. */
474
475bool
476sem_function::equals_private (sem_item *item,
477 hash_map <symtab_node *, sem_item *> &ignored_nodes)
478{
479 if (item->type != FUNC)
480 return false;
481
482 basic_block bb1, bb2;
483 edge e1, e2;
484 edge_iterator ei1, ei2;
b84d4347
ML
485 bool result = true;
486 tree arg1, arg2;
487
488 m_compared_func = static_cast<sem_function *> (item);
489
490 gcc_assert (decl != item->decl);
491
492 if (bb_sorted.length () != m_compared_func->bb_sorted.length ()
493 || edge_count != m_compared_func->edge_count
494 || cfg_checksum != m_compared_func->cfg_checksum)
495 return return_false ();
496
497 if (!equals_wpa (item, ignored_nodes))
498 return false;
499
3f9f4ae7
ML
500 /* Checking function TARGET and OPTIMIZATION flags. */
501 cl_target_option *tar1 = target_opts_for_fn (decl);
502 cl_target_option *tar2 = target_opts_for_fn (m_compared_func->decl);
503
9f54bf9c 504 if (tar1 != NULL && tar2 != NULL)
3f9f4ae7
ML
505 {
506 if (!cl_target_option_eq (tar1, tar2))
507 {
508 if (dump_file && (dump_flags & TDF_DETAILS))
509 {
eaabbb00
ML
510 fprintf (dump_file, "target flags difference");
511 cl_target_option_print_diff (dump_file, 2, tar1, tar2);
3f9f4ae7
ML
512 }
513
514 return return_false_with_msg ("Target flags are different");
515 }
516 }
517 else if (tar1 != NULL || tar2 != NULL)
518 return return_false_with_msg ("Target flags are different");
519
520 cl_optimization *opt1 = opts_for_fn (decl);
521 cl_optimization *opt2 = opts_for_fn (m_compared_func->decl);
522
523 if (opt1 != NULL && opt2 != NULL)
524 {
525 if (memcmp (opt1, opt2, sizeof(cl_optimization)))
526 {
527 if (dump_file && (dump_flags & TDF_DETAILS))
528 {
eaabbb00
ML
529 fprintf (dump_file, "optimization flags difference");
530 cl_optimization_print_diff (dump_file, 2, opt1, opt2);
3f9f4ae7
ML
531 }
532
533 return return_false_with_msg ("optimization flags are different");
534 }
535 }
536 else if (opt1 != NULL || opt2 != NULL)
537 return return_false_with_msg ("optimization flags are different");
538
b84d4347
ML
539 /* Checking function arguments. */
540 tree decl1 = DECL_ATTRIBUTES (decl);
541 tree decl2 = DECL_ATTRIBUTES (m_compared_func->decl);
542
543 m_checker = new func_checker (decl, m_compared_func->decl,
544 compare_polymorphic_p (),
545 false,
546 &refs_set,
547 &m_compared_func->refs_set);
548 while (decl1)
549 {
550 if (decl2 == NULL)
551 return return_false ();
552
553 if (get_attribute_name (decl1) != get_attribute_name (decl2))
554 return return_false ();
555
556 tree attr_value1 = TREE_VALUE (decl1);
557 tree attr_value2 = TREE_VALUE (decl2);
558
559 if (attr_value1 && attr_value2)
560 {
561 bool ret = m_checker->compare_operand (TREE_VALUE (attr_value1),
562 TREE_VALUE (attr_value2));
563 if (!ret)
564 return return_false_with_msg ("attribute values are different");
565 }
566 else if (!attr_value1 && !attr_value2)
567 {}
568 else
569 return return_false ();
570
571 decl1 = TREE_CHAIN (decl1);
572 decl2 = TREE_CHAIN (decl2);
573 }
574
575 if (decl1 != decl2)
576 return return_false();
577
578
579 for (arg1 = DECL_ARGUMENTS (decl),
580 arg2 = DECL_ARGUMENTS (m_compared_func->decl);
581 arg1; arg1 = DECL_CHAIN (arg1), arg2 = DECL_CHAIN (arg2))
582 if (!m_checker->compare_decl (arg1, arg2))
583 return return_false ();
584
585 /* Fill-up label dictionary. */
586 for (unsigned i = 0; i < bb_sorted.length (); ++i)
587 {
588 m_checker->parse_labels (bb_sorted[i]);
589 m_checker->parse_labels (m_compared_func->bb_sorted[i]);
590 }
591
592 /* Checking all basic blocks. */
593 for (unsigned i = 0; i < bb_sorted.length (); ++i)
594 if(!m_checker->compare_bb (bb_sorted[i], m_compared_func->bb_sorted[i]))
595 return return_false();
596
597 dump_message ("All BBs are equal\n");
598
c190efcc
ML
599 auto_vec <int> bb_dict;
600
b84d4347
ML
601 /* Basic block edges check. */
602 for (unsigned i = 0; i < bb_sorted.length (); ++i)
603 {
b84d4347
ML
604 bb1 = bb_sorted[i]->bb;
605 bb2 = m_compared_func->bb_sorted[i]->bb;
606
607 ei2 = ei_start (bb2->preds);
608
609 for (ei1 = ei_start (bb1->preds); ei_cond (ei1, &e1); ei_next (&ei1))
610 {
611 ei_cond (ei2, &e2);
612
613 if (e1->flags != e2->flags)
614 return return_false_with_msg ("flags comparison returns false");
615
1216ea72 616 if (!bb_dict_test (&bb_dict, e1->src->index, e2->src->index))
b84d4347
ML
617 return return_false_with_msg ("edge comparison returns false");
618
1216ea72 619 if (!bb_dict_test (&bb_dict, e1->dest->index, e2->dest->index))
b84d4347
ML
620 return return_false_with_msg ("BB comparison returns false");
621
622 if (!m_checker->compare_edge (e1, e2))
623 return return_false_with_msg ("edge comparison returns false");
624
625 ei_next (&ei2);
626 }
627 }
628
629 /* Basic block PHI nodes comparison. */
630 for (unsigned i = 0; i < bb_sorted.length (); i++)
631 if (!compare_phi_node (bb_sorted[i]->bb, m_compared_func->bb_sorted[i]->bb))
632 return return_false_with_msg ("PHI node comparison returns false");
633
e8fb91a8
ML
634 /* Compare special function DECL attributes. */
635 if (DECL_FUNCTION_PERSONALITY (decl) != DECL_FUNCTION_PERSONALITY (item->decl))
636 return return_false_with_msg ("function personalities are different");
637
638 if (DECL_DISREGARD_INLINE_LIMITS (decl) != DECL_DISREGARD_INLINE_LIMITS (item->decl))
639 return return_false_with_msg ("DECL_DISREGARD_INLINE_LIMITS are different");
640
641 if (DECL_DECLARED_INLINE_P (decl) != DECL_DECLARED_INLINE_P (item->decl))
642 return return_false_with_msg ("inline attributes are different");
643
644 if (DECL_IS_OPERATOR_NEW (decl) != DECL_IS_OPERATOR_NEW (item->decl))
645 return return_false_with_msg ("operator new flags are different");
646
647 if (DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl)
648 != DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (item->decl))
649 return return_false_with_msg ("intrument function entry exit "
650 "attributes are different");
651
652 if (DECL_NO_LIMIT_STACK (decl) != DECL_NO_LIMIT_STACK (item->decl))
653 return return_false_with_msg ("no stack limit attributes are different");
654
655 if (flags_from_decl_or_type (decl) != flags_from_decl_or_type (item->decl))
656 return return_false_with_msg ("decl_or_type flags are different");
657
b84d4347
ML
658 return result;
659}
660
106b5466
JH
661/* Set LOCAL_P of NODE to true if DATA is non-NULL.
662 Helper for call_for_symbol_thunks_and_aliases. */
663
664static bool
665set_local (cgraph_node *node, void *data)
666{
667 node->local.local = data != NULL;
668 return false;
669}
670
412049de 671/* TREE_ADDRESSABLE of NODE to true.
0a7246ee
JH
672 Helper for call_for_symbol_thunks_and_aliases. */
673
674static bool
675set_addressable (varpool_node *node, void *)
676{
677 TREE_ADDRESSABLE (node->decl) = 1;
678 return false;
679}
680
412049de
JH
681/* Clear DECL_RTL of NODE.
682 Helper for call_for_symbol_thunks_and_aliases. */
683
684static bool
685clear_decl_rtl (symtab_node *node, void *)
686{
687 SET_DECL_RTL (node->decl, NULL);
688 return false;
689}
690
0a7246ee
JH
691/* Redirect all callers of N and its aliases to TO. Remove aliases if
692 possible. Return number of redirections made. */
693
694static int
695redirect_all_callers (cgraph_node *n, cgraph_node *to)
696{
697 int nredirected = 0;
698 ipa_ref *ref;
699
700 while (n->callers)
701 {
702 cgraph_edge *e = n->callers;
703 e->redirect_callee (to);
704 nredirected++;
705 }
706 for (unsigned i = 0; n->iterate_direct_aliases (i, ref);)
707 {
708 bool removed = false;
709 cgraph_node *n_alias = dyn_cast <cgraph_node *> (ref->referring);
710
711 if ((DECL_COMDAT_GROUP (n->decl)
712 && (DECL_COMDAT_GROUP (n->decl)
713 == DECL_COMDAT_GROUP (n_alias->decl)))
714 || (n_alias->get_availability () > AVAIL_INTERPOSABLE
715 && n->get_availability () > AVAIL_INTERPOSABLE))
716 {
717 nredirected += redirect_all_callers (n_alias, to);
718 if (n_alias->can_remove_if_no_direct_calls_p ()
719 && !n_alias->has_aliases_p ())
720 n_alias->remove ();
721 }
722 if (!removed)
723 i++;
724 }
725 return nredirected;
726}
727
b84d4347
ML
728/* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can
729 be applied. */
0a7246ee 730
b84d4347
ML
731bool
732sem_function::merge (sem_item *alias_item)
733{
734 gcc_assert (alias_item->type == FUNC);
735
736 sem_function *alias_func = static_cast<sem_function *> (alias_item);
737
738 cgraph_node *original = get_node ();
0a7246ee 739 cgraph_node *local_original = NULL;
b84d4347 740 cgraph_node *alias = alias_func->get_node ();
b84d4347 741
0a7246ee 742 bool create_wrapper = false;
b84d4347
ML
743 bool create_alias = false;
744 bool redirect_callers = false;
0a7246ee
JH
745 bool remove = false;
746
b84d4347 747 bool original_discardable = false;
c7a06bc1 748 bool original_discarded = false;
b84d4347 749
0a7246ee
JH
750 bool original_address_matters = original->address_matters_p ();
751 bool alias_address_matters = alias->address_matters_p ();
752
753 if (DECL_NO_INLINE_WARNING_P (original->decl)
754 != DECL_NO_INLINE_WARNING_P (alias->decl))
755 {
756 if (dump_file)
757 fprintf (dump_file,
758 "Not unifying; "
759 "DECL_NO_INLINE_WARNING mismatch.\n\n");
760 return false;
761 }
762
b84d4347
ML
763 /* Do not attempt to mix functions from different user sections;
764 we do not know what user intends with those. */
765 if (((DECL_SECTION_NAME (original->decl) && !original->implicit_section)
766 || (DECL_SECTION_NAME (alias->decl) && !alias->implicit_section))
767 && DECL_SECTION_NAME (original->decl) != DECL_SECTION_NAME (alias->decl))
768 {
769 if (dump_file)
770 fprintf (dump_file,
0a7246ee
JH
771 "Not unifying; "
772 "original and alias are in different sections.\n\n");
b84d4347
ML
773 return false;
774 }
775
776 /* See if original is in a section that can be discarded if the main
c7a06bc1 777 symbol is not used. */
0a7246ee 778
c7a06bc1
JH
779 if (original->can_be_discarded_p ())
780 original_discardable = true;
781 /* Also consider case where we have resolution info and we know that
0a7246ee
JH
782 original's definition is not going to be used. In this case we can not
783 create alias to original. */
c7a06bc1
JH
784 if (node->resolution != LDPR_UNKNOWN
785 && !decl_binds_to_current_def_p (node->decl))
786 original_discardable = original_discarded = true;
b84d4347 787
0a7246ee
JH
788 /* Creating a symtab alias is the optimal way to merge.
789 It however can not be used in the following cases:
790
791 1) if ORIGINAL and ALIAS may be possibly compared for address equality.
792 2) if ORIGINAL is in a section that may be discarded by linker or if
793 it is an external functions where we can not create an alias
794 (ORIGINAL_DISCARDABLE)
795 3) if target do not support symbol aliases.
bbcdfb93 796 4) original and alias lie in different comdat groups.
0a7246ee
JH
797
798 If we can not produce alias, we will turn ALIAS into WRAPPER of ORIGINAL
799 and/or redirect all callers from ALIAS to ORIGINAL. */
800 if ((original_address_matters && alias_address_matters)
bbcdfb93
JH
801 || (original_discardable
802 && (!DECL_COMDAT_GROUP (alias->decl)
803 || (DECL_COMDAT_GROUP (alias->decl)
804 != DECL_COMDAT_GROUP (original->decl))))
c7a06bc1 805 || original_discarded
bbcdfb93
JH
806 || !sem_item::target_supports_symbol_aliases_p ()
807 || DECL_COMDAT_GROUP (alias->decl) != DECL_COMDAT_GROUP (original->decl))
b84d4347 808 {
0a7246ee
JH
809 /* First see if we can produce wrapper. */
810
811 /* Do not turn function in one comdat group into wrapper to another
812 comdat group. Other compiler producing the body of the
813 another comdat group may make opossite decision and with unfortunate
814 linker choices this may close a loop. */
c7a06bc1 815 if (DECL_COMDAT_GROUP (original->decl) && DECL_COMDAT_GROUP (alias->decl)
0a7246ee
JH
816 && (DECL_COMDAT_GROUP (alias->decl)
817 != DECL_COMDAT_GROUP (original->decl)))
818 {
819 if (dump_file)
820 fprintf (dump_file,
821 "Wrapper cannot be created because of COMDAT\n");
822 }
823 else if (DECL_STATIC_CHAIN (alias->decl))
824 {
825 if (dump_file)
826 fprintf (dump_file,
827 "Can not create wrapper of nested functions.\n");
828 }
829 /* TODO: We can also deal with variadic functions never calling
830 VA_START. */
831 else if (stdarg_p (TREE_TYPE (alias->decl)))
832 {
833 if (dump_file)
834 fprintf (dump_file,
835 "can not create wrapper of stdarg function.\n");
836 }
837 else if (inline_summaries
838 && inline_summaries->get (alias)->self_size <= 2)
839 {
840 if (dump_file)
841 fprintf (dump_file, "Wrapper creation is not "
842 "profitable (function is too small).\n");
843 }
844 /* If user paid attention to mark function noinline, assume it is
845 somewhat special and do not try to turn it into a wrapper that can
846 not be undone by inliner. */
847 else if (lookup_attribute ("noinline", DECL_ATTRIBUTES (alias->decl)))
848 {
849 if (dump_file)
850 fprintf (dump_file, "Wrappers are not created for noinline.\n");
851 }
852 else
853 create_wrapper = true;
854
855 /* We can redirect local calls in the case both alias and orignal
856 are not interposable. */
b84d4347 857 redirect_callers
0a7246ee
JH
858 = alias->get_availability () > AVAIL_INTERPOSABLE
859 && original->get_availability () > AVAIL_INTERPOSABLE
860 && !alias->instrumented_version;
b84d4347 861
0a7246ee
JH
862 if (!redirect_callers && !create_wrapper)
863 {
864 if (dump_file)
865 fprintf (dump_file, "Not unifying; can not redirect callers nor "
866 "produce wrapper\n\n");
867 return false;
868 }
869
870 /* Work out the symbol the wrapper should call.
871 If ORIGINAL is interposable, we need to call a local alias.
c7a06bc1
JH
872 Also produce local alias (if possible) as an optimization.
873
874 Local aliases can not be created inside comdat groups because that
875 prevents inlining. */
876 if (!original_discardable && !original->get_comdat_group ())
0a7246ee
JH
877 {
878 local_original
879 = dyn_cast <cgraph_node *> (original->noninterposable_alias ());
880 if (!local_original
881 && original->get_availability () > AVAIL_INTERPOSABLE)
882 local_original = original;
0a7246ee
JH
883 }
884 /* If we can not use local alias, fallback to the original
885 when possible. */
886 else if (original->get_availability () > AVAIL_INTERPOSABLE)
887 local_original = original;
c7a06bc1
JH
888
889 /* If original is COMDAT local, we can not really redirect calls outside
890 of its comdat group to it. */
891 if (original->comdat_local_p ())
892 redirect_callers = false;
0a7246ee
JH
893 if (!local_original)
894 {
895 if (dump_file)
896 fprintf (dump_file, "Not unifying; "
897 "can not produce local alias.\n\n");
898 return false;
899 }
f657d665 900
0a7246ee
JH
901 if (!redirect_callers && !create_wrapper)
902 {
903 if (dump_file)
904 fprintf (dump_file, "Not unifying; "
905 "can not redirect callers nor produce a wrapper\n\n");
906 return false;
907 }
908 if (!create_wrapper
909 && !alias->can_remove_if_no_direct_calls_p ())
910 {
911 if (dump_file)
912 fprintf (dump_file, "Not unifying; can not make wrapper and "
913 "function has other uses than direct calls\n\n");
914 return false;
915 }
544dafa6 916 }
0a7246ee
JH
917 else
918 create_alias = true;
544dafa6 919
b84d4347
ML
920 if (redirect_callers)
921 {
0a7246ee 922 int nredirected = redirect_all_callers (alias, local_original);
b84d4347 923
0a7246ee
JH
924 if (nredirected)
925 {
926 alias->icf_merged = true;
927 local_original->icf_merged = true;
b84d4347 928
0a7246ee
JH
929 if (dump_file && nredirected)
930 fprintf (dump_file, "%i local calls have been "
931 "redirected.\n", nredirected);
b84d4347
ML
932 }
933
0a7246ee
JH
934 /* If all callers was redirected, do not produce wrapper. */
935 if (alias->can_remove_if_no_direct_calls_p ()
936 && !alias->has_aliases_p ())
937 {
938 create_wrapper = false;
939 remove = true;
940 }
941 gcc_assert (!create_alias);
b84d4347 942 }
b84d4347
ML
943 else if (create_alias)
944 {
945 alias->icf_merged = true;
946
947 /* Remove the function's body. */
948 ipa_merge_profiles (original, alias);
949 alias->release_body (true);
950 alias->reset ();
412049de
JH
951 /* Notice global symbol possibly produced RTL. */
952 ((symtab_node *)alias)->call_for_symbol_and_aliases (clear_decl_rtl,
953 NULL, true);
b84d4347
ML
954
955 /* Create the alias. */
956 cgraph_node::create_alias (alias_func->decl, decl);
957 alias->resolve_alias (original);
958
106b5466
JH
959 original->call_for_symbol_thunks_and_aliases
960 (set_local, (void *)(size_t) original->local_p (), true);
9d4ded75 961
b84d4347 962 if (dump_file)
0a7246ee 963 fprintf (dump_file, "Unified; Function alias has been created.\n\n");
b84d4347 964 }
0a7246ee 965 if (create_wrapper)
b84d4347 966 {
0a7246ee
JH
967 gcc_assert (!create_alias);
968 alias->icf_merged = true;
969 local_original->icf_merged = true;
b84d4347 970
0a7246ee
JH
971 ipa_merge_profiles (local_original, alias, true);
972 alias->create_wrapper (local_original);
b84d4347 973
0a7246ee
JH
974 if (dump_file)
975 fprintf (dump_file, "Unified; Wrapper has been created.\n\n");
976 }
977 gcc_assert (alias->icf_merged || remove);
978 original->icf_merged = true;
34b42fb0 979
0a7246ee
JH
980 /* Inform the inliner about cross-module merging. */
981 if ((original->lto_file_data || alias->lto_file_data)
982 && original->lto_file_data != alias->lto_file_data)
983 local_original->merged = original->merged = true;
34b42fb0 984
0a7246ee
JH
985 if (remove)
986 {
987 ipa_merge_profiles (original, alias);
988 alias->release_body ();
989 alias->reset ();
990 alias->body_removed = true;
b84d4347 991 alias->icf_merged = true;
b84d4347 992 if (dump_file)
0a7246ee 993 fprintf (dump_file, "Unified; Function body was removed.\n");
b84d4347 994 }
b84d4347
ML
995
996 return true;
997}
998
999/* Semantic item initialization function. */
1000
1001void
1002sem_function::init (void)
1003{
1004 if (in_lto_p)
70486010 1005 get_node ()->get_untransformed_body ();
b84d4347
ML
1006
1007 tree fndecl = node->decl;
1008 function *func = DECL_STRUCT_FUNCTION (fndecl);
1009
1010 gcc_assert (func);
1011 gcc_assert (SSANAMES (func));
1012
1013 ssa_names_size = SSANAMES (func)->length ();
1014 node = node;
1015
1016 decl = fndecl;
1017 region_tree = func->eh->region_tree;
1018
1019 /* iterating all function arguments. */
1020 arg_count = count_formal_params (fndecl);
1021
1022 edge_count = n_edges_for_fn (func);
1023 cfg_checksum = coverage_compute_cfg_checksum (func);
1024
1025 inchash::hash hstate;
1026
1027 basic_block bb;
1028 FOR_EACH_BB_FN (bb, func)
1029 {
1030 unsigned nondbg_stmt_count = 0;
1031
1032 edge e;
a8d93817
JH
1033 for (edge_iterator ei = ei_start (bb->preds); ei_cond (ei, &e);
1034 ei_next (&ei))
b84d4347
ML
1035 cfg_checksum = iterative_hash_host_wide_int (e->flags,
1036 cfg_checksum);
1037
1038 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
1039 gsi_next (&gsi))
1040 {
1041 gimple stmt = gsi_stmt (gsi);
1042
a8d93817
JH
1043 if (gimple_code (stmt) != GIMPLE_DEBUG
1044 && gimple_code (stmt) != GIMPLE_PREDICT)
b84d4347 1045 {
a8d93817 1046 hash_stmt (stmt, hstate);
b84d4347
ML
1047 nondbg_stmt_count++;
1048 }
1049 }
1050
1051 gcode_hash = hstate.end ();
1052 bb_sizes.safe_push (nondbg_stmt_count);
1053
1054 /* Inserting basic block to hash table. */
1055 sem_bb *semantic_bb = new sem_bb (bb, nondbg_stmt_count,
a8d93817
JH
1056 EDGE_COUNT (bb->preds)
1057 + EDGE_COUNT (bb->succs));
b84d4347
ML
1058
1059 bb_sorted.safe_push (semantic_bb);
1060 }
1061
1062 parse_tree_args ();
1063}
1064
a8d93817
JH
1065/* Accumulate to HSTATE a hash of expression EXP.
1066 Identical to inchash::add_expr, but guaranteed to be stable across LTO
1067 and DECL equality classes. */
1068
1069void
1070sem_item::add_expr (const_tree exp, inchash::hash &hstate)
1071{
1072 if (exp == NULL_TREE)
1073 {
1074 hstate.merge_hash (0);
1075 return;
1076 }
1077
1078 /* Handled component can be matched in a cureful way proving equivalence
1079 even if they syntactically differ. Just skip them. */
1080 STRIP_NOPS (exp);
1081 while (handled_component_p (exp))
1082 exp = TREE_OPERAND (exp, 0);
1083
1084 enum tree_code code = TREE_CODE (exp);
1085 hstate.add_int (code);
1086
1087 switch (code)
1088 {
1089 /* Use inchash::add_expr for everything that is LTO stable. */
1090 case VOID_CST:
1091 case INTEGER_CST:
1092 case REAL_CST:
1093 case FIXED_CST:
1094 case STRING_CST:
1095 case COMPLEX_CST:
1096 case VECTOR_CST:
1097 inchash::add_expr (exp, hstate);
1098 break;
1099 case CONSTRUCTOR:
1100 {
1101 unsigned HOST_WIDE_INT idx;
1102 tree value;
1103
1104 hstate.add_wide_int (int_size_in_bytes (TREE_TYPE (exp)));
1105
1106 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, value)
1107 if (value)
1108 add_expr (value, hstate);
1109 break;
1110 }
1111 case ADDR_EXPR:
1112 case FDESC_EXPR:
1113 add_expr (get_base_address (TREE_OPERAND (exp, 0)), hstate);
1114 break;
1115 case SSA_NAME:
1116 case VAR_DECL:
1117 case CONST_DECL:
1118 case PARM_DECL:
1119 hstate.add_wide_int (int_size_in_bytes (TREE_TYPE (exp)));
1120 break;
1121 case MEM_REF:
1122 case POINTER_PLUS_EXPR:
1123 case MINUS_EXPR:
1124 case RANGE_EXPR:
1125 add_expr (TREE_OPERAND (exp, 0), hstate);
1126 add_expr (TREE_OPERAND (exp, 1), hstate);
1127 break;
1128 case PLUS_EXPR:
1129 {
1130 inchash::hash one, two;
1131 add_expr (TREE_OPERAND (exp, 0), one);
1132 add_expr (TREE_OPERAND (exp, 1), two);
1133 hstate.add_commutative (one, two);
1134 }
1135 break;
1136 CASE_CONVERT:
1137 hstate.add_wide_int (int_size_in_bytes (TREE_TYPE (exp)));
1138 return add_expr (TREE_OPERAND (exp, 0), hstate);
1139 default:
1140 break;
1141 }
1142}
1143
b84d4347
ML
1144/* Improve accumulated hash for HSTATE based on a gimple statement STMT. */
1145
1146void
a8d93817 1147sem_function::hash_stmt (gimple stmt, inchash::hash &hstate)
b84d4347
ML
1148{
1149 enum gimple_code code = gimple_code (stmt);
1150
a8d93817 1151 hstate.add_int (code);
b84d4347 1152
a8d93817 1153 switch (code)
b84d4347 1154 {
a8d93817
JH
1155 case GIMPLE_ASSIGN:
1156 if (commutative_tree_code (gimple_assign_rhs_code (stmt))
1157 || commutative_ternary_tree_code (gimple_assign_rhs_code (stmt)))
b84d4347 1158 {
a8d93817 1159 inchash::hash one, two;
b84d4347 1160
a8d93817
JH
1161 add_expr (gimple_assign_rhs1 (stmt), one);
1162 add_expr (gimple_assign_rhs2 (stmt), two);
1163 hstate.add_commutative (one, two);
1164 add_expr (gimple_assign_lhs (stmt), hstate);
1165 break;
b84d4347 1166 }
a8d93817
JH
1167 /* ... fall through ... */
1168 case GIMPLE_CALL:
1169 case GIMPLE_ASM:
1170 case GIMPLE_COND:
1171 case GIMPLE_GOTO:
1172 case GIMPLE_RETURN:
1173 /* All these statements are equivalent if their operands are. */
1174 for (unsigned i = 0; i < gimple_num_ops (stmt); ++i)
1175 add_expr (gimple_op (stmt, i), hstate);
1176 default:
1177 break;
b84d4347
ML
1178 }
1179}
1180
1181
1182/* Return true if polymorphic comparison must be processed. */
1183
1184bool
1185sem_function::compare_polymorphic_p (void)
1186{
1187 return get_node ()->callees != NULL
1c928ddc
ML
1188 || get_node ()->indirect_calls != NULL
1189 || m_compared_func->get_node ()->callees != NULL
1190 || m_compared_func->get_node ()->indirect_calls != NULL;
b84d4347
ML
1191}
1192
1193/* For a given call graph NODE, the function constructs new
1194 semantic function item. */
1195
1196sem_function *
1197sem_function::parse (cgraph_node *node, bitmap_obstack *stack)
1198{
1199 tree fndecl = node->decl;
1200 function *func = DECL_STRUCT_FUNCTION (fndecl);
1201
b6cddc7f 1202 /* TODO: add support for thunks. */
b84d4347
ML
1203
1204 if (!func || !node->has_gimple_body_p ())
1205 return NULL;
1206
1207 if (lookup_attribute_by_prefix ("omp ", DECL_ATTRIBUTES (node->decl)) != NULL)
1208 return NULL;
1209
1210 sem_function *f = new sem_function (node, 0, stack);
1211
1212 f->init ();
1213
1214 return f;
1215}
1216
1217/* Parses function arguments and result type. */
1218
1219void
1220sem_function::parse_tree_args (void)
1221{
1222 tree result;
1223
1224 if (arg_types.exists ())
1225 arg_types.release ();
1226
1227 arg_types.create (4);
1228 tree fnargs = DECL_ARGUMENTS (decl);
1229
1230 for (tree parm = fnargs; parm; parm = DECL_CHAIN (parm))
1231 arg_types.safe_push (DECL_ARG_TYPE (parm));
1232
1233 /* Function result type. */
1234 result = DECL_RESULT (decl);
1235 result_type = result ? TREE_TYPE (result) : NULL;
1236
1237 /* During WPA, we can get arguments by following method. */
1238 if (!fnargs)
1239 {
1240 tree type = TYPE_ARG_TYPES (TREE_TYPE (decl));
1241 for (tree parm = type; parm; parm = TREE_CHAIN (parm))
1242 arg_types.safe_push (TYPE_CANONICAL (TREE_VALUE (parm)));
1243
1244 result_type = TREE_TYPE (TREE_TYPE (decl));
1245 }
1246}
1247
1248/* For given basic blocks BB1 and BB2 (from functions FUNC1 and FUNC),
1249 return true if phi nodes are semantically equivalent in these blocks . */
1250
1251bool
1252sem_function::compare_phi_node (basic_block bb1, basic_block bb2)
1253{
538dd0b7
DM
1254 gphi_iterator si1, si2;
1255 gphi *phi1, *phi2;
b84d4347
ML
1256 unsigned size1, size2, i;
1257 tree t1, t2;
1258 edge e1, e2;
1259
1260 gcc_assert (bb1 != NULL);
1261 gcc_assert (bb2 != NULL);
1262
1263 si2 = gsi_start_phis (bb2);
1264 for (si1 = gsi_start_phis (bb1); !gsi_end_p (si1);
1265 gsi_next (&si1))
1266 {
1267 gsi_next_nonvirtual_phi (&si1);
1268 gsi_next_nonvirtual_phi (&si2);
1269
1270 if (gsi_end_p (si1) && gsi_end_p (si2))
1271 break;
1272
1273 if (gsi_end_p (si1) || gsi_end_p (si2))
1274 return return_false();
1275
538dd0b7
DM
1276 phi1 = si1.phi ();
1277 phi2 = si2.phi ();
b84d4347 1278
59f084e0
ML
1279 tree phi_result1 = gimple_phi_result (phi1);
1280 tree phi_result2 = gimple_phi_result (phi2);
1281
1282 if (!m_checker->compare_operand (phi_result1, phi_result2))
1283 return return_false_with_msg ("PHI results are different");
1284
b84d4347
ML
1285 size1 = gimple_phi_num_args (phi1);
1286 size2 = gimple_phi_num_args (phi2);
1287
1288 if (size1 != size2)
1289 return return_false ();
1290
1291 for (i = 0; i < size1; ++i)
1292 {
1293 t1 = gimple_phi_arg (phi1, i)->def;
1294 t2 = gimple_phi_arg (phi2, i)->def;
1295
1296 if (!m_checker->compare_operand (t1, t2))
1297 return return_false ();
1298
1299 e1 = gimple_phi_arg_edge (phi1, i);
1300 e2 = gimple_phi_arg_edge (phi2, i);
1301
1302 if (!m_checker->compare_edge (e1, e2))
1303 return return_false ();
1304 }
1305
1306 gsi_next (&si2);
1307 }
1308
1309 return true;
1310}
1311
1312/* Returns true if tree T can be compared as a handled component. */
1313
1314bool
1315sem_function::icf_handled_component_p (tree t)
1316{
1317 tree_code tc = TREE_CODE (t);
1318
1319 return ((handled_component_p (t))
1320 || tc == ADDR_EXPR || tc == MEM_REF || tc == REALPART_EXPR
1321 || tc == IMAGPART_EXPR || tc == OBJ_TYPE_REF);
1322}
1323
1324/* Basic blocks dictionary BB_DICT returns true if SOURCE index BB
1325 corresponds to TARGET. */
1326
1327bool
1216ea72 1328sem_function::bb_dict_test (vec<int> *bb_dict, int source, int target)
b84d4347 1329{
c190efcc
ML
1330 source++;
1331 target++;
1332
1216ea72
TS
1333 if (bb_dict->length () <= (unsigned)source)
1334 bb_dict->safe_grow_cleared (source + 1);
c190efcc 1335
1216ea72 1336 if ((*bb_dict)[source] == 0)
b84d4347 1337 {
1216ea72 1338 (*bb_dict)[source] = target;
b84d4347
ML
1339 return true;
1340 }
1341 else
1216ea72 1342 return (*bb_dict)[source] == target;
b84d4347
ML
1343}
1344
1345/* Iterates all tree types in T1 and T2 and returns true if all types
1346 are compatible. If COMPARE_POLYMORPHIC is set to true,
1347 more strict comparison is executed. */
1348
1349bool
1350sem_function::compare_type_list (tree t1, tree t2, bool compare_polymorphic)
1351{
1352 tree tv1, tv2;
1353 tree_code tc1, tc2;
1354
1355 if (!t1 && !t2)
1356 return true;
1357
1358 while (t1 != NULL && t2 != NULL)
1359 {
1360 tv1 = TREE_VALUE (t1);
1361 tv2 = TREE_VALUE (t2);
1362
1363 tc1 = TREE_CODE (tv1);
1364 tc2 = TREE_CODE (tv2);
1365
1366 if (tc1 == NOP_EXPR && tc2 == NOP_EXPR)
1367 {}
1368 else if (tc1 == NOP_EXPR || tc2 == NOP_EXPR)
1369 return false;
1370 else if (!func_checker::compatible_types_p (tv1, tv2, compare_polymorphic))
1371 return false;
1372
1373 t1 = TREE_CHAIN (t1);
1374 t2 = TREE_CHAIN (t2);
1375 }
1376
1377 return !(t1 || t2);
1378}
1379
1380
1381/* Semantic variable constructor that uses STACK as bitmap memory stack. */
1382
1383sem_variable::sem_variable (bitmap_obstack *stack): sem_item (VAR, stack)
1384{
1385}
1386
1387/* Constructor based on varpool node _NODE with computed hash _HASH.
1388 Bitmap STACK is used for memory allocation. */
1389
1390sem_variable::sem_variable (varpool_node *node, hashval_t _hash,
1391 bitmap_obstack *stack): sem_item(VAR,
1392 node, _hash, stack)
1393{
1394 gcc_checking_assert (node);
1395 gcc_checking_assert (get_node ());
1396}
1397
1398/* Returns true if the item equals to ITEM given as argument. */
1399
1400bool
1401sem_variable::equals (sem_item *item,
1402 hash_map <symtab_node *, sem_item *> & ARG_UNUSED (ignored_nodes))
1403{
1404 gcc_assert (item->type == VAR);
1405
1406 sem_variable *v = static_cast<sem_variable *>(item);
1407
1408 if (!ctor || !v->ctor)
1409 return return_false_with_msg ("ctor is missing for semantic variable");
1410
e8fb91a8
ML
1411 if (DECL_IN_CONSTANT_POOL (decl)
1412 && (DECL_IN_CONSTANT_POOL (item->decl)
1413 || item->node->address_matters_p ()))
1414 return return_false_with_msg ("constant pool");
1415
1416 if (DECL_IN_TEXT_SECTION (decl) != DECL_IN_TEXT_SECTION (item->decl))
1417 return return_false_with_msg ("text section");
1418
1419 if (DECL_TLS_MODEL (decl) || DECL_TLS_MODEL (item->decl))
1420 return return_false_with_msg ("TLS model");
1421
b84d4347
ML
1422 return sem_variable::equals (ctor, v->ctor);
1423}
1424
1425/* Compares trees T1 and T2 for semantic equality. */
1426
1427bool
1428sem_variable::equals (tree t1, tree t2)
1429{
1430 tree_code tc1 = TREE_CODE (t1);
1431 tree_code tc2 = TREE_CODE (t2);
1432
1433 if (tc1 != tc2)
1434 return false;
1435
1436 switch (tc1)
1437 {
1438 case CONSTRUCTOR:
1439 {
1440 unsigned len1 = vec_safe_length (CONSTRUCTOR_ELTS (t1));
1441 unsigned len2 = vec_safe_length (CONSTRUCTOR_ELTS (t2));
1442
1443 if (len1 != len2)
1444 return false;
1445
1446 for (unsigned i = 0; i < len1; i++)
1447 if (!sem_variable::equals (CONSTRUCTOR_ELT (t1, i)->value,
1448 CONSTRUCTOR_ELT (t2, i)->value)
1449 || CONSTRUCTOR_ELT (t1, i)->index != CONSTRUCTOR_ELT (t2, i)->index)
1450 return false;
1451
1452 return true;
1453 }
1454 case MEM_REF:
1455 {
1456 tree x1 = TREE_OPERAND (t1, 0);
1457 tree x2 = TREE_OPERAND (t2, 0);
1458 tree y1 = TREE_OPERAND (t1, 1);
1459 tree y2 = TREE_OPERAND (t2, 1);
1460
1461 if (!func_checker::compatible_types_p (TREE_TYPE (x1), TREE_TYPE (x2),
1462 true))
1463 return return_false ();
1464
1465 /* Type of the offset on MEM_REF does not matter. */
1466 return sem_variable::equals (x1, x2)
1467 && wi::to_offset (y1) == wi::to_offset (y2);
1468 }
1469 case NOP_EXPR:
1470 case ADDR_EXPR:
1471 {
1472 tree op1 = TREE_OPERAND (t1, 0);
1473 tree op2 = TREE_OPERAND (t2, 0);
1474 return sem_variable::equals (op1, op2);
1475 }
1476 case FUNCTION_DECL:
1477 case VAR_DECL:
1478 case FIELD_DECL:
1479 case LABEL_DECL:
1480 return t1 == t2;
1481 case INTEGER_CST:
1482 return func_checker::compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2),
1483 true)
1484 && wi::to_offset (t1) == wi::to_offset (t2);
1485 case STRING_CST:
1486 case REAL_CST:
1487 case COMPLEX_CST:
1488 return operand_equal_p (t1, t2, OEP_ONLY_CONST);
1489 case COMPONENT_REF:
1490 case ARRAY_REF:
1491 case POINTER_PLUS_EXPR:
1492 {
1493 tree x1 = TREE_OPERAND (t1, 0);
1494 tree x2 = TREE_OPERAND (t2, 0);
1495 tree y1 = TREE_OPERAND (t1, 1);
1496 tree y2 = TREE_OPERAND (t2, 1);
1497
1498 return sem_variable::equals (x1, x2) && sem_variable::equals (y1, y2);
1499 }
1500 case ERROR_MARK:
1501 return return_false_with_msg ("ERROR_MARK");
1502 default:
1503 return return_false_with_msg ("Unknown TREE code reached");
1504 }
1505}
1506
1507/* Parser function that visits a varpool NODE. */
1508
1509sem_variable *
1510sem_variable::parse (varpool_node *node, bitmap_obstack *stack)
1511{
1512 tree decl = node->decl;
1513
b6cddc7f
ML
1514 if (node->alias)
1515 return NULL;
1516
b84d4347 1517 bool readonly = TYPE_P (decl) ? TYPE_READONLY (decl) : TREE_READONLY (decl);
09cb9532
ML
1518 if (!readonly)
1519 return NULL;
1520
1521 bool can_handle = DECL_VIRTUAL_P (decl)
1522 || flag_merge_constants >= 2
1523 || (!TREE_ADDRESSABLE (decl) && !node->externally_visible);
b84d4347 1524
09cb9532 1525 if (!can_handle || DECL_EXTERNAL (decl))
b84d4347
ML
1526 return NULL;
1527
1528 tree ctor = ctor_for_folding (decl);
1529 if (!ctor)
1530 return NULL;
1531
1532 sem_variable *v = new sem_variable (node, 0, stack);
1533
1534 v->init ();
1535
1536 return v;
1537}
1538
1539/* References independent hash function. */
1540
1541hashval_t
1542sem_variable::get_hash (void)
1543{
1544 if (hash)
1545 return hash;
1546
a8d93817
JH
1547 /* All WPA streamed in symbols should have their hashes computed at compile
1548 time. At this point, the constructor may not be in memory at all.
1549 DECL_INITIAL (decl) would be error_mark_node in that case. */
1550 gcc_assert (!node->lto_file_data);
1551 tree ctor = DECL_INITIAL (decl);
b84d4347
ML
1552 inchash::hash hstate;
1553
1554 hstate.add_int (456346417);
a8d93817
JH
1555 if (DECL_SIZE (decl) && tree_fits_shwi_p (DECL_SIZE (decl)))
1556 hstate.add_wide_int (tree_to_shwi (DECL_SIZE (decl)));
1557 add_expr (ctor, hstate);
b84d4347
ML
1558 hash = hstate.end ();
1559
1560 return hash;
1561}
1562
1563/* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can
1564 be applied. */
1565
1566bool
1567sem_variable::merge (sem_item *alias_item)
1568{
1569 gcc_assert (alias_item->type == VAR);
1570
f657d665
ML
1571 if (!sem_item::target_supports_symbol_aliases_p ())
1572 {
1573 if (dump_file)
0a7246ee
JH
1574 fprintf (dump_file, "Not unifying; "
1575 "Symbol aliases are not supported by target\n\n");
f657d665
ML
1576 return false;
1577 }
1578
b84d4347
ML
1579 sem_variable *alias_var = static_cast<sem_variable *> (alias_item);
1580
1581 varpool_node *original = get_node ();
1582 varpool_node *alias = alias_var->get_node ();
1583 bool original_discardable = false;
1584
0a7246ee
JH
1585 bool original_address_matters = original->address_matters_p ();
1586 bool alias_address_matters = alias->address_matters_p ();
1587
b84d4347 1588 /* See if original is in a section that can be discarded if the main
0a7246ee
JH
1589 symbol is not used.
1590 Also consider case where we have resolution info and we know that
1591 original's definition is not going to be used. In this case we can not
1592 create alias to original. */
1593 if (original->can_be_discarded_p ()
1594 || (node->resolution != LDPR_UNKNOWN
1595 && !decl_binds_to_current_def_p (node->decl)))
b84d4347
ML
1596 original_discardable = true;
1597
1598 gcc_assert (!TREE_ASM_WRITTEN (alias->decl));
1599
0a7246ee
JH
1600 /* Constant pool machinery is not quite ready for aliases.
1601 TODO: varasm code contains logic for merging DECL_IN_CONSTANT_POOL.
1602 For LTO merging does not happen that is an important missing feature.
1603 We can enable merging with LTO if the DECL_IN_CONSTANT_POOL
1604 flag is dropped and non-local symbol name is assigned. */
1605 if (DECL_IN_CONSTANT_POOL (alias->decl)
1606 || DECL_IN_CONSTANT_POOL (original->decl))
b84d4347
ML
1607 {
1608 if (dump_file)
0a7246ee
JH
1609 fprintf (dump_file,
1610 "Not unifying; constant pool variables.\n\n");
1611 return false;
1612 }
b84d4347 1613
0a7246ee
JH
1614 /* Do not attempt to mix functions from different user sections;
1615 we do not know what user intends with those. */
1616 if (((DECL_SECTION_NAME (original->decl) && !original->implicit_section)
1617 || (DECL_SECTION_NAME (alias->decl) && !alias->implicit_section))
1618 && DECL_SECTION_NAME (original->decl) != DECL_SECTION_NAME (alias->decl))
1619 {
1620 if (dump_file)
1621 fprintf (dump_file,
1622 "Not unifying; "
1623 "original and alias are in different sections.\n\n");
b84d4347
ML
1624 return false;
1625 }
0a7246ee
JH
1626
1627 /* We can not merge if address comparsion metters. */
1628 if (original_address_matters && alias_address_matters
1629 && flag_merge_constants < 2)
b84d4347 1630 {
0a7246ee
JH
1631 if (dump_file)
1632 fprintf (dump_file,
1633 "Not unifying; "
1634 "adress of original and alias may be compared.\n\n");
1635 return false;
1636 }
c7a06bc1
JH
1637 if (DECL_COMDAT_GROUP (original->decl) != DECL_COMDAT_GROUP (alias->decl))
1638 {
1639 if (dump_file)
1640 fprintf (dump_file, "Not unifying; alias cannot be created; "
1641 "across comdat group boundary\n\n");
1642
1643 return false;
1644 }
b84d4347 1645
c7a06bc1 1646 if (original_discardable)
0a7246ee
JH
1647 {
1648 if (dump_file)
1649 fprintf (dump_file, "Not unifying; alias cannot be created; "
1650 "target is discardable\n\n");
b84d4347 1651
0a7246ee
JH
1652 return false;
1653 }
1654 else
1655 {
1656 gcc_assert (!original->alias);
1657 gcc_assert (!alias->alias);
b84d4347
ML
1658
1659 alias->analyzed = false;
1660
1661 DECL_INITIAL (alias->decl) = NULL;
412049de
JH
1662 ((symtab_node *)alias)->call_for_symbol_and_aliases (clear_decl_rtl,
1663 NULL, true);
d5e254e1 1664 alias->need_bounds_init = false;
b84d4347 1665 alias->remove_all_references ();
0a7246ee
JH
1666 if (TREE_ADDRESSABLE (alias->decl))
1667 original->call_for_symbol_and_aliases (set_addressable, NULL, true);
b84d4347
ML
1668
1669 varpool_node::create_alias (alias_var->decl, decl);
1670 alias->resolve_alias (original);
1671
1672 if (dump_file)
0a7246ee 1673 fprintf (dump_file, "Unified; Variable alias has been created.\n\n");
b84d4347
ML
1674
1675 return true;
1676 }
1677}
1678
b84d4347
ML
1679/* Dump symbol to FILE. */
1680
1681void
1682sem_variable::dump_to_file (FILE *file)
1683{
1684 gcc_assert (file);
1685
1686 print_node (file, "", decl, 0);
1687 fprintf (file, "\n\n");
1688}
1689
1690/* Iterates though a constructor and identifies tree references
1691 we are interested in semantic function equality. */
1692
1693void
1694sem_variable::parse_tree_refs (tree t)
1695{
1696 switch (TREE_CODE (t))
1697 {
1698 case CONSTRUCTOR:
1699 {
1700 unsigned length = vec_safe_length (CONSTRUCTOR_ELTS (t));
1701
1702 for (unsigned i = 0; i < length; i++)
1703 parse_tree_refs(CONSTRUCTOR_ELT (t, i)->value);
1704
1705 break;
1706 }
1707 case NOP_EXPR:
1708 case ADDR_EXPR:
1709 {
1710 tree op = TREE_OPERAND (t, 0);
1711 parse_tree_refs (op);
1712 break;
1713 }
1714 case FUNCTION_DECL:
1715 {
1716 tree_refs.safe_push (t);
1717 break;
1718 }
1719 default:
1720 break;
1721 }
1722}
1723
1724unsigned int sem_item_optimizer::class_id = 0;
1725
1726sem_item_optimizer::sem_item_optimizer (): worklist (0), m_classes (0),
1727 m_classes_count (0), m_cgraph_node_hooks (NULL), m_varpool_node_hooks (NULL)
1728{
1729 m_items.create (0);
1730 bitmap_obstack_initialize (&m_bmstack);
1731}
1732
1733sem_item_optimizer::~sem_item_optimizer ()
1734{
1735 for (unsigned int i = 0; i < m_items.length (); i++)
1736 delete m_items[i];
1737
1738 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
1739 it != m_classes.end (); ++it)
1740 {
1741 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
1742 delete (*it)->classes[i];
1743
1744 (*it)->classes.release ();
ba2dbfce 1745 free (*it);
b84d4347
ML
1746 }
1747
1748 m_items.release ();
1749
1750 bitmap_obstack_release (&m_bmstack);
1751}
1752
1753/* Write IPA ICF summary for symbols. */
1754
1755void
1756sem_item_optimizer::write_summary (void)
1757{
1758 unsigned int count = 0;
1759
1760 output_block *ob = create_output_block (LTO_section_ipa_icf);
1761 lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
1762 ob->symbol = NULL;
1763
1764 /* Calculate number of symbols to be serialized. */
1765 for (lto_symtab_encoder_iterator lsei = lsei_start_in_partition (encoder);
1766 !lsei_end_p (lsei);
1767 lsei_next_in_partition (&lsei))
1768 {
1769 symtab_node *node = lsei_node (lsei);
1770
1771 if (m_symtab_node_map.get (node))
1772 count++;
1773 }
1774
1775 streamer_write_uhwi (ob, count);
1776
1777 /* Process all of the symbols. */
1778 for (lto_symtab_encoder_iterator lsei = lsei_start_in_partition (encoder);
1779 !lsei_end_p (lsei);
1780 lsei_next_in_partition (&lsei))
1781 {
1782 symtab_node *node = lsei_node (lsei);
1783
1784 sem_item **item = m_symtab_node_map.get (node);
1785
1786 if (item && *item)
1787 {
1788 int node_ref = lto_symtab_encoder_encode (encoder, node);
1789 streamer_write_uhwi_stream (ob->main_stream, node_ref);
1790
1791 streamer_write_uhwi (ob, (*item)->get_hash ());
1792 }
1793 }
1794
1795 streamer_write_char_stream (ob->main_stream, 0);
1796 produce_asm (ob, NULL);
1797 destroy_output_block (ob);
1798}
1799
1800/* Reads a section from LTO stream file FILE_DATA. Input block for DATA
1801 contains LEN bytes. */
1802
1803void
1804sem_item_optimizer::read_section (lto_file_decl_data *file_data,
1805 const char *data, size_t len)
1806{
1807 const lto_function_header *header =
1808 (const lto_function_header *) data;
1809 const int cfg_offset = sizeof (lto_function_header);
1810 const int main_offset = cfg_offset + header->cfg_size;
1811 const int string_offset = main_offset + header->main_size;
1812 data_in *data_in;
1813 unsigned int i;
1814 unsigned int count;
1815
1816 lto_input_block ib_main ((const char *) data + main_offset, 0,
db847fa8 1817 header->main_size, file_data->mode_table);
b84d4347
ML
1818
1819 data_in =
1820 lto_data_in_create (file_data, (const char *) data + string_offset,
1821 header->string_size, vNULL);
1822
1823 count = streamer_read_uhwi (&ib_main);
1824
1825 for (i = 0; i < count; i++)
1826 {
1827 unsigned int index;
1828 symtab_node *node;
1829 lto_symtab_encoder_t encoder;
1830
1831 index = streamer_read_uhwi (&ib_main);
1832 encoder = file_data->symtab_node_encoder;
1833 node = lto_symtab_encoder_deref (encoder, index);
1834
1835 hashval_t hash = streamer_read_uhwi (&ib_main);
1836
1837 gcc_assert (node->definition);
1838
1839 if (dump_file)
1840 fprintf (dump_file, "Symbol added:%s (tree: %p, uid:%u)\n", node->asm_name (),
1841 (void *) node->decl, node->order);
1842
1843 if (is_a<cgraph_node *> (node))
1844 {
1845 cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
1846
1847 m_items.safe_push (new sem_function (cnode, hash, &m_bmstack));
1848 }
1849 else
1850 {
1851 varpool_node *vnode = dyn_cast <varpool_node *> (node);
1852
1853 m_items.safe_push (new sem_variable (vnode, hash, &m_bmstack));
1854 }
1855 }
1856
1857 lto_free_section_data (file_data, LTO_section_ipa_icf, NULL, data,
1858 len);
1859 lto_data_in_delete (data_in);
1860}
1861
1862/* Read IPA IPA ICF summary for symbols. */
1863
1864void
1865sem_item_optimizer::read_summary (void)
1866{
1867 lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
1868 lto_file_decl_data *file_data;
1869 unsigned int j = 0;
1870
1871 while ((file_data = file_data_vec[j++]))
1872 {
1873 size_t len;
1874 const char *data = lto_get_section_data (file_data,
1875 LTO_section_ipa_icf, NULL, &len);
1876
1877 if (data)
1878 read_section (file_data, data, len);
1879 }
1880}
1881
1882/* Register callgraph and varpool hooks. */
1883
1884void
1885sem_item_optimizer::register_hooks (void)
1886{
e3e968e9
ML
1887 if (!m_cgraph_node_hooks)
1888 m_cgraph_node_hooks = symtab->add_cgraph_removal_hook
1889 (&sem_item_optimizer::cgraph_removal_hook, this);
b84d4347 1890
e3e968e9
ML
1891 if (!m_varpool_node_hooks)
1892 m_varpool_node_hooks = symtab->add_varpool_removal_hook
1893 (&sem_item_optimizer::varpool_removal_hook, this);
b84d4347
ML
1894}
1895
1896/* Unregister callgraph and varpool hooks. */
1897
1898void
1899sem_item_optimizer::unregister_hooks (void)
1900{
1901 if (m_cgraph_node_hooks)
1902 symtab->remove_cgraph_removal_hook (m_cgraph_node_hooks);
1903
1904 if (m_varpool_node_hooks)
1905 symtab->remove_varpool_removal_hook (m_varpool_node_hooks);
1906}
1907
1908/* Adds a CLS to hashtable associated by hash value. */
1909
1910void
1911sem_item_optimizer::add_class (congruence_class *cls)
1912{
1913 gcc_assert (cls->members.length ());
1914
1915 congruence_class_group *group = get_group_by_hash (
1916 cls->members[0]->get_hash (),
1917 cls->members[0]->type);
1918 group->classes.safe_push (cls);
1919}
1920
1921/* Gets a congruence class group based on given HASH value and TYPE. */
1922
1923congruence_class_group *
1924sem_item_optimizer::get_group_by_hash (hashval_t hash, sem_item_type type)
1925{
1926 congruence_class_group *item = XNEW (congruence_class_group);
1927 item->hash = hash;
1928 item->type = type;
1929
1930 congruence_class_group **slot = m_classes.find_slot (item, INSERT);
1931
1932 if (*slot)
1933 free (item);
1934 else
1935 {
1936 item->classes.create (1);
1937 *slot = item;
1938 }
1939
1940 return *slot;
1941}
1942
1943/* Callgraph removal hook called for a NODE with a custom DATA. */
1944
1945void
1946sem_item_optimizer::cgraph_removal_hook (cgraph_node *node, void *data)
1947{
1948 sem_item_optimizer *optimizer = (sem_item_optimizer *) data;
1949 optimizer->remove_symtab_node (node);
1950}
1951
1952/* Varpool removal hook called for a NODE with a custom DATA. */
1953
1954void
1955sem_item_optimizer::varpool_removal_hook (varpool_node *node, void *data)
1956{
1957 sem_item_optimizer *optimizer = (sem_item_optimizer *) data;
1958 optimizer->remove_symtab_node (node);
1959}
1960
1961/* Remove symtab NODE triggered by symtab removal hooks. */
1962
1963void
1964sem_item_optimizer::remove_symtab_node (symtab_node *node)
1965{
1966 gcc_assert (!m_classes.elements());
1967
1968 m_removed_items_set.add (node);
1969}
1970
1971void
1972sem_item_optimizer::remove_item (sem_item *item)
1973{
1974 if (m_symtab_node_map.get (item->node))
1975 m_symtab_node_map.remove (item->node);
1976 delete item;
1977}
1978
1979/* Removes all callgraph and varpool nodes that are marked by symtab
1980 as deleted. */
1981
1982void
1983sem_item_optimizer::filter_removed_items (void)
1984{
1985 auto_vec <sem_item *> filtered;
1986
1987 for (unsigned int i = 0; i < m_items.length(); i++)
1988 {
1989 sem_item *item = m_items[i];
1990
90190bb3
ML
1991 if (m_removed_items_set.contains (item->node))
1992 {
b84d4347
ML
1993 remove_item (item);
1994 continue;
90190bb3 1995 }
b84d4347
ML
1996
1997 if (item->type == FUNC)
90190bb3 1998 {
b84d4347
ML
1999 cgraph_node *cnode = static_cast <sem_function *>(item)->get_node ();
2000
90190bb3
ML
2001 bool no_body_function = in_lto_p && (cnode->alias || cnode->body_removed);
2002 if (no_body_function || !opt_for_fn (item->decl, flag_ipa_icf_functions)
2003 || DECL_CXX_CONSTRUCTOR_P (item->decl)
2004 || DECL_CXX_DESTRUCTOR_P (item->decl))
2005 remove_item (item);
2006 else
2007 filtered.safe_push (item);
2008 }
2009 else /* VAR. */
2010 {
2011 if (!flag_ipa_icf_variables)
2012 remove_item (item);
2013 else
2014 filtered.safe_push (item);
2015 }
b84d4347
ML
2016 }
2017
2018 /* Clean-up of released semantic items. */
2019
2020 m_items.release ();
2021 for (unsigned int i = 0; i < filtered.length(); i++)
2022 m_items.safe_push (filtered[i]);
2023}
2024
2025/* Optimizer entry point. */
2026
2027void
2028sem_item_optimizer::execute (void)
2029{
2030 filter_removed_items ();
8b048701
JJ
2031 unregister_hooks ();
2032
b84d4347
ML
2033 build_hash_based_classes ();
2034
2035 if (dump_file)
2036 fprintf (dump_file, "Dump after hash based groups\n");
2037 dump_cong_classes ();
2038
2039 for (unsigned int i = 0; i < m_items.length(); i++)
2040 m_items[i]->init_wpa ();
2041
2042 build_graph ();
2043
2044 subdivide_classes_by_equality (true);
2045
2046 if (dump_file)
2047 fprintf (dump_file, "Dump after WPA based types groups\n");
2048
2049 dump_cong_classes ();
2050
2051 process_cong_reduction ();
2052 verify_classes ();
2053
2054 if (dump_file)
2055 fprintf (dump_file, "Dump after callgraph-based congruence reduction\n");
2056
2057 dump_cong_classes ();
2058
2059 parse_nonsingleton_classes ();
2060 subdivide_classes_by_equality ();
2061
2062 if (dump_file)
2063 fprintf (dump_file, "Dump after full equality comparison of groups\n");
2064
2065 dump_cong_classes ();
2066
2067 unsigned int prev_class_count = m_classes_count;
2068
2069 process_cong_reduction ();
2070 dump_cong_classes ();
2071 verify_classes ();
2072 merge_classes (prev_class_count);
2073
2074 if (dump_file && (dump_flags & TDF_DETAILS))
2075 symtab_node::dump_table (dump_file);
2076}
2077
2078/* Function responsible for visiting all potential functions and
2079 read-only variables that can be merged. */
2080
2081void
2082sem_item_optimizer::parse_funcs_and_vars (void)
2083{
2084 cgraph_node *cnode;
2085
2086 if (flag_ipa_icf_functions)
2087 FOR_EACH_DEFINED_FUNCTION (cnode)
2088 {
2089 sem_function *f = sem_function::parse (cnode, &m_bmstack);
2090 if (f)
2091 {
2092 m_items.safe_push (f);
2093 m_symtab_node_map.put (cnode, f);
2094
2095 if (dump_file)
2096 fprintf (dump_file, "Parsed function:%s\n", f->asm_name ());
2097
2098 if (dump_file && (dump_flags & TDF_DETAILS))
2099 f->dump_to_file (dump_file);
2100 }
2101 else if (dump_file)
2102 fprintf (dump_file, "Not parsed function:%s\n", cnode->asm_name ());
2103 }
2104
2105 varpool_node *vnode;
2106
2107 if (flag_ipa_icf_variables)
2108 FOR_EACH_DEFINED_VARIABLE (vnode)
2109 {
2110 sem_variable *v = sem_variable::parse (vnode, &m_bmstack);
2111
2112 if (v)
2113 {
2114 m_items.safe_push (v);
2115 m_symtab_node_map.put (vnode, v);
2116 }
2117 }
2118}
2119
2120/* Makes pairing between a congruence class CLS and semantic ITEM. */
2121
2122void
2123sem_item_optimizer::add_item_to_class (congruence_class *cls, sem_item *item)
2124{
2125 item->index_in_class = cls->members.length ();
2126 cls->members.safe_push (item);
2127 item->cls = cls;
2128}
2129
2130/* Congruence classes are built by hash value. */
2131
2132void
2133sem_item_optimizer::build_hash_based_classes (void)
2134{
2135 for (unsigned i = 0; i < m_items.length (); i++)
2136 {
2137 sem_item *item = m_items[i];
2138
2139 congruence_class_group *group = get_group_by_hash (item->get_hash (),
2140 item->type);
2141
2142 if (!group->classes.length ())
2143 {
2144 m_classes_count++;
2145 group->classes.safe_push (new congruence_class (class_id++));
2146 }
2147
2148 add_item_to_class (group->classes[0], item);
2149 }
2150}
2151
2152/* Build references according to call graph. */
2153
2154void
2155sem_item_optimizer::build_graph (void)
2156{
2157 for (unsigned i = 0; i < m_items.length (); i++)
2158 {
2159 sem_item *item = m_items[i];
2160 m_symtab_node_map.put (item->node, item);
2161 }
2162
2163 for (unsigned i = 0; i < m_items.length (); i++)
2164 {
2165 sem_item *item = m_items[i];
2166
2167 if (item->type == FUNC)
2168 {
2169 cgraph_node *cnode = dyn_cast <cgraph_node *> (item->node);
2170
2171 cgraph_edge *e = cnode->callees;
2172 while (e)
2173 {
b6cddc7f
ML
2174 sem_item **slot = m_symtab_node_map.get
2175 (e->callee->ultimate_alias_target ());
b84d4347
ML
2176 if (slot)
2177 item->add_reference (*slot);
2178
2179 e = e->next_callee;
2180 }
2181 }
2182
2183 ipa_ref *ref = NULL;
2184 for (unsigned i = 0; item->node->iterate_reference (i, ref); i++)
2185 {
b6cddc7f
ML
2186 sem_item **slot = m_symtab_node_map.get
2187 (ref->referred->ultimate_alias_target ());
b84d4347
ML
2188 if (slot)
2189 item->add_reference (*slot);
2190 }
2191 }
2192}
2193
2194/* Semantic items in classes having more than one element and initialized.
2195 In case of WPA, we load function body. */
2196
2197void
2198sem_item_optimizer::parse_nonsingleton_classes (void)
2199{
2200 unsigned int init_called_count = 0;
2201
2202 for (unsigned i = 0; i < m_items.length (); i++)
2203 if (m_items[i]->cls->members.length () > 1)
2204 {
2205 m_items[i]->init ();
2206 init_called_count++;
2207 }
2208
2209 if (dump_file)
2210 fprintf (dump_file, "Init called for %u items (%.2f%%).\n", init_called_count,
f1c859ee 2211 m_items.length () ? 100.0f * init_called_count / m_items.length (): 0.0f);
b84d4347
ML
2212}
2213
2214/* Equality function for semantic items is used to subdivide existing
2215 classes. If IN_WPA, fast equality function is invoked. */
2216
2217void
2218sem_item_optimizer::subdivide_classes_by_equality (bool in_wpa)
2219{
2220 for (hash_table <congruence_class_group_hash>::iterator it = m_classes.begin ();
2221 it != m_classes.end (); ++it)
2222 {
2223 unsigned int class_count = (*it)->classes.length ();
2224
2225 for (unsigned i = 0; i < class_count; i++)
2226 {
2227 congruence_class *c = (*it)->classes [i];
2228
2229 if (c->members.length() > 1)
2230 {
2231 auto_vec <sem_item *> new_vector;
2232
2233 sem_item *first = c->members[0];
2234 new_vector.safe_push (first);
2235
2236 unsigned class_split_first = (*it)->classes.length ();
2237
2238 for (unsigned j = 1; j < c->members.length (); j++)
2239 {
2240 sem_item *item = c->members[j];
2241
2242 bool equals = in_wpa ? first->equals_wpa (item,
2243 m_symtab_node_map) : first->equals (item, m_symtab_node_map);
2244
2245 if (equals)
2246 new_vector.safe_push (item);
2247 else
2248 {
2249 bool integrated = false;
2250
2251 for (unsigned k = class_split_first; k < (*it)->classes.length (); k++)
2252 {
2253 sem_item *x = (*it)->classes[k]->members[0];
2254 bool equals = in_wpa ? x->equals_wpa (item,
2255 m_symtab_node_map) : x->equals (item, m_symtab_node_map);
2256
2257 if (equals)
2258 {
2259 integrated = true;
2260 add_item_to_class ((*it)->classes[k], item);
2261
2262 break;
2263 }
2264 }
2265
2266 if (!integrated)
2267 {
2268 congruence_class *c = new congruence_class (class_id++);
2269 m_classes_count++;
2270 add_item_to_class (c, item);
2271
2272 (*it)->classes.safe_push (c);
2273 }
2274 }
2275 }
2276
2277 // we replace newly created new_vector for the class we've just splitted
2278 c->members.release ();
2279 c->members.create (new_vector.length ());
2280
2281 for (unsigned int j = 0; j < new_vector.length (); j++)
2282 add_item_to_class (c, new_vector[j]);
2283 }
2284 }
2285 }
2286
2287 verify_classes ();
2288}
2289
5ebd0e61
ML
2290/* Subdivide classes by address references that members of the class
2291 reference. Example can be a pair of functions that have an address
2292 taken from a function. If these addresses are different the class
2293 is split. */
2294
2295unsigned
2296sem_item_optimizer::subdivide_classes_by_sensitive_refs ()
2297{
2298 unsigned newly_created_classes = 0;
2299
2300 for (hash_table <congruence_class_group_hash>::iterator it = m_classes.begin ();
2301 it != m_classes.end (); ++it)
2302 {
2303 unsigned int class_count = (*it)->classes.length ();
2304 auto_vec<congruence_class *> new_classes;
2305
2306 for (unsigned i = 0; i < class_count; i++)
2307 {
2308 congruence_class *c = (*it)->classes [i];
2309
2310 if (c->members.length() > 1)
2311 {
2312 hash_map <symbol_compare_collection *, vec <sem_item *>,
2313 symbol_compare_hashmap_traits> split_map;
2314
2315 for (unsigned j = 0; j < c->members.length (); j++)
2316 {
2317 sem_item *source_node = c->members[j];
2318
2319 symbol_compare_collection *collection = new symbol_compare_collection (source_node->node);
2320
2321 vec <sem_item *> *slot = &split_map.get_or_insert (collection);
2322 gcc_checking_assert (slot);
2323
2324 slot->safe_push (source_node);
2325 }
2326
2327 /* If the map contains more than one key, we have to split the map
2328 appropriately. */
2329 if (split_map.elements () != 1)
2330 {
2331 bool first_class = true;
2332
2333 hash_map <symbol_compare_collection *, vec <sem_item *>,
2334 symbol_compare_hashmap_traits>::iterator it2 = split_map.begin ();
2335 for (; it2 != split_map.end (); ++it2)
2336 {
2337 congruence_class *new_cls;
2338 new_cls = new congruence_class (class_id++);
2339
2340 for (unsigned k = 0; k < (*it2).second.length (); k++)
2341 add_item_to_class (new_cls, (*it2).second[k]);
2342
2343 worklist_push (new_cls);
2344 newly_created_classes++;
2345
2346 if (first_class)
2347 {
2348 (*it)->classes[i] = new_cls;
2349 first_class = false;
2350 }
2351 else
2352 {
2353 new_classes.safe_push (new_cls);
2354 m_classes_count++;
2355 }
2356 }
2357 }
2358 }
2359 }
2360
2361 for (unsigned i = 0; i < new_classes.length (); i++)
2362 (*it)->classes.safe_push (new_classes[i]);
2363 }
2364
2365 return newly_created_classes;
2366}
2367
b84d4347
ML
2368/* Verify congruence classes if checking is enabled. */
2369
2370void
2371sem_item_optimizer::verify_classes (void)
2372{
2373#if ENABLE_CHECKING
2374 for (hash_table <congruence_class_group_hash>::iterator it = m_classes.begin ();
2375 it != m_classes.end (); ++it)
2376 {
2377 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
2378 {
2379 congruence_class *cls = (*it)->classes[i];
2380
2381 gcc_checking_assert (cls);
2382 gcc_checking_assert (cls->members.length () > 0);
2383
2384 for (unsigned int j = 0; j < cls->members.length (); j++)
2385 {
2386 sem_item *item = cls->members[j];
2387
2388 gcc_checking_assert (item);
2389 gcc_checking_assert (item->cls == cls);
2390
2391 for (unsigned k = 0; k < item->usages.length (); k++)
2392 {
2393 sem_usage_pair *usage = item->usages[k];
2394 gcc_checking_assert (usage->item->index_in_class <
2395 usage->item->cls->members.length ());
2396 }
2397 }
2398 }
2399 }
2400#endif
2401}
2402
2403/* Disposes split map traverse function. CLS_PTR is pointer to congruence
2404 class, BSLOT is bitmap slot we want to release. DATA is mandatory,
2405 but unused argument. */
2406
2407bool
2408sem_item_optimizer::release_split_map (congruence_class * const &,
2409 bitmap const &b, traverse_split_pair *)
2410{
2411 bitmap bmp = b;
2412
2413 BITMAP_FREE (bmp);
2414
2415 return true;
2416}
2417
2418/* Process split operation for a class given as pointer CLS_PTR,
2419 where bitmap B splits congruence class members. DATA is used
2420 as argument of split pair. */
2421
2422bool
2423sem_item_optimizer::traverse_congruence_split (congruence_class * const &cls,
2424 bitmap const &b, traverse_split_pair *pair)
2425{
2426 sem_item_optimizer *optimizer = pair->optimizer;
2427 const congruence_class *splitter_cls = pair->cls;
2428
2429 /* If counted bits are greater than zero and less than the number of members
2430 a group will be splitted. */
2431 unsigned popcount = bitmap_count_bits (b);
2432
2433 if (popcount > 0 && popcount < cls->members.length ())
2434 {
2435 congruence_class* newclasses[2] = { new congruence_class (class_id++), new congruence_class (class_id++) };
2436
2437 for (unsigned int i = 0; i < cls->members.length (); i++)
2438 {
2439 int target = bitmap_bit_p (b, i);
2440 congruence_class *tc = newclasses[target];
2441
2442 add_item_to_class (tc, cls->members[i]);
2443 }
2444
2445#ifdef ENABLE_CHECKING
2446 for (unsigned int i = 0; i < 2; i++)
2447 gcc_checking_assert (newclasses[i]->members.length ());
2448#endif
2449
2450 if (splitter_cls == cls)
2451 optimizer->splitter_class_removed = true;
2452
2453 /* Remove old class from worklist if presented. */
2454 bool in_worklist = cls->in_worklist;
2455
2456 if (in_worklist)
2457 cls->in_worklist = false;
2458
2459 congruence_class_group g;
2460 g.hash = cls->members[0]->get_hash ();
2461 g.type = cls->members[0]->type;
2462
2463 congruence_class_group *slot = optimizer->m_classes.find(&g);
2464
2465 for (unsigned int i = 0; i < slot->classes.length (); i++)
2466 if (slot->classes[i] == cls)
2467 {
2468 slot->classes.ordered_remove (i);
2469 break;
2470 }
2471
2472 /* New class will be inserted and integrated to work list. */
2473 for (unsigned int i = 0; i < 2; i++)
2474 optimizer->add_class (newclasses[i]);
2475
2476 /* Two classes replace one, so that increment just by one. */
2477 optimizer->m_classes_count++;
2478
2479 /* If OLD class was presented in the worklist, we remove the class
2480 and replace it will both newly created classes. */
2481 if (in_worklist)
2482 for (unsigned int i = 0; i < 2; i++)
2483 optimizer->worklist_push (newclasses[i]);
2484 else /* Just smaller class is inserted. */
2485 {
2486 unsigned int smaller_index = newclasses[0]->members.length () <
2487 newclasses[1]->members.length () ?
2488 0 : 1;
2489 optimizer->worklist_push (newclasses[smaller_index]);
2490 }
2491
2492 if (dump_file && (dump_flags & TDF_DETAILS))
2493 {
2494 fprintf (dump_file, " congruence class splitted:\n");
2495 cls->dump (dump_file, 4);
2496
2497 fprintf (dump_file, " newly created groups:\n");
2498 for (unsigned int i = 0; i < 2; i++)
2499 newclasses[i]->dump (dump_file, 4);
2500 }
2501
2502 /* Release class if not presented in work list. */
2503 if (!in_worklist)
2504 delete cls;
2505 }
2506
2507
2508 return true;
2509}
2510
2511/* Tests if a class CLS used as INDEXth splits any congruence classes.
2512 Bitmap stack BMSTACK is used for bitmap allocation. */
2513
2514void
2515sem_item_optimizer::do_congruence_step_for_index (congruence_class *cls,
2516 unsigned int index)
2517{
2518 hash_map <congruence_class *, bitmap> split_map;
2519
2520 for (unsigned int i = 0; i < cls->members.length (); i++)
2521 {
2522 sem_item *item = cls->members[i];
2523
2524 /* Iterate all usages that have INDEX as usage of the item. */
2525 for (unsigned int j = 0; j < item->usages.length (); j++)
2526 {
2527 sem_usage_pair *usage = item->usages[j];
2528
2529 if (usage->index != index)
2530 continue;
2531
2532 bitmap *slot = split_map.get (usage->item->cls);
2533 bitmap b;
2534
2535 if(!slot)
2536 {
2537 b = BITMAP_ALLOC (&m_bmstack);
2538 split_map.put (usage->item->cls, b);
2539 }
2540 else
2541 b = *slot;
2542
2543#if ENABLE_CHECKING
2544 gcc_checking_assert (usage->item->cls);
2545 gcc_checking_assert (usage->item->index_in_class <
2546 usage->item->cls->members.length ());
2547#endif
2548
2549 bitmap_set_bit (b, usage->item->index_in_class);
2550 }
2551 }
2552
2553 traverse_split_pair pair;
2554 pair.optimizer = this;
2555 pair.cls = cls;
2556
2557 splitter_class_removed = false;
2558 split_map.traverse
2559 <traverse_split_pair *, sem_item_optimizer::traverse_congruence_split> (&pair);
2560
2561 /* Bitmap clean-up. */
2562 split_map.traverse
2563 <traverse_split_pair *, sem_item_optimizer::release_split_map> (NULL);
2564}
2565
2566/* Every usage of a congruence class CLS is a candidate that can split the
2567 collection of classes. Bitmap stack BMSTACK is used for bitmap
2568 allocation. */
2569
2570void
2571sem_item_optimizer::do_congruence_step (congruence_class *cls)
2572{
2573 bitmap_iterator bi;
2574 unsigned int i;
2575
2576 bitmap usage = BITMAP_ALLOC (&m_bmstack);
2577
2578 for (unsigned int i = 0; i < cls->members.length (); i++)
2579 bitmap_ior_into (usage, cls->members[i]->usage_index_bitmap);
2580
2581 EXECUTE_IF_SET_IN_BITMAP (usage, 0, i, bi)
2582 {
2583 if (dump_file && (dump_flags & TDF_DETAILS))
2584 fprintf (dump_file, " processing congruece step for class: %u, index: %u\n",
2585 cls->id, i);
2586
2587 do_congruence_step_for_index (cls, i);
2588
2589 if (splitter_class_removed)
2590 break;
2591 }
2592
2593 BITMAP_FREE (usage);
2594}
2595
2596/* Adds a newly created congruence class CLS to worklist. */
2597
2598void
2599sem_item_optimizer::worklist_push (congruence_class *cls)
2600{
2601 /* Return if the class CLS is already presented in work list. */
2602 if (cls->in_worklist)
2603 return;
2604
2605 cls->in_worklist = true;
2606 worklist.push_back (cls);
2607}
2608
2609/* Pops a class from worklist. */
2610
2611congruence_class *
2612sem_item_optimizer::worklist_pop (void)
2613{
2614 congruence_class *cls;
2615
2616 while (!worklist.empty ())
2617 {
2618 cls = worklist.front ();
2619 worklist.pop_front ();
2620 if (cls->in_worklist)
2621 {
2622 cls->in_worklist = false;
2623
2624 return cls;
2625 }
2626 else
2627 {
2628 /* Work list item was already intended to be removed.
2629 The only reason for doing it is to split a class.
2630 Thus, the class CLS is deleted. */
2631 delete cls;
2632 }
2633 }
2634
2635 return NULL;
2636}
2637
2638/* Iterative congruence reduction function. */
2639
2640void
2641sem_item_optimizer::process_cong_reduction (void)
2642{
2643 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2644 it != m_classes.end (); ++it)
2645 for (unsigned i = 0; i < (*it)->classes.length (); i++)
2646 if ((*it)->classes[i]->is_class_used ())
2647 worklist_push ((*it)->classes[i]);
2648
2649 if (dump_file)
2650 fprintf (dump_file, "Worklist has been filled with: %lu\n",
10568163 2651 (unsigned long) worklist.size ());
b84d4347
ML
2652
2653 if (dump_file && (dump_flags & TDF_DETAILS))
2654 fprintf (dump_file, "Congruence class reduction\n");
2655
2656 congruence_class *cls;
5ebd0e61
ML
2657
2658 /* Process complete congruence reduction. */
b84d4347
ML
2659 while ((cls = worklist_pop ()) != NULL)
2660 do_congruence_step (cls);
5ebd0e61
ML
2661
2662 /* Subdivide newly created classes according to references. */
2663 unsigned new_classes = subdivide_classes_by_sensitive_refs ();
2664
2665 if (dump_file)
2666 fprintf (dump_file, "Address reference subdivision created: %u "
2667 "new classes.\n", new_classes);
b84d4347
ML
2668}
2669
2670/* Debug function prints all informations about congruence classes. */
2671
2672void
2673sem_item_optimizer::dump_cong_classes (void)
2674{
2675 if (!dump_file)
2676 return;
2677
2678 fprintf (dump_file,
2679 "Congruence classes: %u (unique hash values: %lu), with total: %u items\n",
10568163 2680 m_classes_count, (unsigned long) m_classes.elements(), m_items.length ());
b84d4347
ML
2681
2682 /* Histogram calculation. */
2683 unsigned int max_index = 0;
2684 unsigned int* histogram = XCNEWVEC (unsigned int, m_items.length () + 1);
2685
2686 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2687 it != m_classes.end (); ++it)
2688
2689 for (unsigned i = 0; i < (*it)->classes.length (); i++)
2690 {
2691 unsigned int c = (*it)->classes[i]->members.length ();
2692 histogram[c]++;
2693
2694 if (c > max_index)
2695 max_index = c;
2696 }
2697
2698 fprintf (dump_file,
2699 "Class size histogram [num of members]: number of classe number of classess\n");
2700
2701 for (unsigned int i = 0; i <= max_index; i++)
2702 if (histogram[i])
2703 fprintf (dump_file, "[%u]: %u classes\n", i, histogram[i]);
2704
2705 fprintf (dump_file, "\n\n");
2706
2707
2708 if (dump_flags & TDF_DETAILS)
2709 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2710 it != m_classes.end (); ++it)
2711 {
2712 fprintf (dump_file, " group: with %u classes:\n", (*it)->classes.length ());
2713
2714 for (unsigned i = 0; i < (*it)->classes.length (); i++)
2715 {
2716 (*it)->classes[i]->dump (dump_file, 4);
2717
2718 if(i < (*it)->classes.length () - 1)
2719 fprintf (dump_file, " ");
2720 }
2721 }
2722
2723 free (histogram);
2724}
2725
2726/* After reduction is done, we can declare all items in a group
2727 to be equal. PREV_CLASS_COUNT is start number of classes
2728 before reduction. */
2729
2730void
2731sem_item_optimizer::merge_classes (unsigned int prev_class_count)
2732{
2733 unsigned int item_count = m_items.length ();
2734 unsigned int class_count = m_classes_count;
2735 unsigned int equal_items = item_count - class_count;
2736
2737 unsigned int non_singular_classes_count = 0;
2738 unsigned int non_singular_classes_sum = 0;
2739
2740 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2741 it != m_classes.end (); ++it)
2742 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
2743 {
2744 congruence_class *c = (*it)->classes[i];
2745 if (c->members.length () > 1)
2746 {
2747 non_singular_classes_count++;
2748 non_singular_classes_sum += c->members.length ();
2749 }
2750 }
2751
2752 if (dump_file)
2753 {
2754 fprintf (dump_file, "\nItem count: %u\n", item_count);
2755 fprintf (dump_file, "Congruent classes before: %u, after: %u\n",
2756 prev_class_count, class_count);
2757 fprintf (dump_file, "Average class size before: %.2f, after: %.2f\n",
f1c859ee
ML
2758 prev_class_count ? 1.0f * item_count / prev_class_count : 0.0f,
2759 class_count ? 1.0f * item_count / class_count : 0.0f);
b84d4347 2760 fprintf (dump_file, "Average non-singular class size: %.2f, count: %u\n",
f1c859ee
ML
2761 non_singular_classes_count ? 1.0f * non_singular_classes_sum /
2762 non_singular_classes_count : 0.0f,
b84d4347
ML
2763 non_singular_classes_count);
2764 fprintf (dump_file, "Equal symbols: %u\n", equal_items);
2765 fprintf (dump_file, "Fraction of visited symbols: %.2f%%\n\n",
f1c859ee 2766 item_count ? 100.0f * equal_items / item_count : 0.0f);
b84d4347
ML
2767 }
2768
2769 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2770 it != m_classes.end (); ++it)
2771 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
2772 {
2773 congruence_class *c = (*it)->classes[i];
2774
2775 if (c->members.length () == 1)
2776 continue;
2777
2778 gcc_assert (c->members.length ());
2779
2780 sem_item *source = c->members[0];
2781
2782 for (unsigned int j = 1; j < c->members.length (); j++)
2783 {
2784 sem_item *alias = c->members[j];
b84d4347
ML
2785
2786 if (dump_file)
2787 {
2788 fprintf (dump_file, "Semantic equality hit:%s->%s\n",
2789 source->name (), alias->name ());
2790 fprintf (dump_file, "Assembler symbol names:%s->%s\n",
2791 source->asm_name (), alias->asm_name ());
2792 }
2793
185c9e56
ML
2794 if (lookup_attribute ("no_icf", DECL_ATTRIBUTES (alias->decl)))
2795 {
2796 if (dump_file)
2797 fprintf (dump_file,
2798 "Merge operation is skipped due to no_icf "
2799 "attribute.\n\n");
2800
2801 continue;
2802 }
2803
b84d4347
ML
2804 if (dump_file && (dump_flags & TDF_DETAILS))
2805 {
2806 source->dump_to_file (dump_file);
2807 alias->dump_to_file (dump_file);
2808 }
2809
2810 source->merge (alias);
2811 }
2812 }
2813}
2814
2815/* Dump function prints all class members to a FILE with an INDENT. */
2816
2817void
2818congruence_class::dump (FILE *file, unsigned int indent) const
2819{
2820 FPRINTF_SPACES (file, indent, "class with id: %u, hash: %u, items: %u\n",
2821 id, members[0]->get_hash (), members.length ());
2822
2823 FPUTS_SPACES (file, indent + 2, "");
2824 for (unsigned i = 0; i < members.length (); i++)
2825 fprintf (file, "%s(%p/%u) ", members[i]->asm_name (), (void *) members[i]->decl,
2826 members[i]->node->order);
2827
2828 fprintf (file, "\n");
2829}
2830
2831/* Returns true if there's a member that is used from another group. */
2832
2833bool
2834congruence_class::is_class_used (void)
2835{
2836 for (unsigned int i = 0; i < members.length (); i++)
2837 if (members[i]->usages.length ())
2838 return true;
2839
2840 return false;
2841}
2842
2843/* Initialization and computation of symtab node hash, there data
2844 are propagated later on. */
2845
2846static sem_item_optimizer *optimizer = NULL;
2847
2848/* Generate pass summary for IPA ICF pass. */
2849
2850static void
2851ipa_icf_generate_summary (void)
2852{
2853 if (!optimizer)
2854 optimizer = new sem_item_optimizer ();
2855
e3e968e9 2856 optimizer->register_hooks ();
b84d4347
ML
2857 optimizer->parse_funcs_and_vars ();
2858}
2859
2860/* Write pass summary for IPA ICF pass. */
2861
2862static void
2863ipa_icf_write_summary (void)
2864{
2865 gcc_assert (optimizer);
2866
2867 optimizer->write_summary ();
2868}
2869
2870/* Read pass summary for IPA ICF pass. */
2871
2872static void
2873ipa_icf_read_summary (void)
2874{
2875 if (!optimizer)
2876 optimizer = new sem_item_optimizer ();
2877
2878 optimizer->read_summary ();
2879 optimizer->register_hooks ();
2880}
2881
2882/* Semantic equality exection function. */
2883
2884static unsigned int
2885ipa_icf_driver (void)
2886{
2887 gcc_assert (optimizer);
2888
2889 optimizer->execute ();
b84d4347
ML
2890
2891 delete optimizer;
9612a39a 2892 optimizer = NULL;
b84d4347
ML
2893
2894 return 0;
2895}
2896
2897const pass_data pass_data_ipa_icf =
2898{
2899 IPA_PASS, /* type */
2900 "icf", /* name */
2901 OPTGROUP_IPA, /* optinfo_flags */
2902 TV_IPA_ICF, /* tv_id */
2903 0, /* properties_required */
2904 0, /* properties_provided */
2905 0, /* properties_destroyed */
2906 0, /* todo_flags_start */
2907 0, /* todo_flags_finish */
2908};
2909
2910class pass_ipa_icf : public ipa_opt_pass_d
2911{
2912public:
2913 pass_ipa_icf (gcc::context *ctxt)
2914 : ipa_opt_pass_d (pass_data_ipa_icf, ctxt,
2915 ipa_icf_generate_summary, /* generate_summary */
2916 ipa_icf_write_summary, /* write_summary */
2917 ipa_icf_read_summary, /* read_summary */
2918 NULL, /*
2919 write_optimization_summary */
2920 NULL, /*
2921 read_optimization_summary */
2922 NULL, /* stmt_fixup */
2923 0, /* function_transform_todo_flags_start */
2924 NULL, /* function_transform */
2925 NULL) /* variable_transform */
2926 {}
2927
2928 /* opt_pass methods: */
2929 virtual bool gate (function *)
2930 {
b16650ac 2931 return in_lto_p || flag_ipa_icf_variables || flag_ipa_icf_functions;
b84d4347
ML
2932 }
2933
2934 virtual unsigned int execute (function *)
2935 {
2936 return ipa_icf_driver();
2937 }
2938}; // class pass_ipa_icf
2939
2940} // ipa_icf namespace
2941
2942ipa_opt_pass_d *
2943make_pass_ipa_icf (gcc::context *ctxt)
2944{
2945 return new ipa_icf::pass_ipa_icf (ctxt);
2946}