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