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