1 /* Interprocedural Identical Code Folding pass
2 Copyright (C) 2014-2015 Free Software Foundation, Inc.
4 Contributed by Jan Hubicka <hubicka@ucw.cz> and Martin Liska <mliska@suse.cz>
6 This file is part of GCC.
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
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
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/>. */
22 /* Interprocedural Identical Code Folding for functions and
25 The goal of this transformation is to discover functions and read-only
26 variables which do have exactly the same semantics.
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
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
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.
56 #include "coretypes.h"
60 #include "double-int.h"
68 #include "fold-const.h"
71 #include "hard-reg-set.h"
73 #include "dominance.h"
75 #include "basic-block.h"
76 #include "tree-ssa-alias.h"
77 #include "internal-fn.h"
78 #include "gimple-expr.h"
84 #include "statistics.h"
86 #include "fixed-value.h"
87 #include "insn-config.h"
96 #include "gimple-iterator.h"
97 #include "gimple-ssa.h"
99 #include "tree-phinodes.h"
100 #include "stringpool.h"
101 #include "tree-ssanames.h"
102 #include "tree-dfa.h"
103 #include "tree-pass.h"
104 #include "gimple-pretty-print.h"
105 #include "hash-map.h"
106 #include "plugin-api.h"
109 #include "alloc-pool.h"
110 #include "symbol-summary.h"
111 #include "ipa-prop.h"
112 #include "ipa-inline.h"
115 #include "hash-table.h"
116 #include "coverage.h"
118 #include "print-tree.h"
119 #include "lto-streamer.h"
120 #include "data-streamer.h"
121 #include "ipa-utils.h"
123 #include "ipa-icf-gimple.h"
126 using namespace ipa_icf_gimple;
132 symbol_compare_collection::symbol_compare_collection (symtab_node *node)
134 m_references.create (0);
135 m_interposables.create (0);
139 if (is_a <varpool_node *> (node) && DECL_VIRTUAL_P (node->decl))
142 for (unsigned i = 0; i < node->num_references (); i++)
144 ref = node->iterate_reference (i, ref);
145 if (ref->address_matters_p ())
146 m_references.safe_push (ref->referred);
148 if (ref->referred->get_availability () <= AVAIL_INTERPOSABLE)
150 if (ref->address_matters_p ())
151 m_references.safe_push (ref->referred);
153 m_interposables.safe_push (ref->referred);
157 if (is_a <cgraph_node *> (node))
159 cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
161 for (cgraph_edge *e = cnode->callees; e; e = e->next_callee)
162 if (e->callee->get_availability () <= AVAIL_INTERPOSABLE)
163 m_interposables.safe_push (e->callee);
167 /* Constructor for key value pair, where _ITEM is key and _INDEX is a target. */
169 sem_usage_pair::sem_usage_pair (sem_item *_item, unsigned int _index):
170 item (_item), index (_index)
174 /* Semantic item constructor for a node of _TYPE, where STACK is used
175 for bitmap memory allocation. */
177 sem_item::sem_item (sem_item_type _type,
178 bitmap_obstack *stack): type(_type), hash(0)
183 /* Semantic item constructor for a node of _TYPE, where STACK is used
184 for bitmap memory allocation. The item is based on symtab node _NODE
185 with computed _HASH. */
187 sem_item::sem_item (sem_item_type _type, symtab_node *_node,
188 hashval_t _hash, bitmap_obstack *stack): type(_type),
189 node (_node), hash (_hash)
195 /* Add reference to a semantic TARGET. */
198 sem_item::add_reference (sem_item *target)
200 refs.safe_push (target);
201 unsigned index = refs.length ();
202 target->usages.safe_push (new sem_usage_pair(this, index));
203 bitmap_set_bit (target->usage_index_bitmap, index);
204 refs_set.add (target->node);
207 /* Initialize internal data structures. Bitmap STACK is used for
208 bitmap memory allocation process. */
211 sem_item::setup (bitmap_obstack *stack)
213 gcc_checking_assert (node);
216 tree_refs.create (0);
218 usage_index_bitmap = BITMAP_ALLOC (stack);
221 sem_item::~sem_item ()
223 for (unsigned i = 0; i < usages.length (); i++)
227 tree_refs.release ();
230 BITMAP_FREE (usage_index_bitmap);
233 /* Dump function for debugging purpose. */
236 sem_item::dump (void)
240 fprintf (dump_file, "[%s] %s (%u) (tree:%p)\n", type == FUNC ? "func" : "var",
241 name(), node->order, (void *) node->decl);
242 fprintf (dump_file, " hash: %u\n", get_hash ());
243 fprintf (dump_file, " references: ");
245 for (unsigned i = 0; i < refs.length (); i++)
246 fprintf (dump_file, "%s%s ", refs[i]->name (),
247 i < refs.length() - 1 ? "," : "");
249 fprintf (dump_file, "\n");
253 /* Return true if target supports alias symbols. */
256 sem_item::target_supports_symbol_aliases_p (void)
258 #if !defined (ASM_OUTPUT_DEF) || (!defined(ASM_OUTPUT_WEAK_ALIAS) && !defined (ASM_WEAKEN_DECL))
265 /* Semantic function constructor that uses STACK as bitmap memory stack. */
267 sem_function::sem_function (bitmap_obstack *stack): sem_item (FUNC, stack),
268 m_checker (NULL), m_compared_func (NULL)
270 arg_types.create (0);
272 bb_sorted.create (0);
275 /* Constructor based on callgraph node _NODE with computed hash _HASH.
276 Bitmap STACK is used for memory allocation. */
277 sem_function::sem_function (cgraph_node *node, hashval_t hash,
278 bitmap_obstack *stack):
279 sem_item (FUNC, node, hash, stack),
280 m_checker (NULL), m_compared_func (NULL)
282 arg_types.create (0);
284 bb_sorted.create (0);
287 sem_function::~sem_function ()
289 for (unsigned i = 0; i < bb_sorted.length (); i++)
290 delete (bb_sorted[i]);
292 arg_types.release ();
294 bb_sorted.release ();
297 /* Calculates hash value based on a BASIC_BLOCK. */
300 sem_function::get_bb_hash (const sem_bb *basic_block)
302 inchash::hash hstate;
304 hstate.add_int (basic_block->nondbg_stmt_count);
305 hstate.add_int (basic_block->edge_count);
307 return hstate.end ();
310 /* References independent hash function. */
313 sem_function::get_hash (void)
317 inchash::hash hstate;
318 hstate.add_int (177454); /* Random number for function type. */
320 hstate.add_int (arg_count);
321 hstate.add_int (cfg_checksum);
322 hstate.add_int (gcode_hash);
324 for (unsigned i = 0; i < bb_sorted.length (); i++)
325 hstate.merge_hash (get_bb_hash (bb_sorted[i]));
327 for (unsigned i = 0; i < bb_sizes.length (); i++)
328 hstate.add_int (bb_sizes[i]);
330 hash = hstate.end ();
336 /* For a given symbol table nodes N1 and N2, we check that FUNCTION_DECLs
337 point to a same function. Comparison can be skipped if IGNORED_NODES
338 contains these nodes. */
341 sem_function::compare_cgraph_references (hash_map <symtab_node *, sem_item *>
343 symtab_node *n1, symtab_node *n2)
345 if (n1 == n2 || (ignored_nodes.get (n1) && ignored_nodes.get (n2)))
348 /* TODO: add more precise comparison for weakrefs, etc. */
350 return return_false_with_msg ("different references");
353 /* If cgraph edges E1 and E2 are indirect calls, verify that
354 ECF flags are the same. */
356 bool sem_function::compare_edge_flags (cgraph_edge *e1, cgraph_edge *e2)
358 if (e1->indirect_info && e2->indirect_info)
360 int e1_flags = e1->indirect_info->ecf_flags;
361 int e2_flags = e2->indirect_info->ecf_flags;
363 if (e1_flags != e2_flags)
364 return return_false_with_msg ("ICF flags are different");
366 else if (e1->indirect_info || e2->indirect_info)
372 /* Fast equality function based on knowledge known in WPA. */
375 sem_function::equals_wpa (sem_item *item,
376 hash_map <symtab_node *, sem_item *> &ignored_nodes)
378 gcc_assert (item->type == FUNC);
380 m_compared_func = static_cast<sem_function *> (item);
382 if (arg_types.length () != m_compared_func->arg_types.length ())
383 return return_false_with_msg ("different number of arguments");
385 /* Checking types of arguments. */
386 for (unsigned i = 0; i < arg_types.length (); i++)
388 /* This guard is here for function pointer with attributes (pr59927.c). */
389 if (!arg_types[i] || !m_compared_func->arg_types[i])
390 return return_false_with_msg ("NULL argument type");
392 /* Polymorphic comparison is executed just for non-leaf functions. */
393 bool is_not_leaf = get_node ()->callees != NULL
394 || get_node ()->indirect_calls != NULL;
396 if (!func_checker::compatible_types_p (arg_types[i],
397 m_compared_func->arg_types[i],
398 is_not_leaf, i == 0))
399 return return_false_with_msg ("argument type is different");
402 /* Result type checking. */
403 if (!func_checker::compatible_types_p (result_type,
404 m_compared_func->result_type))
405 return return_false_with_msg ("result types are different");
407 if (node->num_references () != item->node->num_references ())
408 return return_false_with_msg ("different number of references");
410 ipa_ref *ref = NULL, *ref2 = NULL;
411 for (unsigned i = 0; node->iterate_reference (i, ref); i++)
413 item->node->iterate_reference (i, ref2);
415 if (!compare_cgraph_references (ignored_nodes, ref->referred, ref2->referred))
419 cgraph_edge *e1 = dyn_cast <cgraph_node *> (node)->callees;
420 cgraph_edge *e2 = dyn_cast <cgraph_node *> (item->node)->callees;
424 if (!compare_cgraph_references (ignored_nodes, e1->callee, e2->callee))
427 e1 = e1->next_callee;
428 e2 = e2->next_callee;
432 return return_false_with_msg ("different number of edges");
437 /* Returns true if the item equals to ITEM given as argument. */
440 sem_function::equals (sem_item *item,
441 hash_map <symtab_node *, sem_item *> &ignored_nodes)
443 gcc_assert (item->type == FUNC);
444 bool eq = equals_private (item, ignored_nodes);
446 if (m_checker != NULL)
452 if (dump_file && (dump_flags & TDF_DETAILS))
454 "Equals called for:%s:%s (%u:%u) (%s:%s) with result: %s\n\n",
455 name(), item->name (), node->order, item->node->order, asm_name (),
456 item->asm_name (), eq ? "true" : "false");
461 /* Processes function equality comparison. */
464 sem_function::equals_private (sem_item *item,
465 hash_map <symtab_node *, sem_item *> &ignored_nodes)
467 if (item->type != FUNC)
470 basic_block bb1, bb2;
472 edge_iterator ei1, ei2;
476 m_compared_func = static_cast<sem_function *> (item);
478 gcc_assert (decl != item->decl);
480 if (bb_sorted.length () != m_compared_func->bb_sorted.length ()
481 || edge_count != m_compared_func->edge_count
482 || cfg_checksum != m_compared_func->cfg_checksum)
483 return return_false ();
485 if (!equals_wpa (item, ignored_nodes))
488 /* Checking function TARGET and OPTIMIZATION flags. */
489 cl_target_option *tar1 = target_opts_for_fn (decl);
490 cl_target_option *tar2 = target_opts_for_fn (m_compared_func->decl);
492 if (tar1 != NULL && tar2 != NULL)
494 if (!cl_target_option_eq (tar1, tar2))
496 if (dump_file && (dump_flags & TDF_DETAILS))
498 fprintf (dump_file, "target flags difference");
499 cl_target_option_print_diff (dump_file, 2, tar1, tar2);
502 return return_false_with_msg ("Target flags are different");
505 else if (tar1 != NULL || tar2 != NULL)
506 return return_false_with_msg ("Target flags are different");
508 cl_optimization *opt1 = opts_for_fn (decl);
509 cl_optimization *opt2 = opts_for_fn (m_compared_func->decl);
511 if (opt1 != NULL && opt2 != NULL)
513 if (memcmp (opt1, opt2, sizeof(cl_optimization)))
515 if (dump_file && (dump_flags & TDF_DETAILS))
517 fprintf (dump_file, "optimization flags difference");
518 cl_optimization_print_diff (dump_file, 2, opt1, opt2);
521 return return_false_with_msg ("optimization flags are different");
524 else if (opt1 != NULL || opt2 != NULL)
525 return return_false_with_msg ("optimization flags are different");
527 /* Checking function arguments. */
528 tree decl1 = DECL_ATTRIBUTES (decl);
529 tree decl2 = DECL_ATTRIBUTES (m_compared_func->decl);
531 m_checker = new func_checker (decl, m_compared_func->decl,
532 compare_polymorphic_p (),
535 &m_compared_func->refs_set);
539 return return_false ();
541 if (get_attribute_name (decl1) != get_attribute_name (decl2))
542 return return_false ();
544 tree attr_value1 = TREE_VALUE (decl1);
545 tree attr_value2 = TREE_VALUE (decl2);
547 if (attr_value1 && attr_value2)
549 bool ret = m_checker->compare_operand (TREE_VALUE (attr_value1),
550 TREE_VALUE (attr_value2));
552 return return_false_with_msg ("attribute values are different");
554 else if (!attr_value1 && !attr_value2)
557 return return_false ();
559 decl1 = TREE_CHAIN (decl1);
560 decl2 = TREE_CHAIN (decl2);
564 return return_false();
567 for (arg1 = DECL_ARGUMENTS (decl),
568 arg2 = DECL_ARGUMENTS (m_compared_func->decl);
569 arg1; arg1 = DECL_CHAIN (arg1), arg2 = DECL_CHAIN (arg2))
570 if (!m_checker->compare_decl (arg1, arg2))
571 return return_false ();
573 /* Fill-up label dictionary. */
574 for (unsigned i = 0; i < bb_sorted.length (); ++i)
576 m_checker->parse_labels (bb_sorted[i]);
577 m_checker->parse_labels (m_compared_func->bb_sorted[i]);
580 /* Checking all basic blocks. */
581 for (unsigned i = 0; i < bb_sorted.length (); ++i)
582 if(!m_checker->compare_bb (bb_sorted[i], m_compared_func->bb_sorted[i]))
583 return return_false();
585 dump_message ("All BBs are equal\n");
587 auto_vec <int> bb_dict;
589 /* Basic block edges check. */
590 for (unsigned i = 0; i < bb_sorted.length (); ++i)
592 bb1 = bb_sorted[i]->bb;
593 bb2 = m_compared_func->bb_sorted[i]->bb;
595 ei2 = ei_start (bb2->preds);
597 for (ei1 = ei_start (bb1->preds); ei_cond (ei1, &e1); ei_next (&ei1))
601 if (e1->flags != e2->flags)
602 return return_false_with_msg ("flags comparison returns false");
604 if (!bb_dict_test (&bb_dict, e1->src->index, e2->src->index))
605 return return_false_with_msg ("edge comparison returns false");
607 if (!bb_dict_test (&bb_dict, e1->dest->index, e2->dest->index))
608 return return_false_with_msg ("BB comparison returns false");
610 if (!m_checker->compare_edge (e1, e2))
611 return return_false_with_msg ("edge comparison returns false");
617 /* Basic block PHI nodes comparison. */
618 for (unsigned i = 0; i < bb_sorted.length (); i++)
619 if (!compare_phi_node (bb_sorted[i]->bb, m_compared_func->bb_sorted[i]->bb))
620 return return_false_with_msg ("PHI node comparison returns false");
622 /* Compare special function DECL attributes. */
623 if (DECL_FUNCTION_PERSONALITY (decl) != DECL_FUNCTION_PERSONALITY (item->decl))
624 return return_false_with_msg ("function personalities are different");
626 if (DECL_DISREGARD_INLINE_LIMITS (decl) != DECL_DISREGARD_INLINE_LIMITS (item->decl))
627 return return_false_with_msg ("DECL_DISREGARD_INLINE_LIMITS are different");
629 if (DECL_DECLARED_INLINE_P (decl) != DECL_DECLARED_INLINE_P (item->decl))
630 return return_false_with_msg ("inline attributes are different");
632 if (DECL_IS_OPERATOR_NEW (decl) != DECL_IS_OPERATOR_NEW (item->decl))
633 return return_false_with_msg ("operator new flags are different");
635 if (DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl)
636 != DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (item->decl))
637 return return_false_with_msg ("intrument function entry exit "
638 "attributes are different");
640 if (DECL_NO_LIMIT_STACK (decl) != DECL_NO_LIMIT_STACK (item->decl))
641 return return_false_with_msg ("no stack limit attributes are different");
643 if (flags_from_decl_or_type (decl) != flags_from_decl_or_type (item->decl))
644 return return_false_with_msg ("decl_or_type flags are different");
649 /* Set LOCAL_P of NODE to true if DATA is non-NULL.
650 Helper for call_for_symbol_thunks_and_aliases. */
653 set_local (cgraph_node *node, void *data)
655 node->local.local = data != NULL;
659 /* TREE_ADDRESSABLE of NODE to true.
660 Helper for call_for_symbol_thunks_and_aliases. */
663 set_addressable (varpool_node *node, void *)
665 TREE_ADDRESSABLE (node->decl) = 1;
669 /* Clear DECL_RTL of NODE.
670 Helper for call_for_symbol_thunks_and_aliases. */
673 clear_decl_rtl (symtab_node *node, void *)
675 SET_DECL_RTL (node->decl, NULL);
679 /* Redirect all callers of N and its aliases to TO. Remove aliases if
680 possible. Return number of redirections made. */
683 redirect_all_callers (cgraph_node *n, cgraph_node *to)
690 cgraph_edge *e = n->callers;
691 e->redirect_callee (to);
694 for (unsigned i = 0; n->iterate_direct_aliases (i, ref);)
696 bool removed = false;
697 cgraph_node *n_alias = dyn_cast <cgraph_node *> (ref->referring);
699 if ((DECL_COMDAT_GROUP (n->decl)
700 && (DECL_COMDAT_GROUP (n->decl)
701 == DECL_COMDAT_GROUP (n_alias->decl)))
702 || (n_alias->get_availability () > AVAIL_INTERPOSABLE
703 && n->get_availability () > AVAIL_INTERPOSABLE))
705 nredirected += redirect_all_callers (n_alias, to);
706 if (n_alias->can_remove_if_no_direct_calls_p ()
707 && !n_alias->has_aliases_p ())
716 /* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can
720 sem_function::merge (sem_item *alias_item)
722 gcc_assert (alias_item->type == FUNC);
724 sem_function *alias_func = static_cast<sem_function *> (alias_item);
726 cgraph_node *original = get_node ();
727 cgraph_node *local_original = NULL;
728 cgraph_node *alias = alias_func->get_node ();
730 bool create_wrapper = false;
731 bool create_alias = false;
732 bool redirect_callers = false;
735 bool original_discardable = false;
736 bool original_discarded = false;
738 bool original_address_matters = original->address_matters_p ();
739 bool alias_address_matters = alias->address_matters_p ();
741 if (DECL_NO_INLINE_WARNING_P (original->decl)
742 != DECL_NO_INLINE_WARNING_P (alias->decl))
747 "DECL_NO_INLINE_WARNING mismatch.\n\n");
751 /* Do not attempt to mix functions from different user sections;
752 we do not know what user intends with those. */
753 if (((DECL_SECTION_NAME (original->decl) && !original->implicit_section)
754 || (DECL_SECTION_NAME (alias->decl) && !alias->implicit_section))
755 && DECL_SECTION_NAME (original->decl) != DECL_SECTION_NAME (alias->decl))
760 "original and alias are in different sections.\n\n");
764 /* See if original is in a section that can be discarded if the main
765 symbol is not used. */
767 if (original->can_be_discarded_p ())
768 original_discardable = true;
769 /* Also consider case where we have resolution info and we know that
770 original's definition is not going to be used. In this case we can not
771 create alias to original. */
772 if (node->resolution != LDPR_UNKNOWN
773 && !decl_binds_to_current_def_p (node->decl))
774 original_discardable = original_discarded = true;
776 /* Creating a symtab alias is the optimal way to merge.
777 It however can not be used in the following cases:
779 1) if ORIGINAL and ALIAS may be possibly compared for address equality.
780 2) if ORIGINAL is in a section that may be discarded by linker or if
781 it is an external functions where we can not create an alias
782 (ORIGINAL_DISCARDABLE)
783 3) if target do not support symbol aliases.
784 4) original and alias lie in different comdat groups.
786 If we can not produce alias, we will turn ALIAS into WRAPPER of ORIGINAL
787 and/or redirect all callers from ALIAS to ORIGINAL. */
788 if ((original_address_matters && alias_address_matters)
789 || (original_discardable
790 && (!DECL_COMDAT_GROUP (alias->decl)
791 || (DECL_COMDAT_GROUP (alias->decl)
792 != DECL_COMDAT_GROUP (original->decl))))
793 || original_discarded
794 || !sem_item::target_supports_symbol_aliases_p ()
795 || DECL_COMDAT_GROUP (alias->decl) != DECL_COMDAT_GROUP (original->decl))
797 /* First see if we can produce wrapper. */
799 /* Do not turn function in one comdat group into wrapper to another
800 comdat group. Other compiler producing the body of the
801 another comdat group may make opossite decision and with unfortunate
802 linker choices this may close a loop. */
803 if (DECL_COMDAT_GROUP (original->decl) && DECL_COMDAT_GROUP (alias->decl)
804 && (DECL_COMDAT_GROUP (alias->decl)
805 != DECL_COMDAT_GROUP (original->decl)))
809 "Wrapper cannot be created because of COMDAT\n");
811 else if (DECL_STATIC_CHAIN (alias->decl))
815 "Can not create wrapper of nested functions.\n");
817 /* TODO: We can also deal with variadic functions never calling
819 else if (stdarg_p (TREE_TYPE (alias->decl)))
823 "can not create wrapper of stdarg function.\n");
825 else if (inline_summaries
826 && inline_summaries->get (alias)->self_size <= 2)
829 fprintf (dump_file, "Wrapper creation is not "
830 "profitable (function is too small).\n");
832 /* If user paid attention to mark function noinline, assume it is
833 somewhat special and do not try to turn it into a wrapper that can
834 not be undone by inliner. */
835 else if (lookup_attribute ("noinline", DECL_ATTRIBUTES (alias->decl)))
838 fprintf (dump_file, "Wrappers are not created for noinline.\n");
841 create_wrapper = true;
843 /* We can redirect local calls in the case both alias and orignal
844 are not interposable. */
846 = alias->get_availability () > AVAIL_INTERPOSABLE
847 && original->get_availability () > AVAIL_INTERPOSABLE
848 && !alias->instrumented_version;
850 if (!redirect_callers && !create_wrapper)
853 fprintf (dump_file, "Not unifying; can not redirect callers nor "
854 "produce wrapper\n\n");
858 /* Work out the symbol the wrapper should call.
859 If ORIGINAL is interposable, we need to call a local alias.
860 Also produce local alias (if possible) as an optimization.
862 Local aliases can not be created inside comdat groups because that
863 prevents inlining. */
864 if (!original_discardable && !original->get_comdat_group ())
867 = dyn_cast <cgraph_node *> (original->noninterposable_alias ());
869 && original->get_availability () > AVAIL_INTERPOSABLE)
870 local_original = original;
872 /* If we can not use local alias, fallback to the original
874 else if (original->get_availability () > AVAIL_INTERPOSABLE)
875 local_original = original;
877 /* If original is COMDAT local, we can not really redirect calls outside
878 of its comdat group to it. */
879 if (original->comdat_local_p ())
880 redirect_callers = false;
884 fprintf (dump_file, "Not unifying; "
885 "can not produce local alias.\n\n");
889 if (!redirect_callers && !create_wrapper)
892 fprintf (dump_file, "Not unifying; "
893 "can not redirect callers nor produce a wrapper\n\n");
897 && !alias->can_remove_if_no_direct_calls_p ())
900 fprintf (dump_file, "Not unifying; can not make wrapper and "
901 "function has other uses than direct calls\n\n");
908 if (redirect_callers)
910 int nredirected = redirect_all_callers (alias, local_original);
914 alias->icf_merged = true;
915 local_original->icf_merged = true;
917 if (dump_file && nredirected)
918 fprintf (dump_file, "%i local calls have been "
919 "redirected.\n", nredirected);
922 /* If all callers was redirected, do not produce wrapper. */
923 if (alias->can_remove_if_no_direct_calls_p ()
924 && !alias->has_aliases_p ())
926 create_wrapper = false;
929 gcc_assert (!create_alias);
931 else if (create_alias)
933 alias->icf_merged = true;
935 /* Remove the function's body. */
936 ipa_merge_profiles (original, alias);
937 alias->release_body (true);
939 /* Notice global symbol possibly produced RTL. */
940 ((symtab_node *)alias)->call_for_symbol_and_aliases (clear_decl_rtl,
943 /* Create the alias. */
944 cgraph_node::create_alias (alias_func->decl, decl);
945 alias->resolve_alias (original);
947 original->call_for_symbol_thunks_and_aliases
948 (set_local, (void *)(size_t) original->local_p (), true);
951 fprintf (dump_file, "Unified; Function alias has been created.\n\n");
955 gcc_assert (!create_alias);
956 alias->icf_merged = true;
957 local_original->icf_merged = true;
959 ipa_merge_profiles (local_original, alias, true);
960 alias->create_wrapper (local_original);
963 fprintf (dump_file, "Unified; Wrapper has been created.\n\n");
965 gcc_assert (alias->icf_merged || remove);
966 original->icf_merged = true;
968 /* Inform the inliner about cross-module merging. */
969 if ((original->lto_file_data || alias->lto_file_data)
970 && original->lto_file_data != alias->lto_file_data)
971 local_original->merged = original->merged = true;
975 ipa_merge_profiles (original, alias);
976 alias->release_body ();
978 alias->body_removed = true;
979 alias->icf_merged = true;
981 fprintf (dump_file, "Unified; Function body was removed.\n");
987 /* Semantic item initialization function. */
990 sem_function::init (void)
993 get_node ()->get_untransformed_body ();
995 tree fndecl = node->decl;
996 function *func = DECL_STRUCT_FUNCTION (fndecl);
999 gcc_assert (SSANAMES (func));
1001 ssa_names_size = SSANAMES (func)->length ();
1005 region_tree = func->eh->region_tree;
1007 /* iterating all function arguments. */
1008 arg_count = count_formal_params (fndecl);
1010 edge_count = n_edges_for_fn (func);
1011 cfg_checksum = coverage_compute_cfg_checksum (func);
1013 inchash::hash hstate;
1016 FOR_EACH_BB_FN (bb, func)
1018 unsigned nondbg_stmt_count = 0;
1021 for (edge_iterator ei = ei_start (bb->preds); ei_cond (ei, &e); ei_next (&ei))
1022 cfg_checksum = iterative_hash_host_wide_int (e->flags,
1025 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
1028 gimple stmt = gsi_stmt (gsi);
1030 if (gimple_code (stmt) != GIMPLE_DEBUG)
1032 hash_stmt (&hstate, stmt);
1033 nondbg_stmt_count++;
1037 gcode_hash = hstate.end ();
1038 bb_sizes.safe_push (nondbg_stmt_count);
1040 /* Inserting basic block to hash table. */
1041 sem_bb *semantic_bb = new sem_bb (bb, nondbg_stmt_count,
1042 EDGE_COUNT (bb->preds) + EDGE_COUNT (bb->succs));
1044 bb_sorted.safe_push (semantic_bb);
1050 /* Improve accumulated hash for HSTATE based on a gimple statement STMT. */
1053 sem_function::hash_stmt (inchash::hash *hstate, gimple stmt)
1055 enum gimple_code code = gimple_code (stmt);
1057 hstate->add_int (code);
1059 if (code == GIMPLE_CALL)
1061 /* Checking of argument. */
1062 for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i)
1064 tree argument = gimple_call_arg (stmt, i);
1066 switch (TREE_CODE (argument))
1069 if (tree_fits_shwi_p (argument))
1070 hstate->add_wide_int (tree_to_shwi (argument));
1071 else if (tree_fits_uhwi_p (argument))
1072 hstate->add_wide_int (tree_to_uhwi (argument));
1078 c = TREE_REAL_CST (argument);
1079 n = real_to_integer (&c);
1081 hstate->add_wide_int (n);
1085 tree addr_operand = TREE_OPERAND (argument, 0);
1087 if (TREE_CODE (addr_operand) == STRING_CST)
1088 hstate->add (TREE_STRING_POINTER (addr_operand),
1089 TREE_STRING_LENGTH (addr_operand));
1100 /* Return true if polymorphic comparison must be processed. */
1103 sem_function::compare_polymorphic_p (void)
1105 return get_node ()->callees != NULL
1106 || get_node ()->indirect_calls != NULL
1107 || m_compared_func->get_node ()->callees != NULL
1108 || m_compared_func->get_node ()->indirect_calls != NULL;
1111 /* For a given call graph NODE, the function constructs new
1112 semantic function item. */
1115 sem_function::parse (cgraph_node *node, bitmap_obstack *stack)
1117 tree fndecl = node->decl;
1118 function *func = DECL_STRUCT_FUNCTION (fndecl);
1120 /* TODO: add support for thunks and aliases. */
1122 if (!func || !node->has_gimple_body_p ())
1125 if (lookup_attribute_by_prefix ("omp ", DECL_ATTRIBUTES (node->decl)) != NULL)
1128 sem_function *f = new sem_function (node, 0, stack);
1135 /* Parses function arguments and result type. */
1138 sem_function::parse_tree_args (void)
1142 if (arg_types.exists ())
1143 arg_types.release ();
1145 arg_types.create (4);
1146 tree fnargs = DECL_ARGUMENTS (decl);
1148 for (tree parm = fnargs; parm; parm = DECL_CHAIN (parm))
1149 arg_types.safe_push (DECL_ARG_TYPE (parm));
1151 /* Function result type. */
1152 result = DECL_RESULT (decl);
1153 result_type = result ? TREE_TYPE (result) : NULL;
1155 /* During WPA, we can get arguments by following method. */
1158 tree type = TYPE_ARG_TYPES (TREE_TYPE (decl));
1159 for (tree parm = type; parm; parm = TREE_CHAIN (parm))
1160 arg_types.safe_push (TYPE_CANONICAL (TREE_VALUE (parm)));
1162 result_type = TREE_TYPE (TREE_TYPE (decl));
1166 /* For given basic blocks BB1 and BB2 (from functions FUNC1 and FUNC),
1167 return true if phi nodes are semantically equivalent in these blocks . */
1170 sem_function::compare_phi_node (basic_block bb1, basic_block bb2)
1172 gphi_iterator si1, si2;
1174 unsigned size1, size2, i;
1178 gcc_assert (bb1 != NULL);
1179 gcc_assert (bb2 != NULL);
1181 si2 = gsi_start_phis (bb2);
1182 for (si1 = gsi_start_phis (bb1); !gsi_end_p (si1);
1185 gsi_next_nonvirtual_phi (&si1);
1186 gsi_next_nonvirtual_phi (&si2);
1188 if (gsi_end_p (si1) && gsi_end_p (si2))
1191 if (gsi_end_p (si1) || gsi_end_p (si2))
1192 return return_false();
1197 tree phi_result1 = gimple_phi_result (phi1);
1198 tree phi_result2 = gimple_phi_result (phi2);
1200 if (!m_checker->compare_operand (phi_result1, phi_result2))
1201 return return_false_with_msg ("PHI results are different");
1203 size1 = gimple_phi_num_args (phi1);
1204 size2 = gimple_phi_num_args (phi2);
1207 return return_false ();
1209 for (i = 0; i < size1; ++i)
1211 t1 = gimple_phi_arg (phi1, i)->def;
1212 t2 = gimple_phi_arg (phi2, i)->def;
1214 if (!m_checker->compare_operand (t1, t2))
1215 return return_false ();
1217 e1 = gimple_phi_arg_edge (phi1, i);
1218 e2 = gimple_phi_arg_edge (phi2, i);
1220 if (!m_checker->compare_edge (e1, e2))
1221 return return_false ();
1230 /* Returns true if tree T can be compared as a handled component. */
1233 sem_function::icf_handled_component_p (tree t)
1235 tree_code tc = TREE_CODE (t);
1237 return ((handled_component_p (t))
1238 || tc == ADDR_EXPR || tc == MEM_REF || tc == REALPART_EXPR
1239 || tc == IMAGPART_EXPR || tc == OBJ_TYPE_REF);
1242 /* Basic blocks dictionary BB_DICT returns true if SOURCE index BB
1243 corresponds to TARGET. */
1246 sem_function::bb_dict_test (vec<int> *bb_dict, int source, int target)
1251 if (bb_dict->length () <= (unsigned)source)
1252 bb_dict->safe_grow_cleared (source + 1);
1254 if ((*bb_dict)[source] == 0)
1256 (*bb_dict)[source] = target;
1260 return (*bb_dict)[source] == target;
1263 /* Iterates all tree types in T1 and T2 and returns true if all types
1264 are compatible. If COMPARE_POLYMORPHIC is set to true,
1265 more strict comparison is executed. */
1268 sem_function::compare_type_list (tree t1, tree t2, bool compare_polymorphic)
1276 while (t1 != NULL && t2 != NULL)
1278 tv1 = TREE_VALUE (t1);
1279 tv2 = TREE_VALUE (t2);
1281 tc1 = TREE_CODE (tv1);
1282 tc2 = TREE_CODE (tv2);
1284 if (tc1 == NOP_EXPR && tc2 == NOP_EXPR)
1286 else if (tc1 == NOP_EXPR || tc2 == NOP_EXPR)
1288 else if (!func_checker::compatible_types_p (tv1, tv2, compare_polymorphic))
1291 t1 = TREE_CHAIN (t1);
1292 t2 = TREE_CHAIN (t2);
1299 /* Semantic variable constructor that uses STACK as bitmap memory stack. */
1301 sem_variable::sem_variable (bitmap_obstack *stack): sem_item (VAR, stack)
1305 /* Constructor based on varpool node _NODE with computed hash _HASH.
1306 Bitmap STACK is used for memory allocation. */
1308 sem_variable::sem_variable (varpool_node *node, hashval_t _hash,
1309 bitmap_obstack *stack): sem_item(VAR,
1312 gcc_checking_assert (node);
1313 gcc_checking_assert (get_node ());
1316 /* Returns true if the item equals to ITEM given as argument. */
1319 sem_variable::equals (sem_item *item,
1320 hash_map <symtab_node *, sem_item *> & ARG_UNUSED (ignored_nodes))
1322 gcc_assert (item->type == VAR);
1324 sem_variable *v = static_cast<sem_variable *>(item);
1326 if (!ctor || !v->ctor)
1327 return return_false_with_msg ("ctor is missing for semantic variable");
1329 if (DECL_IN_CONSTANT_POOL (decl)
1330 && (DECL_IN_CONSTANT_POOL (item->decl)
1331 || item->node->address_matters_p ()))
1332 return return_false_with_msg ("constant pool");
1334 if (DECL_IN_TEXT_SECTION (decl) != DECL_IN_TEXT_SECTION (item->decl))
1335 return return_false_with_msg ("text section");
1337 if (DECL_TLS_MODEL (decl) || DECL_TLS_MODEL (item->decl))
1338 return return_false_with_msg ("TLS model");
1340 return sem_variable::equals (ctor, v->ctor);
1343 /* Compares trees T1 and T2 for semantic equality. */
1346 sem_variable::equals (tree t1, tree t2)
1348 tree_code tc1 = TREE_CODE (t1);
1349 tree_code tc2 = TREE_CODE (t2);
1358 unsigned len1 = vec_safe_length (CONSTRUCTOR_ELTS (t1));
1359 unsigned len2 = vec_safe_length (CONSTRUCTOR_ELTS (t2));
1364 for (unsigned i = 0; i < len1; i++)
1365 if (!sem_variable::equals (CONSTRUCTOR_ELT (t1, i)->value,
1366 CONSTRUCTOR_ELT (t2, i)->value)
1367 || CONSTRUCTOR_ELT (t1, i)->index != CONSTRUCTOR_ELT (t2, i)->index)
1374 tree x1 = TREE_OPERAND (t1, 0);
1375 tree x2 = TREE_OPERAND (t2, 0);
1376 tree y1 = TREE_OPERAND (t1, 1);
1377 tree y2 = TREE_OPERAND (t2, 1);
1379 if (!func_checker::compatible_types_p (TREE_TYPE (x1), TREE_TYPE (x2),
1381 return return_false ();
1383 /* Type of the offset on MEM_REF does not matter. */
1384 return sem_variable::equals (x1, x2)
1385 && wi::to_offset (y1) == wi::to_offset (y2);
1390 tree op1 = TREE_OPERAND (t1, 0);
1391 tree op2 = TREE_OPERAND (t2, 0);
1392 return sem_variable::equals (op1, op2);
1400 return func_checker::compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2),
1402 && wi::to_offset (t1) == wi::to_offset (t2);
1406 return operand_equal_p (t1, t2, OEP_ONLY_CONST);
1409 case POINTER_PLUS_EXPR:
1411 tree x1 = TREE_OPERAND (t1, 0);
1412 tree x2 = TREE_OPERAND (t2, 0);
1413 tree y1 = TREE_OPERAND (t1, 1);
1414 tree y2 = TREE_OPERAND (t2, 1);
1416 return sem_variable::equals (x1, x2) && sem_variable::equals (y1, y2);
1419 return return_false_with_msg ("ERROR_MARK");
1421 return return_false_with_msg ("Unknown TREE code reached");
1425 /* Parser function that visits a varpool NODE. */
1428 sem_variable::parse (varpool_node *node, bitmap_obstack *stack)
1430 tree decl = node->decl;
1432 bool readonly = TYPE_P (decl) ? TYPE_READONLY (decl) : TREE_READONLY (decl);
1436 bool can_handle = DECL_VIRTUAL_P (decl)
1437 || flag_merge_constants >= 2
1438 || (!TREE_ADDRESSABLE (decl) && !node->externally_visible);
1440 if (!can_handle || DECL_EXTERNAL (decl))
1443 tree ctor = ctor_for_folding (decl);
1447 sem_variable *v = new sem_variable (node, 0, stack);
1454 /* References independent hash function. */
1457 sem_variable::get_hash (void)
1462 inchash::hash hstate;
1464 hstate.add_int (456346417);
1465 hstate.add_int (TREE_CODE (ctor));
1467 if (TREE_CODE (ctor) == CONSTRUCTOR)
1469 unsigned length = vec_safe_length (CONSTRUCTOR_ELTS (ctor));
1470 hstate.add_int (length);
1473 hash = hstate.end ();
1478 /* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can
1482 sem_variable::merge (sem_item *alias_item)
1484 gcc_assert (alias_item->type == VAR);
1486 if (!sem_item::target_supports_symbol_aliases_p ())
1489 fprintf (dump_file, "Not unifying; "
1490 "Symbol aliases are not supported by target\n\n");
1494 sem_variable *alias_var = static_cast<sem_variable *> (alias_item);
1496 varpool_node *original = get_node ();
1497 varpool_node *alias = alias_var->get_node ();
1498 bool original_discardable = false;
1500 bool original_address_matters = original->address_matters_p ();
1501 bool alias_address_matters = alias->address_matters_p ();
1503 /* See if original is in a section that can be discarded if the main
1505 Also consider case where we have resolution info and we know that
1506 original's definition is not going to be used. In this case we can not
1507 create alias to original. */
1508 if (original->can_be_discarded_p ()
1509 || (node->resolution != LDPR_UNKNOWN
1510 && !decl_binds_to_current_def_p (node->decl)))
1511 original_discardable = true;
1513 gcc_assert (!TREE_ASM_WRITTEN (alias->decl));
1515 /* Constant pool machinery is not quite ready for aliases.
1516 TODO: varasm code contains logic for merging DECL_IN_CONSTANT_POOL.
1517 For LTO merging does not happen that is an important missing feature.
1518 We can enable merging with LTO if the DECL_IN_CONSTANT_POOL
1519 flag is dropped and non-local symbol name is assigned. */
1520 if (DECL_IN_CONSTANT_POOL (alias->decl)
1521 || DECL_IN_CONSTANT_POOL (original->decl))
1525 "Not unifying; constant pool variables.\n\n");
1529 /* Do not attempt to mix functions from different user sections;
1530 we do not know what user intends with those. */
1531 if (((DECL_SECTION_NAME (original->decl) && !original->implicit_section)
1532 || (DECL_SECTION_NAME (alias->decl) && !alias->implicit_section))
1533 && DECL_SECTION_NAME (original->decl) != DECL_SECTION_NAME (alias->decl))
1538 "original and alias are in different sections.\n\n");
1542 /* We can not merge if address comparsion metters. */
1543 if (original_address_matters && alias_address_matters
1544 && flag_merge_constants < 2)
1549 "adress of original and alias may be compared.\n\n");
1552 if (DECL_COMDAT_GROUP (original->decl) != DECL_COMDAT_GROUP (alias->decl))
1555 fprintf (dump_file, "Not unifying; alias cannot be created; "
1556 "across comdat group boundary\n\n");
1561 if (original_discardable)
1564 fprintf (dump_file, "Not unifying; alias cannot be created; "
1565 "target is discardable\n\n");
1571 gcc_assert (!original->alias);
1572 gcc_assert (!alias->alias);
1574 alias->analyzed = false;
1576 DECL_INITIAL (alias->decl) = NULL;
1577 ((symtab_node *)alias)->call_for_symbol_and_aliases (clear_decl_rtl,
1579 alias->need_bounds_init = false;
1580 alias->remove_all_references ();
1581 if (TREE_ADDRESSABLE (alias->decl))
1582 original->call_for_symbol_and_aliases (set_addressable, NULL, true);
1584 varpool_node::create_alias (alias_var->decl, decl);
1585 alias->resolve_alias (original);
1588 fprintf (dump_file, "Unified; Variable alias has been created.\n\n");
1594 /* Dump symbol to FILE. */
1597 sem_variable::dump_to_file (FILE *file)
1601 print_node (file, "", decl, 0);
1602 fprintf (file, "\n\n");
1605 /* Iterates though a constructor and identifies tree references
1606 we are interested in semantic function equality. */
1609 sem_variable::parse_tree_refs (tree t)
1611 switch (TREE_CODE (t))
1615 unsigned length = vec_safe_length (CONSTRUCTOR_ELTS (t));
1617 for (unsigned i = 0; i < length; i++)
1618 parse_tree_refs(CONSTRUCTOR_ELT (t, i)->value);
1625 tree op = TREE_OPERAND (t, 0);
1626 parse_tree_refs (op);
1631 tree_refs.safe_push (t);
1639 unsigned int sem_item_optimizer::class_id = 0;
1641 sem_item_optimizer::sem_item_optimizer (): worklist (0), m_classes (0),
1642 m_classes_count (0), m_cgraph_node_hooks (NULL), m_varpool_node_hooks (NULL)
1645 bitmap_obstack_initialize (&m_bmstack);
1648 sem_item_optimizer::~sem_item_optimizer ()
1650 for (unsigned int i = 0; i < m_items.length (); i++)
1653 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
1654 it != m_classes.end (); ++it)
1656 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
1657 delete (*it)->classes[i];
1659 (*it)->classes.release ();
1665 bitmap_obstack_release (&m_bmstack);
1668 /* Write IPA ICF summary for symbols. */
1671 sem_item_optimizer::write_summary (void)
1673 unsigned int count = 0;
1675 output_block *ob = create_output_block (LTO_section_ipa_icf);
1676 lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
1679 /* Calculate number of symbols to be serialized. */
1680 for (lto_symtab_encoder_iterator lsei = lsei_start_in_partition (encoder);
1682 lsei_next_in_partition (&lsei))
1684 symtab_node *node = lsei_node (lsei);
1686 if (m_symtab_node_map.get (node))
1690 streamer_write_uhwi (ob, count);
1692 /* Process all of the symbols. */
1693 for (lto_symtab_encoder_iterator lsei = lsei_start_in_partition (encoder);
1695 lsei_next_in_partition (&lsei))
1697 symtab_node *node = lsei_node (lsei);
1699 sem_item **item = m_symtab_node_map.get (node);
1703 int node_ref = lto_symtab_encoder_encode (encoder, node);
1704 streamer_write_uhwi_stream (ob->main_stream, node_ref);
1706 streamer_write_uhwi (ob, (*item)->get_hash ());
1710 streamer_write_char_stream (ob->main_stream, 0);
1711 produce_asm (ob, NULL);
1712 destroy_output_block (ob);
1715 /* Reads a section from LTO stream file FILE_DATA. Input block for DATA
1716 contains LEN bytes. */
1719 sem_item_optimizer::read_section (lto_file_decl_data *file_data,
1720 const char *data, size_t len)
1722 const lto_function_header *header =
1723 (const lto_function_header *) data;
1724 const int cfg_offset = sizeof (lto_function_header);
1725 const int main_offset = cfg_offset + header->cfg_size;
1726 const int string_offset = main_offset + header->main_size;
1731 lto_input_block ib_main ((const char *) data + main_offset, 0,
1732 header->main_size, file_data->mode_table);
1735 lto_data_in_create (file_data, (const char *) data + string_offset,
1736 header->string_size, vNULL);
1738 count = streamer_read_uhwi (&ib_main);
1740 for (i = 0; i < count; i++)
1744 lto_symtab_encoder_t encoder;
1746 index = streamer_read_uhwi (&ib_main);
1747 encoder = file_data->symtab_node_encoder;
1748 node = lto_symtab_encoder_deref (encoder, index);
1750 hashval_t hash = streamer_read_uhwi (&ib_main);
1752 gcc_assert (node->definition);
1755 fprintf (dump_file, "Symbol added:%s (tree: %p, uid:%u)\n", node->asm_name (),
1756 (void *) node->decl, node->order);
1758 if (is_a<cgraph_node *> (node))
1760 cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
1762 m_items.safe_push (new sem_function (cnode, hash, &m_bmstack));
1766 varpool_node *vnode = dyn_cast <varpool_node *> (node);
1768 m_items.safe_push (new sem_variable (vnode, hash, &m_bmstack));
1772 lto_free_section_data (file_data, LTO_section_ipa_icf, NULL, data,
1774 lto_data_in_delete (data_in);
1777 /* Read IPA IPA ICF summary for symbols. */
1780 sem_item_optimizer::read_summary (void)
1782 lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
1783 lto_file_decl_data *file_data;
1786 while ((file_data = file_data_vec[j++]))
1789 const char *data = lto_get_section_data (file_data,
1790 LTO_section_ipa_icf, NULL, &len);
1793 read_section (file_data, data, len);
1797 /* Register callgraph and varpool hooks. */
1800 sem_item_optimizer::register_hooks (void)
1802 if (!m_cgraph_node_hooks)
1803 m_cgraph_node_hooks = symtab->add_cgraph_removal_hook
1804 (&sem_item_optimizer::cgraph_removal_hook, this);
1806 if (!m_varpool_node_hooks)
1807 m_varpool_node_hooks = symtab->add_varpool_removal_hook
1808 (&sem_item_optimizer::varpool_removal_hook, this);
1811 /* Unregister callgraph and varpool hooks. */
1814 sem_item_optimizer::unregister_hooks (void)
1816 if (m_cgraph_node_hooks)
1817 symtab->remove_cgraph_removal_hook (m_cgraph_node_hooks);
1819 if (m_varpool_node_hooks)
1820 symtab->remove_varpool_removal_hook (m_varpool_node_hooks);
1823 /* Adds a CLS to hashtable associated by hash value. */
1826 sem_item_optimizer::add_class (congruence_class *cls)
1828 gcc_assert (cls->members.length ());
1830 congruence_class_group *group = get_group_by_hash (
1831 cls->members[0]->get_hash (),
1832 cls->members[0]->type);
1833 group->classes.safe_push (cls);
1836 /* Gets a congruence class group based on given HASH value and TYPE. */
1838 congruence_class_group *
1839 sem_item_optimizer::get_group_by_hash (hashval_t hash, sem_item_type type)
1841 congruence_class_group *item = XNEW (congruence_class_group);
1845 congruence_class_group **slot = m_classes.find_slot (item, INSERT);
1851 item->classes.create (1);
1858 /* Callgraph removal hook called for a NODE with a custom DATA. */
1861 sem_item_optimizer::cgraph_removal_hook (cgraph_node *node, void *data)
1863 sem_item_optimizer *optimizer = (sem_item_optimizer *) data;
1864 optimizer->remove_symtab_node (node);
1867 /* Varpool removal hook called for a NODE with a custom DATA. */
1870 sem_item_optimizer::varpool_removal_hook (varpool_node *node, void *data)
1872 sem_item_optimizer *optimizer = (sem_item_optimizer *) data;
1873 optimizer->remove_symtab_node (node);
1876 /* Remove symtab NODE triggered by symtab removal hooks. */
1879 sem_item_optimizer::remove_symtab_node (symtab_node *node)
1881 gcc_assert (!m_classes.elements());
1883 m_removed_items_set.add (node);
1887 sem_item_optimizer::remove_item (sem_item *item)
1889 if (m_symtab_node_map.get (item->node))
1890 m_symtab_node_map.remove (item->node);
1894 /* Removes all callgraph and varpool nodes that are marked by symtab
1898 sem_item_optimizer::filter_removed_items (void)
1900 auto_vec <sem_item *> filtered;
1902 for (unsigned int i = 0; i < m_items.length(); i++)
1904 sem_item *item = m_items[i];
1906 if (m_removed_items_set.contains (item->node))
1912 if (item->type == FUNC)
1914 cgraph_node *cnode = static_cast <sem_function *>(item)->get_node ();
1916 bool no_body_function = in_lto_p && (cnode->alias || cnode->body_removed);
1917 if (no_body_function || !opt_for_fn (item->decl, flag_ipa_icf_functions)
1918 || DECL_CXX_CONSTRUCTOR_P (item->decl)
1919 || DECL_CXX_DESTRUCTOR_P (item->decl))
1922 filtered.safe_push (item);
1926 if (!flag_ipa_icf_variables)
1929 filtered.safe_push (item);
1933 /* Clean-up of released semantic items. */
1936 for (unsigned int i = 0; i < filtered.length(); i++)
1937 m_items.safe_push (filtered[i]);
1940 /* Optimizer entry point. */
1943 sem_item_optimizer::execute (void)
1945 filter_removed_items ();
1946 unregister_hooks ();
1948 build_hash_based_classes ();
1951 fprintf (dump_file, "Dump after hash based groups\n");
1952 dump_cong_classes ();
1954 for (unsigned int i = 0; i < m_items.length(); i++)
1955 m_items[i]->init_wpa ();
1959 subdivide_classes_by_equality (true);
1962 fprintf (dump_file, "Dump after WPA based types groups\n");
1964 dump_cong_classes ();
1966 process_cong_reduction ();
1970 fprintf (dump_file, "Dump after callgraph-based congruence reduction\n");
1972 dump_cong_classes ();
1974 parse_nonsingleton_classes ();
1975 subdivide_classes_by_equality ();
1978 fprintf (dump_file, "Dump after full equality comparison of groups\n");
1980 dump_cong_classes ();
1982 unsigned int prev_class_count = m_classes_count;
1984 process_cong_reduction ();
1985 dump_cong_classes ();
1987 merge_classes (prev_class_count);
1989 if (dump_file && (dump_flags & TDF_DETAILS))
1990 symtab_node::dump_table (dump_file);
1993 /* Function responsible for visiting all potential functions and
1994 read-only variables that can be merged. */
1997 sem_item_optimizer::parse_funcs_and_vars (void)
2001 if (flag_ipa_icf_functions)
2002 FOR_EACH_DEFINED_FUNCTION (cnode)
2004 sem_function *f = sem_function::parse (cnode, &m_bmstack);
2007 m_items.safe_push (f);
2008 m_symtab_node_map.put (cnode, f);
2011 fprintf (dump_file, "Parsed function:%s\n", f->asm_name ());
2013 if (dump_file && (dump_flags & TDF_DETAILS))
2014 f->dump_to_file (dump_file);
2017 fprintf (dump_file, "Not parsed function:%s\n", cnode->asm_name ());
2020 varpool_node *vnode;
2022 if (flag_ipa_icf_variables)
2023 FOR_EACH_DEFINED_VARIABLE (vnode)
2025 sem_variable *v = sem_variable::parse (vnode, &m_bmstack);
2029 m_items.safe_push (v);
2030 m_symtab_node_map.put (vnode, v);
2035 /* Makes pairing between a congruence class CLS and semantic ITEM. */
2038 sem_item_optimizer::add_item_to_class (congruence_class *cls, sem_item *item)
2040 item->index_in_class = cls->members.length ();
2041 cls->members.safe_push (item);
2045 /* Congruence classes are built by hash value. */
2048 sem_item_optimizer::build_hash_based_classes (void)
2050 for (unsigned i = 0; i < m_items.length (); i++)
2052 sem_item *item = m_items[i];
2054 congruence_class_group *group = get_group_by_hash (item->get_hash (),
2057 if (!group->classes.length ())
2060 group->classes.safe_push (new congruence_class (class_id++));
2063 add_item_to_class (group->classes[0], item);
2067 /* Build references according to call graph. */
2070 sem_item_optimizer::build_graph (void)
2072 for (unsigned i = 0; i < m_items.length (); i++)
2074 sem_item *item = m_items[i];
2075 m_symtab_node_map.put (item->node, item);
2078 for (unsigned i = 0; i < m_items.length (); i++)
2080 sem_item *item = m_items[i];
2082 if (item->type == FUNC)
2084 cgraph_node *cnode = dyn_cast <cgraph_node *> (item->node);
2086 cgraph_edge *e = cnode->callees;
2089 sem_item **slot = m_symtab_node_map.get (e->callee);
2091 item->add_reference (*slot);
2097 ipa_ref *ref = NULL;
2098 for (unsigned i = 0; item->node->iterate_reference (i, ref); i++)
2100 sem_item **slot = m_symtab_node_map.get (ref->referred);
2102 item->add_reference (*slot);
2107 /* Semantic items in classes having more than one element and initialized.
2108 In case of WPA, we load function body. */
2111 sem_item_optimizer::parse_nonsingleton_classes (void)
2113 unsigned int init_called_count = 0;
2115 for (unsigned i = 0; i < m_items.length (); i++)
2116 if (m_items[i]->cls->members.length () > 1)
2118 m_items[i]->init ();
2119 init_called_count++;
2123 fprintf (dump_file, "Init called for %u items (%.2f%%).\n", init_called_count,
2124 m_items.length () ? 100.0f * init_called_count / m_items.length (): 0.0f);
2127 /* Equality function for semantic items is used to subdivide existing
2128 classes. If IN_WPA, fast equality function is invoked. */
2131 sem_item_optimizer::subdivide_classes_by_equality (bool in_wpa)
2133 for (hash_table <congruence_class_group_hash>::iterator it = m_classes.begin ();
2134 it != m_classes.end (); ++it)
2136 unsigned int class_count = (*it)->classes.length ();
2138 for (unsigned i = 0; i < class_count; i++)
2140 congruence_class *c = (*it)->classes [i];
2142 if (c->members.length() > 1)
2144 auto_vec <sem_item *> new_vector;
2146 sem_item *first = c->members[0];
2147 new_vector.safe_push (first);
2149 unsigned class_split_first = (*it)->classes.length ();
2151 for (unsigned j = 1; j < c->members.length (); j++)
2153 sem_item *item = c->members[j];
2155 bool equals = in_wpa ? first->equals_wpa (item,
2156 m_symtab_node_map) : first->equals (item, m_symtab_node_map);
2159 new_vector.safe_push (item);
2162 bool integrated = false;
2164 for (unsigned k = class_split_first; k < (*it)->classes.length (); k++)
2166 sem_item *x = (*it)->classes[k]->members[0];
2167 bool equals = in_wpa ? x->equals_wpa (item,
2168 m_symtab_node_map) : x->equals (item, m_symtab_node_map);
2173 add_item_to_class ((*it)->classes[k], item);
2181 congruence_class *c = new congruence_class (class_id++);
2183 add_item_to_class (c, item);
2185 (*it)->classes.safe_push (c);
2190 // we replace newly created new_vector for the class we've just splitted
2191 c->members.release ();
2192 c->members.create (new_vector.length ());
2194 for (unsigned int j = 0; j < new_vector.length (); j++)
2195 add_item_to_class (c, new_vector[j]);
2203 /* Subdivide classes by address references that members of the class
2204 reference. Example can be a pair of functions that have an address
2205 taken from a function. If these addresses are different the class
2209 sem_item_optimizer::subdivide_classes_by_sensitive_refs ()
2211 unsigned newly_created_classes = 0;
2213 for (hash_table <congruence_class_group_hash>::iterator it = m_classes.begin ();
2214 it != m_classes.end (); ++it)
2216 unsigned int class_count = (*it)->classes.length ();
2217 auto_vec<congruence_class *> new_classes;
2219 for (unsigned i = 0; i < class_count; i++)
2221 congruence_class *c = (*it)->classes [i];
2223 if (c->members.length() > 1)
2225 hash_map <symbol_compare_collection *, vec <sem_item *>,
2226 symbol_compare_hashmap_traits> split_map;
2228 for (unsigned j = 0; j < c->members.length (); j++)
2230 sem_item *source_node = c->members[j];
2232 symbol_compare_collection *collection = new symbol_compare_collection (source_node->node);
2234 vec <sem_item *> *slot = &split_map.get_or_insert (collection);
2235 gcc_checking_assert (slot);
2237 slot->safe_push (source_node);
2240 /* If the map contains more than one key, we have to split the map
2242 if (split_map.elements () != 1)
2244 bool first_class = true;
2246 hash_map <symbol_compare_collection *, vec <sem_item *>,
2247 symbol_compare_hashmap_traits>::iterator it2 = split_map.begin ();
2248 for (; it2 != split_map.end (); ++it2)
2250 congruence_class *new_cls;
2251 new_cls = new congruence_class (class_id++);
2253 for (unsigned k = 0; k < (*it2).second.length (); k++)
2254 add_item_to_class (new_cls, (*it2).second[k]);
2256 worklist_push (new_cls);
2257 newly_created_classes++;
2261 (*it)->classes[i] = new_cls;
2262 first_class = false;
2266 new_classes.safe_push (new_cls);
2274 for (unsigned i = 0; i < new_classes.length (); i++)
2275 (*it)->classes.safe_push (new_classes[i]);
2278 return newly_created_classes;
2281 /* Verify congruence classes if checking is enabled. */
2284 sem_item_optimizer::verify_classes (void)
2287 for (hash_table <congruence_class_group_hash>::iterator it = m_classes.begin ();
2288 it != m_classes.end (); ++it)
2290 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
2292 congruence_class *cls = (*it)->classes[i];
2294 gcc_checking_assert (cls);
2295 gcc_checking_assert (cls->members.length () > 0);
2297 for (unsigned int j = 0; j < cls->members.length (); j++)
2299 sem_item *item = cls->members[j];
2301 gcc_checking_assert (item);
2302 gcc_checking_assert (item->cls == cls);
2304 for (unsigned k = 0; k < item->usages.length (); k++)
2306 sem_usage_pair *usage = item->usages[k];
2307 gcc_checking_assert (usage->item->index_in_class <
2308 usage->item->cls->members.length ());
2316 /* Disposes split map traverse function. CLS_PTR is pointer to congruence
2317 class, BSLOT is bitmap slot we want to release. DATA is mandatory,
2318 but unused argument. */
2321 sem_item_optimizer::release_split_map (congruence_class * const &,
2322 bitmap const &b, traverse_split_pair *)
2331 /* Process split operation for a class given as pointer CLS_PTR,
2332 where bitmap B splits congruence class members. DATA is used
2333 as argument of split pair. */
2336 sem_item_optimizer::traverse_congruence_split (congruence_class * const &cls,
2337 bitmap const &b, traverse_split_pair *pair)
2339 sem_item_optimizer *optimizer = pair->optimizer;
2340 const congruence_class *splitter_cls = pair->cls;
2342 /* If counted bits are greater than zero and less than the number of members
2343 a group will be splitted. */
2344 unsigned popcount = bitmap_count_bits (b);
2346 if (popcount > 0 && popcount < cls->members.length ())
2348 congruence_class* newclasses[2] = { new congruence_class (class_id++), new congruence_class (class_id++) };
2350 for (unsigned int i = 0; i < cls->members.length (); i++)
2352 int target = bitmap_bit_p (b, i);
2353 congruence_class *tc = newclasses[target];
2355 add_item_to_class (tc, cls->members[i]);
2358 #ifdef ENABLE_CHECKING
2359 for (unsigned int i = 0; i < 2; i++)
2360 gcc_checking_assert (newclasses[i]->members.length ());
2363 if (splitter_cls == cls)
2364 optimizer->splitter_class_removed = true;
2366 /* Remove old class from worklist if presented. */
2367 bool in_worklist = cls->in_worklist;
2370 cls->in_worklist = false;
2372 congruence_class_group g;
2373 g.hash = cls->members[0]->get_hash ();
2374 g.type = cls->members[0]->type;
2376 congruence_class_group *slot = optimizer->m_classes.find(&g);
2378 for (unsigned int i = 0; i < slot->classes.length (); i++)
2379 if (slot->classes[i] == cls)
2381 slot->classes.ordered_remove (i);
2385 /* New class will be inserted and integrated to work list. */
2386 for (unsigned int i = 0; i < 2; i++)
2387 optimizer->add_class (newclasses[i]);
2389 /* Two classes replace one, so that increment just by one. */
2390 optimizer->m_classes_count++;
2392 /* If OLD class was presented in the worklist, we remove the class
2393 and replace it will both newly created classes. */
2395 for (unsigned int i = 0; i < 2; i++)
2396 optimizer->worklist_push (newclasses[i]);
2397 else /* Just smaller class is inserted. */
2399 unsigned int smaller_index = newclasses[0]->members.length () <
2400 newclasses[1]->members.length () ?
2402 optimizer->worklist_push (newclasses[smaller_index]);
2405 if (dump_file && (dump_flags & TDF_DETAILS))
2407 fprintf (dump_file, " congruence class splitted:\n");
2408 cls->dump (dump_file, 4);
2410 fprintf (dump_file, " newly created groups:\n");
2411 for (unsigned int i = 0; i < 2; i++)
2412 newclasses[i]->dump (dump_file, 4);
2415 /* Release class if not presented in work list. */
2424 /* Tests if a class CLS used as INDEXth splits any congruence classes.
2425 Bitmap stack BMSTACK is used for bitmap allocation. */
2428 sem_item_optimizer::do_congruence_step_for_index (congruence_class *cls,
2431 hash_map <congruence_class *, bitmap> split_map;
2433 for (unsigned int i = 0; i < cls->members.length (); i++)
2435 sem_item *item = cls->members[i];
2437 /* Iterate all usages that have INDEX as usage of the item. */
2438 for (unsigned int j = 0; j < item->usages.length (); j++)
2440 sem_usage_pair *usage = item->usages[j];
2442 if (usage->index != index)
2445 bitmap *slot = split_map.get (usage->item->cls);
2450 b = BITMAP_ALLOC (&m_bmstack);
2451 split_map.put (usage->item->cls, b);
2457 gcc_checking_assert (usage->item->cls);
2458 gcc_checking_assert (usage->item->index_in_class <
2459 usage->item->cls->members.length ());
2462 bitmap_set_bit (b, usage->item->index_in_class);
2466 traverse_split_pair pair;
2467 pair.optimizer = this;
2470 splitter_class_removed = false;
2472 <traverse_split_pair *, sem_item_optimizer::traverse_congruence_split> (&pair);
2474 /* Bitmap clean-up. */
2476 <traverse_split_pair *, sem_item_optimizer::release_split_map> (NULL);
2479 /* Every usage of a congruence class CLS is a candidate that can split the
2480 collection of classes. Bitmap stack BMSTACK is used for bitmap
2484 sem_item_optimizer::do_congruence_step (congruence_class *cls)
2489 bitmap usage = BITMAP_ALLOC (&m_bmstack);
2491 for (unsigned int i = 0; i < cls->members.length (); i++)
2492 bitmap_ior_into (usage, cls->members[i]->usage_index_bitmap);
2494 EXECUTE_IF_SET_IN_BITMAP (usage, 0, i, bi)
2496 if (dump_file && (dump_flags & TDF_DETAILS))
2497 fprintf (dump_file, " processing congruece step for class: %u, index: %u\n",
2500 do_congruence_step_for_index (cls, i);
2502 if (splitter_class_removed)
2506 BITMAP_FREE (usage);
2509 /* Adds a newly created congruence class CLS to worklist. */
2512 sem_item_optimizer::worklist_push (congruence_class *cls)
2514 /* Return if the class CLS is already presented in work list. */
2515 if (cls->in_worklist)
2518 cls->in_worklist = true;
2519 worklist.push_back (cls);
2522 /* Pops a class from worklist. */
2525 sem_item_optimizer::worklist_pop (void)
2527 congruence_class *cls;
2529 while (!worklist.empty ())
2531 cls = worklist.front ();
2532 worklist.pop_front ();
2533 if (cls->in_worklist)
2535 cls->in_worklist = false;
2541 /* Work list item was already intended to be removed.
2542 The only reason for doing it is to split a class.
2543 Thus, the class CLS is deleted. */
2551 /* Iterative congruence reduction function. */
2554 sem_item_optimizer::process_cong_reduction (void)
2556 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2557 it != m_classes.end (); ++it)
2558 for (unsigned i = 0; i < (*it)->classes.length (); i++)
2559 if ((*it)->classes[i]->is_class_used ())
2560 worklist_push ((*it)->classes[i]);
2563 fprintf (dump_file, "Worklist has been filled with: %lu\n",
2564 (unsigned long) worklist.size ());
2566 if (dump_file && (dump_flags & TDF_DETAILS))
2567 fprintf (dump_file, "Congruence class reduction\n");
2569 congruence_class *cls;
2571 /* Process complete congruence reduction. */
2572 while ((cls = worklist_pop ()) != NULL)
2573 do_congruence_step (cls);
2575 /* Subdivide newly created classes according to references. */
2576 unsigned new_classes = subdivide_classes_by_sensitive_refs ();
2579 fprintf (dump_file, "Address reference subdivision created: %u "
2580 "new classes.\n", new_classes);
2583 /* Debug function prints all informations about congruence classes. */
2586 sem_item_optimizer::dump_cong_classes (void)
2592 "Congruence classes: %u (unique hash values: %lu), with total: %u items\n",
2593 m_classes_count, (unsigned long) m_classes.elements(), m_items.length ());
2595 /* Histogram calculation. */
2596 unsigned int max_index = 0;
2597 unsigned int* histogram = XCNEWVEC (unsigned int, m_items.length () + 1);
2599 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2600 it != m_classes.end (); ++it)
2602 for (unsigned i = 0; i < (*it)->classes.length (); i++)
2604 unsigned int c = (*it)->classes[i]->members.length ();
2612 "Class size histogram [num of members]: number of classe number of classess\n");
2614 for (unsigned int i = 0; i <= max_index; i++)
2616 fprintf (dump_file, "[%u]: %u classes\n", i, histogram[i]);
2618 fprintf (dump_file, "\n\n");
2621 if (dump_flags & TDF_DETAILS)
2622 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2623 it != m_classes.end (); ++it)
2625 fprintf (dump_file, " group: with %u classes:\n", (*it)->classes.length ());
2627 for (unsigned i = 0; i < (*it)->classes.length (); i++)
2629 (*it)->classes[i]->dump (dump_file, 4);
2631 if(i < (*it)->classes.length () - 1)
2632 fprintf (dump_file, " ");
2639 /* After reduction is done, we can declare all items in a group
2640 to be equal. PREV_CLASS_COUNT is start number of classes
2641 before reduction. */
2644 sem_item_optimizer::merge_classes (unsigned int prev_class_count)
2646 unsigned int item_count = m_items.length ();
2647 unsigned int class_count = m_classes_count;
2648 unsigned int equal_items = item_count - class_count;
2650 unsigned int non_singular_classes_count = 0;
2651 unsigned int non_singular_classes_sum = 0;
2653 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2654 it != m_classes.end (); ++it)
2655 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
2657 congruence_class *c = (*it)->classes[i];
2658 if (c->members.length () > 1)
2660 non_singular_classes_count++;
2661 non_singular_classes_sum += c->members.length ();
2667 fprintf (dump_file, "\nItem count: %u\n", item_count);
2668 fprintf (dump_file, "Congruent classes before: %u, after: %u\n",
2669 prev_class_count, class_count);
2670 fprintf (dump_file, "Average class size before: %.2f, after: %.2f\n",
2671 prev_class_count ? 1.0f * item_count / prev_class_count : 0.0f,
2672 class_count ? 1.0f * item_count / class_count : 0.0f);
2673 fprintf (dump_file, "Average non-singular class size: %.2f, count: %u\n",
2674 non_singular_classes_count ? 1.0f * non_singular_classes_sum /
2675 non_singular_classes_count : 0.0f,
2676 non_singular_classes_count);
2677 fprintf (dump_file, "Equal symbols: %u\n", equal_items);
2678 fprintf (dump_file, "Fraction of visited symbols: %.2f%%\n\n",
2679 item_count ? 100.0f * equal_items / item_count : 0.0f);
2682 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2683 it != m_classes.end (); ++it)
2684 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
2686 congruence_class *c = (*it)->classes[i];
2688 if (c->members.length () == 1)
2691 gcc_assert (c->members.length ());
2693 sem_item *source = c->members[0];
2695 for (unsigned int j = 1; j < c->members.length (); j++)
2697 sem_item *alias = c->members[j];
2701 fprintf (dump_file, "Semantic equality hit:%s->%s\n",
2702 source->name (), alias->name ());
2703 fprintf (dump_file, "Assembler symbol names:%s->%s\n",
2704 source->asm_name (), alias->asm_name ());
2707 if (lookup_attribute ("no_icf", DECL_ATTRIBUTES (alias->decl)))
2711 "Merge operation is skipped due to no_icf "
2717 if (dump_file && (dump_flags & TDF_DETAILS))
2719 source->dump_to_file (dump_file);
2720 alias->dump_to_file (dump_file);
2723 source->merge (alias);
2728 /* Dump function prints all class members to a FILE with an INDENT. */
2731 congruence_class::dump (FILE *file, unsigned int indent) const
2733 FPRINTF_SPACES (file, indent, "class with id: %u, hash: %u, items: %u\n",
2734 id, members[0]->get_hash (), members.length ());
2736 FPUTS_SPACES (file, indent + 2, "");
2737 for (unsigned i = 0; i < members.length (); i++)
2738 fprintf (file, "%s(%p/%u) ", members[i]->asm_name (), (void *) members[i]->decl,
2739 members[i]->node->order);
2741 fprintf (file, "\n");
2744 /* Returns true if there's a member that is used from another group. */
2747 congruence_class::is_class_used (void)
2749 for (unsigned int i = 0; i < members.length (); i++)
2750 if (members[i]->usages.length ())
2756 /* Initialization and computation of symtab node hash, there data
2757 are propagated later on. */
2759 static sem_item_optimizer *optimizer = NULL;
2761 /* Generate pass summary for IPA ICF pass. */
2764 ipa_icf_generate_summary (void)
2767 optimizer = new sem_item_optimizer ();
2769 optimizer->register_hooks ();
2770 optimizer->parse_funcs_and_vars ();
2773 /* Write pass summary for IPA ICF pass. */
2776 ipa_icf_write_summary (void)
2778 gcc_assert (optimizer);
2780 optimizer->write_summary ();
2783 /* Read pass summary for IPA ICF pass. */
2786 ipa_icf_read_summary (void)
2789 optimizer = new sem_item_optimizer ();
2791 optimizer->read_summary ();
2792 optimizer->register_hooks ();
2795 /* Semantic equality exection function. */
2798 ipa_icf_driver (void)
2800 gcc_assert (optimizer);
2802 optimizer->execute ();
2810 const pass_data pass_data_ipa_icf =
2812 IPA_PASS, /* type */
2814 OPTGROUP_IPA, /* optinfo_flags */
2815 TV_IPA_ICF, /* tv_id */
2816 0, /* properties_required */
2817 0, /* properties_provided */
2818 0, /* properties_destroyed */
2819 0, /* todo_flags_start */
2820 0, /* todo_flags_finish */
2823 class pass_ipa_icf : public ipa_opt_pass_d
2826 pass_ipa_icf (gcc::context *ctxt)
2827 : ipa_opt_pass_d (pass_data_ipa_icf, ctxt,
2828 ipa_icf_generate_summary, /* generate_summary */
2829 ipa_icf_write_summary, /* write_summary */
2830 ipa_icf_read_summary, /* read_summary */
2832 write_optimization_summary */
2834 read_optimization_summary */
2835 NULL, /* stmt_fixup */
2836 0, /* function_transform_todo_flags_start */
2837 NULL, /* function_transform */
2838 NULL) /* variable_transform */
2841 /* opt_pass methods: */
2842 virtual bool gate (function *)
2844 return in_lto_p || flag_ipa_icf_variables || flag_ipa_icf_functions;
2847 virtual unsigned int execute (function *)
2849 return ipa_icf_driver();
2851 }; // class pass_ipa_icf
2853 } // ipa_icf namespace
2856 make_pass_ipa_icf (gcc::context *ctxt)
2858 return new ipa_icf::pass_ipa_icf (ctxt);