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