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