]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ipa-icf.c
sh.c: Do not include algorithm.
[thirdparty/gcc.git] / gcc / ipa-icf.c
CommitLineData
b84d4347
ML
1/* Interprocedural Identical Code Folding pass
2 Copyright (C) 2014 Free Software Foundation, Inc.
3
4 Contributed by Jan Hubicka <hubicka@ucw.cz> and Martin Liska <mliska@suse.cz>
5
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"
57#include "tree.h"
60393bbc
AM
58#include "predict.h"
59#include "vec.h"
60#include "hashtab.h"
61#include "hash-set.h"
62#include "machmode.h"
63#include "tm.h"
64#include "hard-reg-set.h"
65#include "input.h"
66#include "function.h"
67#include "dominance.h"
68#include "cfg.h"
b84d4347
ML
69#include "basic-block.h"
70#include "tree-ssa-alias.h"
71#include "internal-fn.h"
72#include "gimple-expr.h"
73#include "is-a.h"
74#include "gimple.h"
75#include "expr.h"
76#include "gimple-iterator.h"
77#include "gimple-ssa.h"
78#include "tree-cfg.h"
79#include "tree-phinodes.h"
80#include "stringpool.h"
81#include "tree-ssanames.h"
82#include "tree-dfa.h"
83#include "tree-pass.h"
84#include "gimple-pretty-print.h"
c582198b
AM
85#include "hash-map.h"
86#include "plugin-api.h"
87#include "ipa-ref.h"
88#include "cgraph.h"
89#include "alloc-pool.h"
90#include "ipa-prop.h"
b84d4347
ML
91#include "ipa-inline.h"
92#include "cfgloop.h"
93#include "except.h"
94#include "hash-table.h"
95#include "coverage.h"
96#include "attribs.h"
97#include "print-tree.h"
98#include "lto-streamer.h"
99#include "data-streamer.h"
100#include "ipa-utils.h"
101#include <list>
102#include "ipa-icf-gimple.h"
103#include "ipa-icf.h"
104
105using namespace ipa_icf_gimple;
106
107namespace ipa_icf {
108/* Constructor for key value pair, where _ITEM is key and _INDEX is a target. */
109
110sem_usage_pair::sem_usage_pair (sem_item *_item, unsigned int _index):
111 item (_item), index (_index)
112{
113}
114
115/* Semantic item constructor for a node of _TYPE, where STACK is used
116 for bitmap memory allocation. */
117
118sem_item::sem_item (sem_item_type _type,
119 bitmap_obstack *stack): type(_type), hash(0)
120{
121 setup (stack);
122}
123
124/* Semantic item constructor for a node of _TYPE, where STACK is used
125 for bitmap memory allocation. The item is based on symtab node _NODE
126 with computed _HASH. */
127
128sem_item::sem_item (sem_item_type _type, symtab_node *_node,
129 hashval_t _hash, bitmap_obstack *stack): type(_type),
130 node (_node), hash (_hash)
131{
132 decl = node->decl;
133 setup (stack);
134}
135
136/* Add reference to a semantic TARGET. */
137
138void
139sem_item::add_reference (sem_item *target)
140{
141 refs.safe_push (target);
142 unsigned index = refs.length ();
143 target->usages.safe_push (new sem_usage_pair(this, index));
144 bitmap_set_bit (target->usage_index_bitmap, index);
145 refs_set.add (target->node);
146}
147
148/* Initialize internal data structures. Bitmap STACK is used for
149 bitmap memory allocation process. */
150
151void
152sem_item::setup (bitmap_obstack *stack)
153{
154 gcc_checking_assert (node);
155
156 refs.create (0);
157 tree_refs.create (0);
158 usages.create (0);
159 usage_index_bitmap = BITMAP_ALLOC (stack);
160}
161
162sem_item::~sem_item ()
163{
164 for (unsigned i = 0; i < usages.length (); i++)
165 delete usages[i];
166
167 refs.release ();
168 tree_refs.release ();
169 usages.release ();
170
171 BITMAP_FREE (usage_index_bitmap);
172}
173
174/* Dump function for debugging purpose. */
175
176DEBUG_FUNCTION void
177sem_item::dump (void)
178{
179 if (dump_file)
180 {
181 fprintf (dump_file, "[%s] %s (%u) (tree:%p)\n", type == FUNC ? "func" : "var",
182 name(), node->order, (void *) node->decl);
183 fprintf (dump_file, " hash: %u\n", get_hash ());
184 fprintf (dump_file, " references: ");
185
186 for (unsigned i = 0; i < refs.length (); i++)
187 fprintf (dump_file, "%s%s ", refs[i]->name (),
188 i < refs.length() - 1 ? "," : "");
189
190 fprintf (dump_file, "\n");
191 }
192}
193
f657d665
ML
194/* Return true if target supports alias symbols. */
195
196bool
197sem_item::target_supports_symbol_aliases_p (void)
198{
199#if !defined (ASM_OUTPUT_DEF) || (!defined(ASM_OUTPUT_WEAK_ALIAS) && !defined (ASM_WEAKEN_DECL))
200 return false;
201#else
202 return true;
203#endif
204}
205
b84d4347
ML
206/* Semantic function constructor that uses STACK as bitmap memory stack. */
207
208sem_function::sem_function (bitmap_obstack *stack): sem_item (FUNC, stack),
209 m_checker (NULL), m_compared_func (NULL)
210{
211 arg_types.create (0);
212 bb_sizes.create (0);
213 bb_sorted.create (0);
214}
215
216/* Constructor based on callgraph node _NODE with computed hash _HASH.
217 Bitmap STACK is used for memory allocation. */
218sem_function::sem_function (cgraph_node *node, hashval_t hash,
219 bitmap_obstack *stack):
220 sem_item (FUNC, node, hash, stack),
221 m_checker (NULL), m_compared_func (NULL)
222{
223 arg_types.create (0);
224 bb_sizes.create (0);
225 bb_sorted.create (0);
226}
227
228sem_function::~sem_function ()
229{
230 for (unsigned i = 0; i < bb_sorted.length (); i++)
e27d328a 231 delete (bb_sorted[i]);
b84d4347
ML
232
233 arg_types.release ();
234 bb_sizes.release ();
235 bb_sorted.release ();
236}
237
238/* Calculates hash value based on a BASIC_BLOCK. */
239
240hashval_t
241sem_function::get_bb_hash (const sem_bb *basic_block)
242{
243 inchash::hash hstate;
244
245 hstate.add_int (basic_block->nondbg_stmt_count);
246 hstate.add_int (basic_block->edge_count);
247
248 return hstate.end ();
249}
250
251/* References independent hash function. */
252
253hashval_t
254sem_function::get_hash (void)
255{
256 if(!hash)
257 {
258 inchash::hash hstate;
259 hstate.add_int (177454); /* Random number for function type. */
260
261 hstate.add_int (arg_count);
262 hstate.add_int (cfg_checksum);
263 hstate.add_int (gcode_hash);
264
265 for (unsigned i = 0; i < bb_sorted.length (); i++)
266 hstate.merge_hash (get_bb_hash (bb_sorted[i]));
267
268 for (unsigned i = 0; i < bb_sizes.length (); i++)
269 hstate.add_int (bb_sizes[i]);
270
271 hash = hstate.end ();
272 }
273
274 return hash;
275}
276
277/* For a given symbol table nodes N1 and N2, we check that FUNCTION_DECLs
278 point to a same function. Comparison can be skipped if IGNORED_NODES
279 contains these nodes. */
280
281bool
282sem_function::compare_cgraph_references (hash_map <symtab_node *, sem_item *>
283 &ignored_nodes,
284 symtab_node *n1, symtab_node *n2)
285{
286 if (n1 == n2 || (ignored_nodes.get (n1) && ignored_nodes.get (n2)))
287 return true;
288
289 /* TODO: add more precise comparison for weakrefs, etc. */
290
291 return return_false_with_msg ("different references");
292}
293
294/* If cgraph edges E1 and E2 are indirect calls, verify that
295 ECF flags are the same. */
296
297bool sem_function::compare_edge_flags (cgraph_edge *e1, cgraph_edge *e2)
298{
299 if (e1->indirect_info && e2->indirect_info)
300 {
301 int e1_flags = e1->indirect_info->ecf_flags;
302 int e2_flags = e2->indirect_info->ecf_flags;
303
304 if (e1_flags != e2_flags)
305 return return_false_with_msg ("ICF flags are different");
306 }
307 else if (e1->indirect_info || e2->indirect_info)
308 return false;
309
310 return true;
311}
312
313/* Fast equality function based on knowledge known in WPA. */
314
315bool
316sem_function::equals_wpa (sem_item *item,
317 hash_map <symtab_node *, sem_item *> &ignored_nodes)
318{
319 gcc_assert (item->type == FUNC);
320
321 m_compared_func = static_cast<sem_function *> (item);
322
323 if (arg_types.length () != m_compared_func->arg_types.length ())
324 return return_false_with_msg ("different number of arguments");
325
326 /* Checking types of arguments. */
327 for (unsigned i = 0; i < arg_types.length (); i++)
328 {
329 /* This guard is here for function pointer with attributes (pr59927.c). */
330 if (!arg_types[i] || !m_compared_func->arg_types[i])
331 return return_false_with_msg ("NULL argument type");
332
333 /* Polymorphic comparison is executed just for non-leaf functions. */
334 bool is_not_leaf = get_node ()->callees != NULL;
335
336 if (!func_checker::compatible_types_p (arg_types[i],
337 m_compared_func->arg_types[i],
338 is_not_leaf, i == 0))
339 return return_false_with_msg ("argument type is different");
340 }
341
342 /* Result type checking. */
343 if (!func_checker::compatible_types_p (result_type,
344 m_compared_func->result_type))
345 return return_false_with_msg ("result types are different");
346
347 if (node->num_references () != item->node->num_references ())
348 return return_false_with_msg ("different number of references");
349
350 ipa_ref *ref = NULL, *ref2 = NULL;
351 for (unsigned i = 0; node->iterate_reference (i, ref); i++)
352 {
353 item->node->iterate_reference (i, ref2);
354
355 if (!compare_cgraph_references (ignored_nodes, ref->referred, ref2->referred))
356 return false;
357 }
358
359 cgraph_edge *e1 = dyn_cast <cgraph_node *> (node)->callees;
360 cgraph_edge *e2 = dyn_cast <cgraph_node *> (item->node)->callees;
361
362 while (e1 && e2)
363 {
364 if (!compare_cgraph_references (ignored_nodes, e1->callee, e2->callee))
365 return false;
366
367 e1 = e1->next_callee;
368 e2 = e2->next_callee;
369 }
370
371 if (e1 || e2)
372 return return_false_with_msg ("different number of edges");
373
374 return true;
375}
376
377/* Returns true if the item equals to ITEM given as argument. */
378
379bool
380sem_function::equals (sem_item *item,
381 hash_map <symtab_node *, sem_item *> &ignored_nodes)
382{
383 gcc_assert (item->type == FUNC);
384 bool eq = equals_private (item, ignored_nodes);
385
386 if (m_checker != NULL)
387 {
388 delete m_checker;
389 m_checker = NULL;
390 }
391
392 if (dump_file && (dump_flags & TDF_DETAILS))
393 fprintf (dump_file,
394 "Equals called for:%s:%s (%u:%u) (%s:%s) with result: %s\n\n",
395 name(), item->name (), node->order, item->node->order, asm_name (),
396 item->asm_name (), eq ? "true" : "false");
397
398 return eq;
399}
400
401/* Processes function equality comparison. */
402
403bool
404sem_function::equals_private (sem_item *item,
405 hash_map <symtab_node *, sem_item *> &ignored_nodes)
406{
407 if (item->type != FUNC)
408 return false;
409
410 basic_block bb1, bb2;
411 edge e1, e2;
412 edge_iterator ei1, ei2;
413 int *bb_dict = NULL;
414 bool result = true;
415 tree arg1, arg2;
416
417 m_compared_func = static_cast<sem_function *> (item);
418
419 gcc_assert (decl != item->decl);
420
421 if (bb_sorted.length () != m_compared_func->bb_sorted.length ()
422 || edge_count != m_compared_func->edge_count
423 || cfg_checksum != m_compared_func->cfg_checksum)
424 return return_false ();
425
426 if (!equals_wpa (item, ignored_nodes))
427 return false;
428
429 /* Checking function arguments. */
430 tree decl1 = DECL_ATTRIBUTES (decl);
431 tree decl2 = DECL_ATTRIBUTES (m_compared_func->decl);
432
433 m_checker = new func_checker (decl, m_compared_func->decl,
434 compare_polymorphic_p (),
435 false,
436 &refs_set,
437 &m_compared_func->refs_set);
438 while (decl1)
439 {
440 if (decl2 == NULL)
441 return return_false ();
442
443 if (get_attribute_name (decl1) != get_attribute_name (decl2))
444 return return_false ();
445
446 tree attr_value1 = TREE_VALUE (decl1);
447 tree attr_value2 = TREE_VALUE (decl2);
448
449 if (attr_value1 && attr_value2)
450 {
451 bool ret = m_checker->compare_operand (TREE_VALUE (attr_value1),
452 TREE_VALUE (attr_value2));
453 if (!ret)
454 return return_false_with_msg ("attribute values are different");
455 }
456 else if (!attr_value1 && !attr_value2)
457 {}
458 else
459 return return_false ();
460
461 decl1 = TREE_CHAIN (decl1);
462 decl2 = TREE_CHAIN (decl2);
463 }
464
465 if (decl1 != decl2)
466 return return_false();
467
468
469 for (arg1 = DECL_ARGUMENTS (decl),
470 arg2 = DECL_ARGUMENTS (m_compared_func->decl);
471 arg1; arg1 = DECL_CHAIN (arg1), arg2 = DECL_CHAIN (arg2))
472 if (!m_checker->compare_decl (arg1, arg2))
473 return return_false ();
474
475 /* Fill-up label dictionary. */
476 for (unsigned i = 0; i < bb_sorted.length (); ++i)
477 {
478 m_checker->parse_labels (bb_sorted[i]);
479 m_checker->parse_labels (m_compared_func->bb_sorted[i]);
480 }
481
482 /* Checking all basic blocks. */
483 for (unsigned i = 0; i < bb_sorted.length (); ++i)
484 if(!m_checker->compare_bb (bb_sorted[i], m_compared_func->bb_sorted[i]))
485 return return_false();
486
487 dump_message ("All BBs are equal\n");
488
489 /* Basic block edges check. */
490 for (unsigned i = 0; i < bb_sorted.length (); ++i)
491 {
492 bb_dict = XNEWVEC (int, bb_sorted.length () + 2);
493 memset (bb_dict, -1, (bb_sorted.length () + 2) * sizeof (int));
494
495 bb1 = bb_sorted[i]->bb;
496 bb2 = m_compared_func->bb_sorted[i]->bb;
497
498 ei2 = ei_start (bb2->preds);
499
500 for (ei1 = ei_start (bb1->preds); ei_cond (ei1, &e1); ei_next (&ei1))
501 {
502 ei_cond (ei2, &e2);
503
504 if (e1->flags != e2->flags)
505 return return_false_with_msg ("flags comparison returns false");
506
507 if (!bb_dict_test (bb_dict, e1->src->index, e2->src->index))
508 return return_false_with_msg ("edge comparison returns false");
509
510 if (!bb_dict_test (bb_dict, e1->dest->index, e2->dest->index))
511 return return_false_with_msg ("BB comparison returns false");
512
513 if (!m_checker->compare_edge (e1, e2))
514 return return_false_with_msg ("edge comparison returns false");
515
516 ei_next (&ei2);
517 }
518 }
519
520 /* Basic block PHI nodes comparison. */
521 for (unsigned i = 0; i < bb_sorted.length (); i++)
522 if (!compare_phi_node (bb_sorted[i]->bb, m_compared_func->bb_sorted[i]->bb))
523 return return_false_with_msg ("PHI node comparison returns false");
524
525 return result;
526}
527
528/* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can
529 be applied. */
530bool
531sem_function::merge (sem_item *alias_item)
532{
533 gcc_assert (alias_item->type == FUNC);
534
535 sem_function *alias_func = static_cast<sem_function *> (alias_item);
536
537 cgraph_node *original = get_node ();
538 cgraph_node *local_original = original;
539 cgraph_node *alias = alias_func->get_node ();
540 bool original_address_matters;
541 bool alias_address_matters;
542
543 bool create_thunk = false;
544 bool create_alias = false;
545 bool redirect_callers = false;
546 bool original_discardable = false;
547
548 /* Do not attempt to mix functions from different user sections;
549 we do not know what user intends with those. */
550 if (((DECL_SECTION_NAME (original->decl) && !original->implicit_section)
551 || (DECL_SECTION_NAME (alias->decl) && !alias->implicit_section))
552 && DECL_SECTION_NAME (original->decl) != DECL_SECTION_NAME (alias->decl))
553 {
554 if (dump_file)
555 fprintf (dump_file,
556 "Not unifying; original and alias are in different sections.\n\n");
557 return false;
558 }
559
560 /* See if original is in a section that can be discarded if the main
561 symbol is not used. */
562 if (DECL_EXTERNAL (original->decl))
563 original_discardable = true;
564 if (original->resolution == LDPR_PREEMPTED_REG
565 || original->resolution == LDPR_PREEMPTED_IR)
566 original_discardable = true;
567 if (original->can_be_discarded_p ())
568 original_discardable = true;
569
570 /* See if original and/or alias address can be compared for equality. */
571 original_address_matters
572 = (!DECL_VIRTUAL_P (original->decl)
573 && (original->externally_visible
574 || original->address_taken_from_non_vtable_p ()));
575 alias_address_matters
576 = (!DECL_VIRTUAL_P (alias->decl)
577 && (alias->externally_visible
578 || alias->address_taken_from_non_vtable_p ()));
579
580 /* If alias and original can be compared for address equality, we need
581 to create a thunk. Also we can not create extra aliases into discardable
582 section (or we risk link failures when section is discarded). */
583 if ((original_address_matters
584 && alias_address_matters)
585 || original_discardable)
586 {
587 create_thunk = !stdarg_p (TREE_TYPE (alias->decl));
588 create_alias = false;
589 /* When both alias and original are not overwritable, we can save
590 the extra thunk wrapper for direct calls. */
591 redirect_callers
592 = (!original_discardable
593 && alias->get_availability () > AVAIL_INTERPOSABLE
d5e254e1
IE
594 && original->get_availability () > AVAIL_INTERPOSABLE
595 && !alias->instrumented_version);
b84d4347
ML
596 }
597 else
598 {
599 create_alias = true;
600 create_thunk = false;
601 redirect_callers = false;
602 }
603
f657d665
ML
604 if (create_alias && (DECL_COMDAT_GROUP (alias->decl)
605 || !sem_item::target_supports_symbol_aliases_p ()))
b84d4347
ML
606 {
607 create_alias = false;
608 create_thunk = true;
609 }
610
611 /* We want thunk to always jump to the local function body
612 unless the body is comdat and may be optimized out. */
613 if ((create_thunk || redirect_callers)
614 && (!original_discardable
615 || (DECL_COMDAT_GROUP (original->decl)
616 && (DECL_COMDAT_GROUP (original->decl)
617 == DECL_COMDAT_GROUP (alias->decl)))))
618 local_original
619 = dyn_cast <cgraph_node *> (original->noninterposable_alias ());
620
f657d665
ML
621 if (!local_original)
622 {
623 if (dump_file)
624 fprintf (dump_file, "Noninterposable alias cannot be created.\n\n");
625
626 return false;
627 }
628
b84d4347
ML
629 if (redirect_callers)
630 {
631 /* If alias is non-overwritable then
632 all direct calls are safe to be redirected to the original. */
633 bool redirected = false;
634 while (alias->callers)
635 {
636 cgraph_edge *e = alias->callers;
637 e->redirect_callee (local_original);
638 push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
639
640 if (e->call_stmt)
641 e->redirect_call_stmt_to_callee ();
642
643 pop_cfun ();
644 redirected = true;
645 }
646
647 alias->icf_merged = true;
648
649 /* The alias function is removed if symbol address
650 does not matter. */
651 if (!alias_address_matters)
652 alias->remove ();
653
654 if (dump_file && redirected)
655 fprintf (dump_file, "Callgraph local calls have been redirected.\n\n");
656 }
657 /* If the condtion above is not met, we are lucky and can turn the
658 function into real alias. */
659 else if (create_alias)
660 {
661 alias->icf_merged = true;
662
663 /* Remove the function's body. */
664 ipa_merge_profiles (original, alias);
665 alias->release_body (true);
666 alias->reset ();
667
668 /* Create the alias. */
669 cgraph_node::create_alias (alias_func->decl, decl);
670 alias->resolve_alias (original);
671
9d4ded75 672 /* Workaround for PR63566 that forces equal calling convention
f657d665 673 to be used. */
9d4ded75
ML
674 alias->local.local = false;
675 original->local.local = false;
676
b84d4347
ML
677 if (dump_file)
678 fprintf (dump_file, "Callgraph alias has been created.\n\n");
679 }
680 else if (create_thunk)
681 {
682 if (DECL_COMDAT_GROUP (alias->decl))
683 {
684 if (dump_file)
685 fprintf (dump_file, "Callgraph thunk cannot be created because of COMDAT\n");
686
687 return 0;
688 }
689
690 alias->icf_merged = true;
691 ipa_merge_profiles (local_original, alias);
692 alias->create_wrapper (local_original);
693
694 if (dump_file)
695 fprintf (dump_file, "Callgraph thunk has been created.\n\n");
696 }
697 else if (dump_file)
698 fprintf (dump_file, "Callgraph merge operation cannot be performed.\n\n");
699
700 return true;
701}
702
703/* Semantic item initialization function. */
704
705void
706sem_function::init (void)
707{
708 if (in_lto_p)
709 get_node ()->get_body ();
710
711 tree fndecl = node->decl;
712 function *func = DECL_STRUCT_FUNCTION (fndecl);
713
714 gcc_assert (func);
715 gcc_assert (SSANAMES (func));
716
717 ssa_names_size = SSANAMES (func)->length ();
718 node = node;
719
720 decl = fndecl;
721 region_tree = func->eh->region_tree;
722
723 /* iterating all function arguments. */
724 arg_count = count_formal_params (fndecl);
725
726 edge_count = n_edges_for_fn (func);
727 cfg_checksum = coverage_compute_cfg_checksum (func);
728
729 inchash::hash hstate;
730
731 basic_block bb;
732 FOR_EACH_BB_FN (bb, func)
733 {
734 unsigned nondbg_stmt_count = 0;
735
736 edge e;
737 for (edge_iterator ei = ei_start (bb->preds); ei_cond (ei, &e); ei_next (&ei))
738 cfg_checksum = iterative_hash_host_wide_int (e->flags,
739 cfg_checksum);
740
741 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
742 gsi_next (&gsi))
743 {
744 gimple stmt = gsi_stmt (gsi);
745
746 if (gimple_code (stmt) != GIMPLE_DEBUG)
747 {
748 hash_stmt (&hstate, stmt);
749 nondbg_stmt_count++;
750 }
751 }
752
753 gcode_hash = hstate.end ();
754 bb_sizes.safe_push (nondbg_stmt_count);
755
756 /* Inserting basic block to hash table. */
757 sem_bb *semantic_bb = new sem_bb (bb, nondbg_stmt_count,
758 EDGE_COUNT (bb->preds) + EDGE_COUNT (bb->succs));
759
760 bb_sorted.safe_push (semantic_bb);
761 }
762
763 parse_tree_args ();
764}
765
766/* Improve accumulated hash for HSTATE based on a gimple statement STMT. */
767
768void
769sem_function::hash_stmt (inchash::hash *hstate, gimple stmt)
770{
771 enum gimple_code code = gimple_code (stmt);
772
773 hstate->add_int (code);
774
775 if (code == GIMPLE_CALL)
776 {
777 /* Checking of argument. */
778 for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i)
779 {
780 tree argument = gimple_call_arg (stmt, i);
781
782 switch (TREE_CODE (argument))
783 {
784 case INTEGER_CST:
785 if (tree_fits_shwi_p (argument))
786 hstate->add_wide_int (tree_to_shwi (argument));
787 else if (tree_fits_uhwi_p (argument))
788 hstate->add_wide_int (tree_to_uhwi (argument));
789 break;
790 case REAL_CST:
791 REAL_VALUE_TYPE c;
792 HOST_WIDE_INT n;
793
794 c = TREE_REAL_CST (argument);
795 n = real_to_integer (&c);
796
797 hstate->add_wide_int (n);
798 break;
799 case ADDR_EXPR:
800 {
801 tree addr_operand = TREE_OPERAND (argument, 0);
802
803 if (TREE_CODE (addr_operand) == STRING_CST)
804 hstate->add (TREE_STRING_POINTER (addr_operand),
805 TREE_STRING_LENGTH (addr_operand));
806 break;
807 }
808 default:
809 break;
810 }
811 }
812 }
813}
814
815
816/* Return true if polymorphic comparison must be processed. */
817
818bool
819sem_function::compare_polymorphic_p (void)
820{
821 return get_node ()->callees != NULL
822 || m_compared_func->get_node ()->callees != NULL;
823}
824
825/* For a given call graph NODE, the function constructs new
826 semantic function item. */
827
828sem_function *
829sem_function::parse (cgraph_node *node, bitmap_obstack *stack)
830{
831 tree fndecl = node->decl;
832 function *func = DECL_STRUCT_FUNCTION (fndecl);
833
834 /* TODO: add support for thunks and aliases. */
835
836 if (!func || !node->has_gimple_body_p ())
837 return NULL;
838
839 if (lookup_attribute_by_prefix ("omp ", DECL_ATTRIBUTES (node->decl)) != NULL)
840 return NULL;
841
842 sem_function *f = new sem_function (node, 0, stack);
843
844 f->init ();
845
846 return f;
847}
848
849/* Parses function arguments and result type. */
850
851void
852sem_function::parse_tree_args (void)
853{
854 tree result;
855
856 if (arg_types.exists ())
857 arg_types.release ();
858
859 arg_types.create (4);
860 tree fnargs = DECL_ARGUMENTS (decl);
861
862 for (tree parm = fnargs; parm; parm = DECL_CHAIN (parm))
863 arg_types.safe_push (DECL_ARG_TYPE (parm));
864
865 /* Function result type. */
866 result = DECL_RESULT (decl);
867 result_type = result ? TREE_TYPE (result) : NULL;
868
869 /* During WPA, we can get arguments by following method. */
870 if (!fnargs)
871 {
872 tree type = TYPE_ARG_TYPES (TREE_TYPE (decl));
873 for (tree parm = type; parm; parm = TREE_CHAIN (parm))
874 arg_types.safe_push (TYPE_CANONICAL (TREE_VALUE (parm)));
875
876 result_type = TREE_TYPE (TREE_TYPE (decl));
877 }
878}
879
880/* For given basic blocks BB1 and BB2 (from functions FUNC1 and FUNC),
881 return true if phi nodes are semantically equivalent in these blocks . */
882
883bool
884sem_function::compare_phi_node (basic_block bb1, basic_block bb2)
885{
886 gimple_stmt_iterator si1, si2;
887 gimple phi1, phi2;
888 unsigned size1, size2, i;
889 tree t1, t2;
890 edge e1, e2;
891
892 gcc_assert (bb1 != NULL);
893 gcc_assert (bb2 != NULL);
894
895 si2 = gsi_start_phis (bb2);
896 for (si1 = gsi_start_phis (bb1); !gsi_end_p (si1);
897 gsi_next (&si1))
898 {
899 gsi_next_nonvirtual_phi (&si1);
900 gsi_next_nonvirtual_phi (&si2);
901
902 if (gsi_end_p (si1) && gsi_end_p (si2))
903 break;
904
905 if (gsi_end_p (si1) || gsi_end_p (si2))
906 return return_false();
907
908 phi1 = gsi_stmt (si1);
909 phi2 = gsi_stmt (si2);
910
59f084e0
ML
911 tree phi_result1 = gimple_phi_result (phi1);
912 tree phi_result2 = gimple_phi_result (phi2);
913
914 if (!m_checker->compare_operand (phi_result1, phi_result2))
915 return return_false_with_msg ("PHI results are different");
916
b84d4347
ML
917 size1 = gimple_phi_num_args (phi1);
918 size2 = gimple_phi_num_args (phi2);
919
920 if (size1 != size2)
921 return return_false ();
922
923 for (i = 0; i < size1; ++i)
924 {
925 t1 = gimple_phi_arg (phi1, i)->def;
926 t2 = gimple_phi_arg (phi2, i)->def;
927
928 if (!m_checker->compare_operand (t1, t2))
929 return return_false ();
930
931 e1 = gimple_phi_arg_edge (phi1, i);
932 e2 = gimple_phi_arg_edge (phi2, i);
933
934 if (!m_checker->compare_edge (e1, e2))
935 return return_false ();
936 }
937
938 gsi_next (&si2);
939 }
940
941 return true;
942}
943
944/* Returns true if tree T can be compared as a handled component. */
945
946bool
947sem_function::icf_handled_component_p (tree t)
948{
949 tree_code tc = TREE_CODE (t);
950
951 return ((handled_component_p (t))
952 || tc == ADDR_EXPR || tc == MEM_REF || tc == REALPART_EXPR
953 || tc == IMAGPART_EXPR || tc == OBJ_TYPE_REF);
954}
955
956/* Basic blocks dictionary BB_DICT returns true if SOURCE index BB
957 corresponds to TARGET. */
958
959bool
960sem_function::bb_dict_test (int* bb_dict, int source, int target)
961{
962 if (bb_dict[source] == -1)
963 {
964 bb_dict[source] = target;
965 return true;
966 }
967 else
968 return bb_dict[source] == target;
969}
970
971/* Iterates all tree types in T1 and T2 and returns true if all types
972 are compatible. If COMPARE_POLYMORPHIC is set to true,
973 more strict comparison is executed. */
974
975bool
976sem_function::compare_type_list (tree t1, tree t2, bool compare_polymorphic)
977{
978 tree tv1, tv2;
979 tree_code tc1, tc2;
980
981 if (!t1 && !t2)
982 return true;
983
984 while (t1 != NULL && t2 != NULL)
985 {
986 tv1 = TREE_VALUE (t1);
987 tv2 = TREE_VALUE (t2);
988
989 tc1 = TREE_CODE (tv1);
990 tc2 = TREE_CODE (tv2);
991
992 if (tc1 == NOP_EXPR && tc2 == NOP_EXPR)
993 {}
994 else if (tc1 == NOP_EXPR || tc2 == NOP_EXPR)
995 return false;
996 else if (!func_checker::compatible_types_p (tv1, tv2, compare_polymorphic))
997 return false;
998
999 t1 = TREE_CHAIN (t1);
1000 t2 = TREE_CHAIN (t2);
1001 }
1002
1003 return !(t1 || t2);
1004}
1005
1006
1007/* Semantic variable constructor that uses STACK as bitmap memory stack. */
1008
1009sem_variable::sem_variable (bitmap_obstack *stack): sem_item (VAR, stack)
1010{
1011}
1012
1013/* Constructor based on varpool node _NODE with computed hash _HASH.
1014 Bitmap STACK is used for memory allocation. */
1015
1016sem_variable::sem_variable (varpool_node *node, hashval_t _hash,
1017 bitmap_obstack *stack): sem_item(VAR,
1018 node, _hash, stack)
1019{
1020 gcc_checking_assert (node);
1021 gcc_checking_assert (get_node ());
1022}
1023
1024/* Returns true if the item equals to ITEM given as argument. */
1025
1026bool
1027sem_variable::equals (sem_item *item,
1028 hash_map <symtab_node *, sem_item *> & ARG_UNUSED (ignored_nodes))
1029{
1030 gcc_assert (item->type == VAR);
1031
1032 sem_variable *v = static_cast<sem_variable *>(item);
1033
1034 if (!ctor || !v->ctor)
1035 return return_false_with_msg ("ctor is missing for semantic variable");
1036
1037 return sem_variable::equals (ctor, v->ctor);
1038}
1039
1040/* Compares trees T1 and T2 for semantic equality. */
1041
1042bool
1043sem_variable::equals (tree t1, tree t2)
1044{
1045 tree_code tc1 = TREE_CODE (t1);
1046 tree_code tc2 = TREE_CODE (t2);
1047
1048 if (tc1 != tc2)
1049 return false;
1050
1051 switch (tc1)
1052 {
1053 case CONSTRUCTOR:
1054 {
1055 unsigned len1 = vec_safe_length (CONSTRUCTOR_ELTS (t1));
1056 unsigned len2 = vec_safe_length (CONSTRUCTOR_ELTS (t2));
1057
1058 if (len1 != len2)
1059 return false;
1060
1061 for (unsigned i = 0; i < len1; i++)
1062 if (!sem_variable::equals (CONSTRUCTOR_ELT (t1, i)->value,
1063 CONSTRUCTOR_ELT (t2, i)->value)
1064 || CONSTRUCTOR_ELT (t1, i)->index != CONSTRUCTOR_ELT (t2, i)->index)
1065 return false;
1066
1067 return true;
1068 }
1069 case MEM_REF:
1070 {
1071 tree x1 = TREE_OPERAND (t1, 0);
1072 tree x2 = TREE_OPERAND (t2, 0);
1073 tree y1 = TREE_OPERAND (t1, 1);
1074 tree y2 = TREE_OPERAND (t2, 1);
1075
1076 if (!func_checker::compatible_types_p (TREE_TYPE (x1), TREE_TYPE (x2),
1077 true))
1078 return return_false ();
1079
1080 /* Type of the offset on MEM_REF does not matter. */
1081 return sem_variable::equals (x1, x2)
1082 && wi::to_offset (y1) == wi::to_offset (y2);
1083 }
1084 case NOP_EXPR:
1085 case ADDR_EXPR:
1086 {
1087 tree op1 = TREE_OPERAND (t1, 0);
1088 tree op2 = TREE_OPERAND (t2, 0);
1089 return sem_variable::equals (op1, op2);
1090 }
1091 case FUNCTION_DECL:
1092 case VAR_DECL:
1093 case FIELD_DECL:
1094 case LABEL_DECL:
1095 return t1 == t2;
1096 case INTEGER_CST:
1097 return func_checker::compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2),
1098 true)
1099 && wi::to_offset (t1) == wi::to_offset (t2);
1100 case STRING_CST:
1101 case REAL_CST:
1102 case COMPLEX_CST:
1103 return operand_equal_p (t1, t2, OEP_ONLY_CONST);
1104 case COMPONENT_REF:
1105 case ARRAY_REF:
1106 case POINTER_PLUS_EXPR:
1107 {
1108 tree x1 = TREE_OPERAND (t1, 0);
1109 tree x2 = TREE_OPERAND (t2, 0);
1110 tree y1 = TREE_OPERAND (t1, 1);
1111 tree y2 = TREE_OPERAND (t2, 1);
1112
1113 return sem_variable::equals (x1, x2) && sem_variable::equals (y1, y2);
1114 }
1115 case ERROR_MARK:
1116 return return_false_with_msg ("ERROR_MARK");
1117 default:
1118 return return_false_with_msg ("Unknown TREE code reached");
1119 }
1120}
1121
1122/* Parser function that visits a varpool NODE. */
1123
1124sem_variable *
1125sem_variable::parse (varpool_node *node, bitmap_obstack *stack)
1126{
1127 tree decl = node->decl;
1128
1129 bool readonly = TYPE_P (decl) ? TYPE_READONLY (decl) : TREE_READONLY (decl);
1130 bool can_handle = readonly && (DECL_VIRTUAL_P (decl)
1131 || !TREE_ADDRESSABLE (decl));
1132
1133 if (!can_handle)
1134 return NULL;
1135
1136 tree ctor = ctor_for_folding (decl);
1137 if (!ctor)
1138 return NULL;
1139
1140 sem_variable *v = new sem_variable (node, 0, stack);
1141
1142 v->init ();
1143
1144 return v;
1145}
1146
1147/* References independent hash function. */
1148
1149hashval_t
1150sem_variable::get_hash (void)
1151{
1152 if (hash)
1153 return hash;
1154
1155 inchash::hash hstate;
1156
1157 hstate.add_int (456346417);
1158 hstate.add_int (TREE_CODE (ctor));
1159
1160 if (TREE_CODE (ctor) == CONSTRUCTOR)
1161 {
1162 unsigned length = vec_safe_length (CONSTRUCTOR_ELTS (ctor));
1163 hstate.add_int (length);
1164 }
1165
1166 hash = hstate.end ();
1167
1168 return hash;
1169}
1170
1171/* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can
1172 be applied. */
1173
1174bool
1175sem_variable::merge (sem_item *alias_item)
1176{
1177 gcc_assert (alias_item->type == VAR);
1178
f657d665
ML
1179 if (!sem_item::target_supports_symbol_aliases_p ())
1180 {
1181 if (dump_file)
1182 fprintf (dump_file, "Symbol aliases are not supported by target\n\n");
1183 return false;
1184 }
1185
b84d4347
ML
1186 sem_variable *alias_var = static_cast<sem_variable *> (alias_item);
1187
1188 varpool_node *original = get_node ();
1189 varpool_node *alias = alias_var->get_node ();
1190 bool original_discardable = false;
1191
1192 /* See if original is in a section that can be discarded if the main
1193 symbol is not used. */
1194 if (DECL_EXTERNAL (original->decl))
1195 original_discardable = true;
1196 if (original->resolution == LDPR_PREEMPTED_REG
1197 || original->resolution == LDPR_PREEMPTED_IR)
1198 original_discardable = true;
1199 if (original->can_be_discarded_p ())
1200 original_discardable = true;
1201
1202 gcc_assert (!TREE_ASM_WRITTEN (alias->decl));
1203
1204 if (original_discardable || DECL_EXTERNAL (alias_var->decl) ||
1205 !compare_sections (alias_var))
1206 {
1207 if (dump_file)
1208 fprintf (dump_file, "Varpool alias cannot be created\n\n");
1209
1210 return false;
1211 }
1212 else
1213 {
1214 // alias cycle creation check
1215 varpool_node *n = original;
1216
1217 while (n->alias)
1218 {
1219 n = n->get_alias_target ();
1220 if (n == alias)
1221 {
1222 if (dump_file)
1223 fprintf (dump_file, "Varpool alias cannot be created (alias cycle).\n\n");
1224
1225 return false;
1226 }
1227 }
1228
1229 alias->analyzed = false;
1230
1231 DECL_INITIAL (alias->decl) = NULL;
d5e254e1 1232 alias->need_bounds_init = false;
b84d4347
ML
1233 alias->remove_all_references ();
1234
1235 varpool_node::create_alias (alias_var->decl, decl);
1236 alias->resolve_alias (original);
1237
1238 if (dump_file)
1239 fprintf (dump_file, "Varpool alias has been created.\n\n");
1240
1241 return true;
1242 }
1243}
1244
1245bool
1246sem_variable::compare_sections (sem_variable *alias)
1247{
1248 const char *source = node->get_section ();
1249 const char *target = alias->node->get_section();
1250
1251 if (source == NULL && target == NULL)
1252 return true;
1253 else if(!source || !target)
1254 return false;
1255 else
1256 return strcmp (source, target) == 0;
1257}
1258
1259/* Dump symbol to FILE. */
1260
1261void
1262sem_variable::dump_to_file (FILE *file)
1263{
1264 gcc_assert (file);
1265
1266 print_node (file, "", decl, 0);
1267 fprintf (file, "\n\n");
1268}
1269
1270/* Iterates though a constructor and identifies tree references
1271 we are interested in semantic function equality. */
1272
1273void
1274sem_variable::parse_tree_refs (tree t)
1275{
1276 switch (TREE_CODE (t))
1277 {
1278 case CONSTRUCTOR:
1279 {
1280 unsigned length = vec_safe_length (CONSTRUCTOR_ELTS (t));
1281
1282 for (unsigned i = 0; i < length; i++)
1283 parse_tree_refs(CONSTRUCTOR_ELT (t, i)->value);
1284
1285 break;
1286 }
1287 case NOP_EXPR:
1288 case ADDR_EXPR:
1289 {
1290 tree op = TREE_OPERAND (t, 0);
1291 parse_tree_refs (op);
1292 break;
1293 }
1294 case FUNCTION_DECL:
1295 {
1296 tree_refs.safe_push (t);
1297 break;
1298 }
1299 default:
1300 break;
1301 }
1302}
1303
1304unsigned int sem_item_optimizer::class_id = 0;
1305
1306sem_item_optimizer::sem_item_optimizer (): worklist (0), m_classes (0),
1307 m_classes_count (0), m_cgraph_node_hooks (NULL), m_varpool_node_hooks (NULL)
1308{
1309 m_items.create (0);
1310 bitmap_obstack_initialize (&m_bmstack);
1311}
1312
1313sem_item_optimizer::~sem_item_optimizer ()
1314{
1315 for (unsigned int i = 0; i < m_items.length (); i++)
1316 delete m_items[i];
1317
1318 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
1319 it != m_classes.end (); ++it)
1320 {
1321 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
1322 delete (*it)->classes[i];
1323
1324 (*it)->classes.release ();
1325 }
1326
1327 m_items.release ();
1328
1329 bitmap_obstack_release (&m_bmstack);
1330}
1331
1332/* Write IPA ICF summary for symbols. */
1333
1334void
1335sem_item_optimizer::write_summary (void)
1336{
1337 unsigned int count = 0;
1338
1339 output_block *ob = create_output_block (LTO_section_ipa_icf);
1340 lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
1341 ob->symbol = NULL;
1342
1343 /* Calculate number of symbols to be serialized. */
1344 for (lto_symtab_encoder_iterator lsei = lsei_start_in_partition (encoder);
1345 !lsei_end_p (lsei);
1346 lsei_next_in_partition (&lsei))
1347 {
1348 symtab_node *node = lsei_node (lsei);
1349
1350 if (m_symtab_node_map.get (node))
1351 count++;
1352 }
1353
1354 streamer_write_uhwi (ob, count);
1355
1356 /* Process all of the symbols. */
1357 for (lto_symtab_encoder_iterator lsei = lsei_start_in_partition (encoder);
1358 !lsei_end_p (lsei);
1359 lsei_next_in_partition (&lsei))
1360 {
1361 symtab_node *node = lsei_node (lsei);
1362
1363 sem_item **item = m_symtab_node_map.get (node);
1364
1365 if (item && *item)
1366 {
1367 int node_ref = lto_symtab_encoder_encode (encoder, node);
1368 streamer_write_uhwi_stream (ob->main_stream, node_ref);
1369
1370 streamer_write_uhwi (ob, (*item)->get_hash ());
1371 }
1372 }
1373
1374 streamer_write_char_stream (ob->main_stream, 0);
1375 produce_asm (ob, NULL);
1376 destroy_output_block (ob);
1377}
1378
1379/* Reads a section from LTO stream file FILE_DATA. Input block for DATA
1380 contains LEN bytes. */
1381
1382void
1383sem_item_optimizer::read_section (lto_file_decl_data *file_data,
1384 const char *data, size_t len)
1385{
1386 const lto_function_header *header =
1387 (const lto_function_header *) data;
1388 const int cfg_offset = sizeof (lto_function_header);
1389 const int main_offset = cfg_offset + header->cfg_size;
1390 const int string_offset = main_offset + header->main_size;
1391 data_in *data_in;
1392 unsigned int i;
1393 unsigned int count;
1394
1395 lto_input_block ib_main ((const char *) data + main_offset, 0,
1396 header->main_size);
1397
1398 data_in =
1399 lto_data_in_create (file_data, (const char *) data + string_offset,
1400 header->string_size, vNULL);
1401
1402 count = streamer_read_uhwi (&ib_main);
1403
1404 for (i = 0; i < count; i++)
1405 {
1406 unsigned int index;
1407 symtab_node *node;
1408 lto_symtab_encoder_t encoder;
1409
1410 index = streamer_read_uhwi (&ib_main);
1411 encoder = file_data->symtab_node_encoder;
1412 node = lto_symtab_encoder_deref (encoder, index);
1413
1414 hashval_t hash = streamer_read_uhwi (&ib_main);
1415
1416 gcc_assert (node->definition);
1417
1418 if (dump_file)
1419 fprintf (dump_file, "Symbol added:%s (tree: %p, uid:%u)\n", node->asm_name (),
1420 (void *) node->decl, node->order);
1421
1422 if (is_a<cgraph_node *> (node))
1423 {
1424 cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
1425
1426 m_items.safe_push (new sem_function (cnode, hash, &m_bmstack));
1427 }
1428 else
1429 {
1430 varpool_node *vnode = dyn_cast <varpool_node *> (node);
1431
1432 m_items.safe_push (new sem_variable (vnode, hash, &m_bmstack));
1433 }
1434 }
1435
1436 lto_free_section_data (file_data, LTO_section_ipa_icf, NULL, data,
1437 len);
1438 lto_data_in_delete (data_in);
1439}
1440
1441/* Read IPA IPA ICF summary for symbols. */
1442
1443void
1444sem_item_optimizer::read_summary (void)
1445{
1446 lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
1447 lto_file_decl_data *file_data;
1448 unsigned int j = 0;
1449
1450 while ((file_data = file_data_vec[j++]))
1451 {
1452 size_t len;
1453 const char *data = lto_get_section_data (file_data,
1454 LTO_section_ipa_icf, NULL, &len);
1455
1456 if (data)
1457 read_section (file_data, data, len);
1458 }
1459}
1460
1461/* Register callgraph and varpool hooks. */
1462
1463void
1464sem_item_optimizer::register_hooks (void)
1465{
1466 m_cgraph_node_hooks = symtab->add_cgraph_removal_hook
1467 (&sem_item_optimizer::cgraph_removal_hook, this);
1468
1469 m_varpool_node_hooks = symtab->add_varpool_removal_hook
1470 (&sem_item_optimizer::varpool_removal_hook, this);
1471}
1472
1473/* Unregister callgraph and varpool hooks. */
1474
1475void
1476sem_item_optimizer::unregister_hooks (void)
1477{
1478 if (m_cgraph_node_hooks)
1479 symtab->remove_cgraph_removal_hook (m_cgraph_node_hooks);
1480
1481 if (m_varpool_node_hooks)
1482 symtab->remove_varpool_removal_hook (m_varpool_node_hooks);
1483}
1484
1485/* Adds a CLS to hashtable associated by hash value. */
1486
1487void
1488sem_item_optimizer::add_class (congruence_class *cls)
1489{
1490 gcc_assert (cls->members.length ());
1491
1492 congruence_class_group *group = get_group_by_hash (
1493 cls->members[0]->get_hash (),
1494 cls->members[0]->type);
1495 group->classes.safe_push (cls);
1496}
1497
1498/* Gets a congruence class group based on given HASH value and TYPE. */
1499
1500congruence_class_group *
1501sem_item_optimizer::get_group_by_hash (hashval_t hash, sem_item_type type)
1502{
1503 congruence_class_group *item = XNEW (congruence_class_group);
1504 item->hash = hash;
1505 item->type = type;
1506
1507 congruence_class_group **slot = m_classes.find_slot (item, INSERT);
1508
1509 if (*slot)
1510 free (item);
1511 else
1512 {
1513 item->classes.create (1);
1514 *slot = item;
1515 }
1516
1517 return *slot;
1518}
1519
1520/* Callgraph removal hook called for a NODE with a custom DATA. */
1521
1522void
1523sem_item_optimizer::cgraph_removal_hook (cgraph_node *node, void *data)
1524{
1525 sem_item_optimizer *optimizer = (sem_item_optimizer *) data;
1526 optimizer->remove_symtab_node (node);
1527}
1528
1529/* Varpool removal hook called for a NODE with a custom DATA. */
1530
1531void
1532sem_item_optimizer::varpool_removal_hook (varpool_node *node, void *data)
1533{
1534 sem_item_optimizer *optimizer = (sem_item_optimizer *) data;
1535 optimizer->remove_symtab_node (node);
1536}
1537
1538/* Remove symtab NODE triggered by symtab removal hooks. */
1539
1540void
1541sem_item_optimizer::remove_symtab_node (symtab_node *node)
1542{
1543 gcc_assert (!m_classes.elements());
1544
1545 m_removed_items_set.add (node);
1546}
1547
1548void
1549sem_item_optimizer::remove_item (sem_item *item)
1550{
1551 if (m_symtab_node_map.get (item->node))
1552 m_symtab_node_map.remove (item->node);
1553 delete item;
1554}
1555
1556/* Removes all callgraph and varpool nodes that are marked by symtab
1557 as deleted. */
1558
1559void
1560sem_item_optimizer::filter_removed_items (void)
1561{
1562 auto_vec <sem_item *> filtered;
1563
1564 for (unsigned int i = 0; i < m_items.length(); i++)
1565 {
1566 sem_item *item = m_items[i];
1567
1568 if (!flag_ipa_icf_functions && item->type == FUNC)
1569 {
1570 remove_item (item);
1571 continue;
1572 }
1573
1574 if (!flag_ipa_icf_variables && item->type == VAR)
1575 {
1576 remove_item (item);
1577 continue;
1578 }
1579
1580 bool no_body_function = false;
1581
1582 if (item->type == FUNC)
1583 {
1584 cgraph_node *cnode = static_cast <sem_function *>(item)->get_node ();
1585
1586 no_body_function = in_lto_p && (cnode->alias || cnode->body_removed);
1587 }
1588
1589 if(!m_removed_items_set.contains (m_items[i]->node)
1590 && !no_body_function)
1591 {
1592 if (item->type == VAR || (!DECL_CXX_CONSTRUCTOR_P (item->decl)
1593 && !DECL_CXX_DESTRUCTOR_P (item->decl)))
1594 {
1595 filtered.safe_push (m_items[i]);
1596 continue;
1597 }
1598 }
1599
1600 remove_item (item);
1601 }
1602
1603 /* Clean-up of released semantic items. */
1604
1605 m_items.release ();
1606 for (unsigned int i = 0; i < filtered.length(); i++)
1607 m_items.safe_push (filtered[i]);
1608}
1609
1610/* Optimizer entry point. */
1611
1612void
1613sem_item_optimizer::execute (void)
1614{
1615 filter_removed_items ();
1616 build_hash_based_classes ();
1617
1618 if (dump_file)
1619 fprintf (dump_file, "Dump after hash based groups\n");
1620 dump_cong_classes ();
1621
1622 for (unsigned int i = 0; i < m_items.length(); i++)
1623 m_items[i]->init_wpa ();
1624
1625 build_graph ();
1626
1627 subdivide_classes_by_equality (true);
1628
1629 if (dump_file)
1630 fprintf (dump_file, "Dump after WPA based types groups\n");
1631
1632 dump_cong_classes ();
1633
1634 process_cong_reduction ();
1635 verify_classes ();
1636
1637 if (dump_file)
1638 fprintf (dump_file, "Dump after callgraph-based congruence reduction\n");
1639
1640 dump_cong_classes ();
1641
1642 parse_nonsingleton_classes ();
1643 subdivide_classes_by_equality ();
1644
1645 if (dump_file)
1646 fprintf (dump_file, "Dump after full equality comparison of groups\n");
1647
1648 dump_cong_classes ();
1649
1650 unsigned int prev_class_count = m_classes_count;
1651
1652 process_cong_reduction ();
1653 dump_cong_classes ();
1654 verify_classes ();
1655 merge_classes (prev_class_count);
1656
1657 if (dump_file && (dump_flags & TDF_DETAILS))
1658 symtab_node::dump_table (dump_file);
1659}
1660
1661/* Function responsible for visiting all potential functions and
1662 read-only variables that can be merged. */
1663
1664void
1665sem_item_optimizer::parse_funcs_and_vars (void)
1666{
1667 cgraph_node *cnode;
1668
1669 if (flag_ipa_icf_functions)
1670 FOR_EACH_DEFINED_FUNCTION (cnode)
1671 {
1672 sem_function *f = sem_function::parse (cnode, &m_bmstack);
1673 if (f)
1674 {
1675 m_items.safe_push (f);
1676 m_symtab_node_map.put (cnode, f);
1677
1678 if (dump_file)
1679 fprintf (dump_file, "Parsed function:%s\n", f->asm_name ());
1680
1681 if (dump_file && (dump_flags & TDF_DETAILS))
1682 f->dump_to_file (dump_file);
1683 }
1684 else if (dump_file)
1685 fprintf (dump_file, "Not parsed function:%s\n", cnode->asm_name ());
1686 }
1687
1688 varpool_node *vnode;
1689
1690 if (flag_ipa_icf_variables)
1691 FOR_EACH_DEFINED_VARIABLE (vnode)
1692 {
1693 sem_variable *v = sem_variable::parse (vnode, &m_bmstack);
1694
1695 if (v)
1696 {
1697 m_items.safe_push (v);
1698 m_symtab_node_map.put (vnode, v);
1699 }
1700 }
1701}
1702
1703/* Makes pairing between a congruence class CLS and semantic ITEM. */
1704
1705void
1706sem_item_optimizer::add_item_to_class (congruence_class *cls, sem_item *item)
1707{
1708 item->index_in_class = cls->members.length ();
1709 cls->members.safe_push (item);
1710 item->cls = cls;
1711}
1712
1713/* Congruence classes are built by hash value. */
1714
1715void
1716sem_item_optimizer::build_hash_based_classes (void)
1717{
1718 for (unsigned i = 0; i < m_items.length (); i++)
1719 {
1720 sem_item *item = m_items[i];
1721
1722 congruence_class_group *group = get_group_by_hash (item->get_hash (),
1723 item->type);
1724
1725 if (!group->classes.length ())
1726 {
1727 m_classes_count++;
1728 group->classes.safe_push (new congruence_class (class_id++));
1729 }
1730
1731 add_item_to_class (group->classes[0], item);
1732 }
1733}
1734
1735/* Build references according to call graph. */
1736
1737void
1738sem_item_optimizer::build_graph (void)
1739{
1740 for (unsigned i = 0; i < m_items.length (); i++)
1741 {
1742 sem_item *item = m_items[i];
1743 m_symtab_node_map.put (item->node, item);
1744 }
1745
1746 for (unsigned i = 0; i < m_items.length (); i++)
1747 {
1748 sem_item *item = m_items[i];
1749
1750 if (item->type == FUNC)
1751 {
1752 cgraph_node *cnode = dyn_cast <cgraph_node *> (item->node);
1753
1754 cgraph_edge *e = cnode->callees;
1755 while (e)
1756 {
1757 sem_item **slot = m_symtab_node_map.get (e->callee);
1758 if (slot)
1759 item->add_reference (*slot);
1760
1761 e = e->next_callee;
1762 }
1763 }
1764
1765 ipa_ref *ref = NULL;
1766 for (unsigned i = 0; item->node->iterate_reference (i, ref); i++)
1767 {
1768 sem_item **slot = m_symtab_node_map.get (ref->referred);
1769 if (slot)
1770 item->add_reference (*slot);
1771 }
1772 }
1773}
1774
1775/* Semantic items in classes having more than one element and initialized.
1776 In case of WPA, we load function body. */
1777
1778void
1779sem_item_optimizer::parse_nonsingleton_classes (void)
1780{
1781 unsigned int init_called_count = 0;
1782
1783 for (unsigned i = 0; i < m_items.length (); i++)
1784 if (m_items[i]->cls->members.length () > 1)
1785 {
1786 m_items[i]->init ();
1787 init_called_count++;
1788 }
1789
1790 if (dump_file)
1791 fprintf (dump_file, "Init called for %u items (%.2f%%).\n", init_called_count,
f1c859ee 1792 m_items.length () ? 100.0f * init_called_count / m_items.length (): 0.0f);
b84d4347
ML
1793}
1794
1795/* Equality function for semantic items is used to subdivide existing
1796 classes. If IN_WPA, fast equality function is invoked. */
1797
1798void
1799sem_item_optimizer::subdivide_classes_by_equality (bool in_wpa)
1800{
1801 for (hash_table <congruence_class_group_hash>::iterator it = m_classes.begin ();
1802 it != m_classes.end (); ++it)
1803 {
1804 unsigned int class_count = (*it)->classes.length ();
1805
1806 for (unsigned i = 0; i < class_count; i++)
1807 {
1808 congruence_class *c = (*it)->classes [i];
1809
1810 if (c->members.length() > 1)
1811 {
1812 auto_vec <sem_item *> new_vector;
1813
1814 sem_item *first = c->members[0];
1815 new_vector.safe_push (first);
1816
1817 unsigned class_split_first = (*it)->classes.length ();
1818
1819 for (unsigned j = 1; j < c->members.length (); j++)
1820 {
1821 sem_item *item = c->members[j];
1822
1823 bool equals = in_wpa ? first->equals_wpa (item,
1824 m_symtab_node_map) : first->equals (item, m_symtab_node_map);
1825
1826 if (equals)
1827 new_vector.safe_push (item);
1828 else
1829 {
1830 bool integrated = false;
1831
1832 for (unsigned k = class_split_first; k < (*it)->classes.length (); k++)
1833 {
1834 sem_item *x = (*it)->classes[k]->members[0];
1835 bool equals = in_wpa ? x->equals_wpa (item,
1836 m_symtab_node_map) : x->equals (item, m_symtab_node_map);
1837
1838 if (equals)
1839 {
1840 integrated = true;
1841 add_item_to_class ((*it)->classes[k], item);
1842
1843 break;
1844 }
1845 }
1846
1847 if (!integrated)
1848 {
1849 congruence_class *c = new congruence_class (class_id++);
1850 m_classes_count++;
1851 add_item_to_class (c, item);
1852
1853 (*it)->classes.safe_push (c);
1854 }
1855 }
1856 }
1857
1858 // we replace newly created new_vector for the class we've just splitted
1859 c->members.release ();
1860 c->members.create (new_vector.length ());
1861
1862 for (unsigned int j = 0; j < new_vector.length (); j++)
1863 add_item_to_class (c, new_vector[j]);
1864 }
1865 }
1866 }
1867
1868 verify_classes ();
1869}
1870
1871/* Verify congruence classes if checking is enabled. */
1872
1873void
1874sem_item_optimizer::verify_classes (void)
1875{
1876#if ENABLE_CHECKING
1877 for (hash_table <congruence_class_group_hash>::iterator it = m_classes.begin ();
1878 it != m_classes.end (); ++it)
1879 {
1880 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
1881 {
1882 congruence_class *cls = (*it)->classes[i];
1883
1884 gcc_checking_assert (cls);
1885 gcc_checking_assert (cls->members.length () > 0);
1886
1887 for (unsigned int j = 0; j < cls->members.length (); j++)
1888 {
1889 sem_item *item = cls->members[j];
1890
1891 gcc_checking_assert (item);
1892 gcc_checking_assert (item->cls == cls);
1893
1894 for (unsigned k = 0; k < item->usages.length (); k++)
1895 {
1896 sem_usage_pair *usage = item->usages[k];
1897 gcc_checking_assert (usage->item->index_in_class <
1898 usage->item->cls->members.length ());
1899 }
1900 }
1901 }
1902 }
1903#endif
1904}
1905
1906/* Disposes split map traverse function. CLS_PTR is pointer to congruence
1907 class, BSLOT is bitmap slot we want to release. DATA is mandatory,
1908 but unused argument. */
1909
1910bool
1911sem_item_optimizer::release_split_map (congruence_class * const &,
1912 bitmap const &b, traverse_split_pair *)
1913{
1914 bitmap bmp = b;
1915
1916 BITMAP_FREE (bmp);
1917
1918 return true;
1919}
1920
1921/* Process split operation for a class given as pointer CLS_PTR,
1922 where bitmap B splits congruence class members. DATA is used
1923 as argument of split pair. */
1924
1925bool
1926sem_item_optimizer::traverse_congruence_split (congruence_class * const &cls,
1927 bitmap const &b, traverse_split_pair *pair)
1928{
1929 sem_item_optimizer *optimizer = pair->optimizer;
1930 const congruence_class *splitter_cls = pair->cls;
1931
1932 /* If counted bits are greater than zero and less than the number of members
1933 a group will be splitted. */
1934 unsigned popcount = bitmap_count_bits (b);
1935
1936 if (popcount > 0 && popcount < cls->members.length ())
1937 {
1938 congruence_class* newclasses[2] = { new congruence_class (class_id++), new congruence_class (class_id++) };
1939
1940 for (unsigned int i = 0; i < cls->members.length (); i++)
1941 {
1942 int target = bitmap_bit_p (b, i);
1943 congruence_class *tc = newclasses[target];
1944
1945 add_item_to_class (tc, cls->members[i]);
1946 }
1947
1948#ifdef ENABLE_CHECKING
1949 for (unsigned int i = 0; i < 2; i++)
1950 gcc_checking_assert (newclasses[i]->members.length ());
1951#endif
1952
1953 if (splitter_cls == cls)
1954 optimizer->splitter_class_removed = true;
1955
1956 /* Remove old class from worklist if presented. */
1957 bool in_worklist = cls->in_worklist;
1958
1959 if (in_worklist)
1960 cls->in_worklist = false;
1961
1962 congruence_class_group g;
1963 g.hash = cls->members[0]->get_hash ();
1964 g.type = cls->members[0]->type;
1965
1966 congruence_class_group *slot = optimizer->m_classes.find(&g);
1967
1968 for (unsigned int i = 0; i < slot->classes.length (); i++)
1969 if (slot->classes[i] == cls)
1970 {
1971 slot->classes.ordered_remove (i);
1972 break;
1973 }
1974
1975 /* New class will be inserted and integrated to work list. */
1976 for (unsigned int i = 0; i < 2; i++)
1977 optimizer->add_class (newclasses[i]);
1978
1979 /* Two classes replace one, so that increment just by one. */
1980 optimizer->m_classes_count++;
1981
1982 /* If OLD class was presented in the worklist, we remove the class
1983 and replace it will both newly created classes. */
1984 if (in_worklist)
1985 for (unsigned int i = 0; i < 2; i++)
1986 optimizer->worklist_push (newclasses[i]);
1987 else /* Just smaller class is inserted. */
1988 {
1989 unsigned int smaller_index = newclasses[0]->members.length () <
1990 newclasses[1]->members.length () ?
1991 0 : 1;
1992 optimizer->worklist_push (newclasses[smaller_index]);
1993 }
1994
1995 if (dump_file && (dump_flags & TDF_DETAILS))
1996 {
1997 fprintf (dump_file, " congruence class splitted:\n");
1998 cls->dump (dump_file, 4);
1999
2000 fprintf (dump_file, " newly created groups:\n");
2001 for (unsigned int i = 0; i < 2; i++)
2002 newclasses[i]->dump (dump_file, 4);
2003 }
2004
2005 /* Release class if not presented in work list. */
2006 if (!in_worklist)
2007 delete cls;
2008 }
2009
2010
2011 return true;
2012}
2013
2014/* Tests if a class CLS used as INDEXth splits any congruence classes.
2015 Bitmap stack BMSTACK is used for bitmap allocation. */
2016
2017void
2018sem_item_optimizer::do_congruence_step_for_index (congruence_class *cls,
2019 unsigned int index)
2020{
2021 hash_map <congruence_class *, bitmap> split_map;
2022
2023 for (unsigned int i = 0; i < cls->members.length (); i++)
2024 {
2025 sem_item *item = cls->members[i];
2026
2027 /* Iterate all usages that have INDEX as usage of the item. */
2028 for (unsigned int j = 0; j < item->usages.length (); j++)
2029 {
2030 sem_usage_pair *usage = item->usages[j];
2031
2032 if (usage->index != index)
2033 continue;
2034
2035 bitmap *slot = split_map.get (usage->item->cls);
2036 bitmap b;
2037
2038 if(!slot)
2039 {
2040 b = BITMAP_ALLOC (&m_bmstack);
2041 split_map.put (usage->item->cls, b);
2042 }
2043 else
2044 b = *slot;
2045
2046#if ENABLE_CHECKING
2047 gcc_checking_assert (usage->item->cls);
2048 gcc_checking_assert (usage->item->index_in_class <
2049 usage->item->cls->members.length ());
2050#endif
2051
2052 bitmap_set_bit (b, usage->item->index_in_class);
2053 }
2054 }
2055
2056 traverse_split_pair pair;
2057 pair.optimizer = this;
2058 pair.cls = cls;
2059
2060 splitter_class_removed = false;
2061 split_map.traverse
2062 <traverse_split_pair *, sem_item_optimizer::traverse_congruence_split> (&pair);
2063
2064 /* Bitmap clean-up. */
2065 split_map.traverse
2066 <traverse_split_pair *, sem_item_optimizer::release_split_map> (NULL);
2067}
2068
2069/* Every usage of a congruence class CLS is a candidate that can split the
2070 collection of classes. Bitmap stack BMSTACK is used for bitmap
2071 allocation. */
2072
2073void
2074sem_item_optimizer::do_congruence_step (congruence_class *cls)
2075{
2076 bitmap_iterator bi;
2077 unsigned int i;
2078
2079 bitmap usage = BITMAP_ALLOC (&m_bmstack);
2080
2081 for (unsigned int i = 0; i < cls->members.length (); i++)
2082 bitmap_ior_into (usage, cls->members[i]->usage_index_bitmap);
2083
2084 EXECUTE_IF_SET_IN_BITMAP (usage, 0, i, bi)
2085 {
2086 if (dump_file && (dump_flags & TDF_DETAILS))
2087 fprintf (dump_file, " processing congruece step for class: %u, index: %u\n",
2088 cls->id, i);
2089
2090 do_congruence_step_for_index (cls, i);
2091
2092 if (splitter_class_removed)
2093 break;
2094 }
2095
2096 BITMAP_FREE (usage);
2097}
2098
2099/* Adds a newly created congruence class CLS to worklist. */
2100
2101void
2102sem_item_optimizer::worklist_push (congruence_class *cls)
2103{
2104 /* Return if the class CLS is already presented in work list. */
2105 if (cls->in_worklist)
2106 return;
2107
2108 cls->in_worklist = true;
2109 worklist.push_back (cls);
2110}
2111
2112/* Pops a class from worklist. */
2113
2114congruence_class *
2115sem_item_optimizer::worklist_pop (void)
2116{
2117 congruence_class *cls;
2118
2119 while (!worklist.empty ())
2120 {
2121 cls = worklist.front ();
2122 worklist.pop_front ();
2123 if (cls->in_worklist)
2124 {
2125 cls->in_worklist = false;
2126
2127 return cls;
2128 }
2129 else
2130 {
2131 /* Work list item was already intended to be removed.
2132 The only reason for doing it is to split a class.
2133 Thus, the class CLS is deleted. */
2134 delete cls;
2135 }
2136 }
2137
2138 return NULL;
2139}
2140
2141/* Iterative congruence reduction function. */
2142
2143void
2144sem_item_optimizer::process_cong_reduction (void)
2145{
2146 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2147 it != m_classes.end (); ++it)
2148 for (unsigned i = 0; i < (*it)->classes.length (); i++)
2149 if ((*it)->classes[i]->is_class_used ())
2150 worklist_push ((*it)->classes[i]);
2151
2152 if (dump_file)
2153 fprintf (dump_file, "Worklist has been filled with: %lu\n",
10568163 2154 (unsigned long) worklist.size ());
b84d4347
ML
2155
2156 if (dump_file && (dump_flags & TDF_DETAILS))
2157 fprintf (dump_file, "Congruence class reduction\n");
2158
2159 congruence_class *cls;
2160 while ((cls = worklist_pop ()) != NULL)
2161 do_congruence_step (cls);
2162}
2163
2164/* Debug function prints all informations about congruence classes. */
2165
2166void
2167sem_item_optimizer::dump_cong_classes (void)
2168{
2169 if (!dump_file)
2170 return;
2171
2172 fprintf (dump_file,
2173 "Congruence classes: %u (unique hash values: %lu), with total: %u items\n",
10568163 2174 m_classes_count, (unsigned long) m_classes.elements(), m_items.length ());
b84d4347
ML
2175
2176 /* Histogram calculation. */
2177 unsigned int max_index = 0;
2178 unsigned int* histogram = XCNEWVEC (unsigned int, m_items.length () + 1);
2179
2180 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2181 it != m_classes.end (); ++it)
2182
2183 for (unsigned i = 0; i < (*it)->classes.length (); i++)
2184 {
2185 unsigned int c = (*it)->classes[i]->members.length ();
2186 histogram[c]++;
2187
2188 if (c > max_index)
2189 max_index = c;
2190 }
2191
2192 fprintf (dump_file,
2193 "Class size histogram [num of members]: number of classe number of classess\n");
2194
2195 for (unsigned int i = 0; i <= max_index; i++)
2196 if (histogram[i])
2197 fprintf (dump_file, "[%u]: %u classes\n", i, histogram[i]);
2198
2199 fprintf (dump_file, "\n\n");
2200
2201
2202 if (dump_flags & TDF_DETAILS)
2203 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2204 it != m_classes.end (); ++it)
2205 {
2206 fprintf (dump_file, " group: with %u classes:\n", (*it)->classes.length ());
2207
2208 for (unsigned i = 0; i < (*it)->classes.length (); i++)
2209 {
2210 (*it)->classes[i]->dump (dump_file, 4);
2211
2212 if(i < (*it)->classes.length () - 1)
2213 fprintf (dump_file, " ");
2214 }
2215 }
2216
2217 free (histogram);
2218}
2219
2220/* After reduction is done, we can declare all items in a group
2221 to be equal. PREV_CLASS_COUNT is start number of classes
2222 before reduction. */
2223
2224void
2225sem_item_optimizer::merge_classes (unsigned int prev_class_count)
2226{
2227 unsigned int item_count = m_items.length ();
2228 unsigned int class_count = m_classes_count;
2229 unsigned int equal_items = item_count - class_count;
2230
2231 unsigned int non_singular_classes_count = 0;
2232 unsigned int non_singular_classes_sum = 0;
2233
2234 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2235 it != m_classes.end (); ++it)
2236 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
2237 {
2238 congruence_class *c = (*it)->classes[i];
2239 if (c->members.length () > 1)
2240 {
2241 non_singular_classes_count++;
2242 non_singular_classes_sum += c->members.length ();
2243 }
2244 }
2245
2246 if (dump_file)
2247 {
2248 fprintf (dump_file, "\nItem count: %u\n", item_count);
2249 fprintf (dump_file, "Congruent classes before: %u, after: %u\n",
2250 prev_class_count, class_count);
2251 fprintf (dump_file, "Average class size before: %.2f, after: %.2f\n",
f1c859ee
ML
2252 prev_class_count ? 1.0f * item_count / prev_class_count : 0.0f,
2253 class_count ? 1.0f * item_count / class_count : 0.0f);
b84d4347 2254 fprintf (dump_file, "Average non-singular class size: %.2f, count: %u\n",
f1c859ee
ML
2255 non_singular_classes_count ? 1.0f * non_singular_classes_sum /
2256 non_singular_classes_count : 0.0f,
b84d4347
ML
2257 non_singular_classes_count);
2258 fprintf (dump_file, "Equal symbols: %u\n", equal_items);
2259 fprintf (dump_file, "Fraction of visited symbols: %.2f%%\n\n",
f1c859ee 2260 item_count ? 100.0f * equal_items / item_count : 0.0f);
b84d4347
ML
2261 }
2262
2263 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2264 it != m_classes.end (); ++it)
2265 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
2266 {
2267 congruence_class *c = (*it)->classes[i];
2268
2269 if (c->members.length () == 1)
2270 continue;
2271
2272 gcc_assert (c->members.length ());
2273
2274 sem_item *source = c->members[0];
2275
2276 for (unsigned int j = 1; j < c->members.length (); j++)
2277 {
2278 sem_item *alias = c->members[j];
2279 source->equals (alias, m_symtab_node_map);
2280
2281 if (dump_file)
2282 {
2283 fprintf (dump_file, "Semantic equality hit:%s->%s\n",
2284 source->name (), alias->name ());
2285 fprintf (dump_file, "Assembler symbol names:%s->%s\n",
2286 source->asm_name (), alias->asm_name ());
2287 }
2288
2289 if (dump_file && (dump_flags & TDF_DETAILS))
2290 {
2291 source->dump_to_file (dump_file);
2292 alias->dump_to_file (dump_file);
2293 }
2294
2295 source->merge (alias);
2296 }
2297 }
2298}
2299
2300/* Dump function prints all class members to a FILE with an INDENT. */
2301
2302void
2303congruence_class::dump (FILE *file, unsigned int indent) const
2304{
2305 FPRINTF_SPACES (file, indent, "class with id: %u, hash: %u, items: %u\n",
2306 id, members[0]->get_hash (), members.length ());
2307
2308 FPUTS_SPACES (file, indent + 2, "");
2309 for (unsigned i = 0; i < members.length (); i++)
2310 fprintf (file, "%s(%p/%u) ", members[i]->asm_name (), (void *) members[i]->decl,
2311 members[i]->node->order);
2312
2313 fprintf (file, "\n");
2314}
2315
2316/* Returns true if there's a member that is used from another group. */
2317
2318bool
2319congruence_class::is_class_used (void)
2320{
2321 for (unsigned int i = 0; i < members.length (); i++)
2322 if (members[i]->usages.length ())
2323 return true;
2324
2325 return false;
2326}
2327
2328/* Initialization and computation of symtab node hash, there data
2329 are propagated later on. */
2330
2331static sem_item_optimizer *optimizer = NULL;
2332
2333/* Generate pass summary for IPA ICF pass. */
2334
2335static void
2336ipa_icf_generate_summary (void)
2337{
2338 if (!optimizer)
2339 optimizer = new sem_item_optimizer ();
2340
2341 optimizer->parse_funcs_and_vars ();
2342}
2343
2344/* Write pass summary for IPA ICF pass. */
2345
2346static void
2347ipa_icf_write_summary (void)
2348{
2349 gcc_assert (optimizer);
2350
2351 optimizer->write_summary ();
2352}
2353
2354/* Read pass summary for IPA ICF pass. */
2355
2356static void
2357ipa_icf_read_summary (void)
2358{
2359 if (!optimizer)
2360 optimizer = new sem_item_optimizer ();
2361
2362 optimizer->read_summary ();
2363 optimizer->register_hooks ();
2364}
2365
2366/* Semantic equality exection function. */
2367
2368static unsigned int
2369ipa_icf_driver (void)
2370{
2371 gcc_assert (optimizer);
2372
2373 optimizer->execute ();
2374 optimizer->unregister_hooks ();
2375
2376 delete optimizer;
9612a39a 2377 optimizer = NULL;
b84d4347
ML
2378
2379 return 0;
2380}
2381
2382const pass_data pass_data_ipa_icf =
2383{
2384 IPA_PASS, /* type */
2385 "icf", /* name */
2386 OPTGROUP_IPA, /* optinfo_flags */
2387 TV_IPA_ICF, /* tv_id */
2388 0, /* properties_required */
2389 0, /* properties_provided */
2390 0, /* properties_destroyed */
2391 0, /* todo_flags_start */
2392 0, /* todo_flags_finish */
2393};
2394
2395class pass_ipa_icf : public ipa_opt_pass_d
2396{
2397public:
2398 pass_ipa_icf (gcc::context *ctxt)
2399 : ipa_opt_pass_d (pass_data_ipa_icf, ctxt,
2400 ipa_icf_generate_summary, /* generate_summary */
2401 ipa_icf_write_summary, /* write_summary */
2402 ipa_icf_read_summary, /* read_summary */
2403 NULL, /*
2404 write_optimization_summary */
2405 NULL, /*
2406 read_optimization_summary */
2407 NULL, /* stmt_fixup */
2408 0, /* function_transform_todo_flags_start */
2409 NULL, /* function_transform */
2410 NULL) /* variable_transform */
2411 {}
2412
2413 /* opt_pass methods: */
2414 virtual bool gate (function *)
2415 {
2416 return flag_ipa_icf_variables || flag_ipa_icf_functions;
2417 }
2418
2419 virtual unsigned int execute (function *)
2420 {
2421 return ipa_icf_driver();
2422 }
2423}; // class pass_ipa_icf
2424
2425} // ipa_icf namespace
2426
2427ipa_opt_pass_d *
2428make_pass_ipa_icf (gcc::context *ctxt)
2429{
2430 return new ipa_icf::pass_ipa_icf (ctxt);
2431}