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