jit: API change to gcc_jit_context_new_global
[official-gcc.git] / gcc / ipa-icf.c
blob9e2dea5397d6c5031b971428e0280b97548cdab3
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
11 version.
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.
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
23 read-only variables.
25 The goal of this transformation is to discover functions and read-only
26 variables which do have exactly the same semantics.
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.
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.
54 #include "config.h"
55 #include "system.h"
56 #include "coretypes.h"
57 #include "hash-set.h"
58 #include "machmode.h"
59 #include "vec.h"
60 #include "double-int.h"
61 #include "input.h"
62 #include "alias.h"
63 #include "symtab.h"
64 #include "options.h"
65 #include "wide-int.h"
66 #include "inchash.h"
67 #include "tree.h"
68 #include "fold-const.h"
69 #include "predict.h"
70 #include "tm.h"
71 #include "hard-reg-set.h"
72 #include "input.h"
73 #include "function.h"
74 #include "dominance.h"
75 #include "cfg.h"
76 #include "basic-block.h"
77 #include "tree-ssa-alias.h"
78 #include "internal-fn.h"
79 #include "gimple-expr.h"
80 #include "is-a.h"
81 #include "gimple.h"
82 #include "expr.h"
83 #include "gimple-iterator.h"
84 #include "gimple-ssa.h"
85 #include "tree-cfg.h"
86 #include "tree-phinodes.h"
87 #include "stringpool.h"
88 #include "tree-ssanames.h"
89 #include "tree-dfa.h"
90 #include "tree-pass.h"
91 #include "gimple-pretty-print.h"
92 #include "hash-map.h"
93 #include "plugin-api.h"
94 #include "ipa-ref.h"
95 #include "cgraph.h"
96 #include "alloc-pool.h"
97 #include "symbol-summary.h"
98 #include "ipa-prop.h"
99 #include "ipa-inline.h"
100 #include "cfgloop.h"
101 #include "except.h"
102 #include "hash-table.h"
103 #include "coverage.h"
104 #include "attribs.h"
105 #include "print-tree.h"
106 #include "lto-streamer.h"
107 #include "data-streamer.h"
108 #include "ipa-utils.h"
109 #include <list>
110 #include "ipa-icf-gimple.h"
111 #include "ipa-icf.h"
112 #include "varasm.h"
114 using namespace ipa_icf_gimple;
116 namespace ipa_icf {
117 /* Constructor for key value pair, where _ITEM is key and _INDEX is a target. */
119 sem_usage_pair::sem_usage_pair (sem_item *_item, unsigned int _index):
120 item (_item), index (_index)
124 /* Semantic item constructor for a node of _TYPE, where STACK is used
125 for bitmap memory allocation. */
127 sem_item::sem_item (sem_item_type _type,
128 bitmap_obstack *stack): type(_type), hash(0)
130 setup (stack);
133 /* Semantic item constructor for a node of _TYPE, where STACK is used
134 for bitmap memory allocation. The item is based on symtab node _NODE
135 with computed _HASH. */
137 sem_item::sem_item (sem_item_type _type, symtab_node *_node,
138 hashval_t _hash, bitmap_obstack *stack): type(_type),
139 node (_node), hash (_hash)
141 decl = node->decl;
142 setup (stack);
145 /* Add reference to a semantic TARGET. */
147 void
148 sem_item::add_reference (sem_item *target)
150 refs.safe_push (target);
151 unsigned index = refs.length ();
152 target->usages.safe_push (new sem_usage_pair(this, index));
153 bitmap_set_bit (target->usage_index_bitmap, index);
154 refs_set.add (target->node);
157 /* Initialize internal data structures. Bitmap STACK is used for
158 bitmap memory allocation process. */
160 void
161 sem_item::setup (bitmap_obstack *stack)
163 gcc_checking_assert (node);
165 refs.create (0);
166 tree_refs.create (0);
167 usages.create (0);
168 usage_index_bitmap = BITMAP_ALLOC (stack);
171 sem_item::~sem_item ()
173 for (unsigned i = 0; i < usages.length (); i++)
174 delete usages[i];
176 refs.release ();
177 tree_refs.release ();
178 usages.release ();
180 BITMAP_FREE (usage_index_bitmap);
183 /* Dump function for debugging purpose. */
185 DEBUG_FUNCTION void
186 sem_item::dump (void)
188 if (dump_file)
190 fprintf (dump_file, "[%s] %s (%u) (tree:%p)\n", type == FUNC ? "func" : "var",
191 name(), node->order, (void *) node->decl);
192 fprintf (dump_file, " hash: %u\n", get_hash ());
193 fprintf (dump_file, " references: ");
195 for (unsigned i = 0; i < refs.length (); i++)
196 fprintf (dump_file, "%s%s ", refs[i]->name (),
197 i < refs.length() - 1 ? "," : "");
199 fprintf (dump_file, "\n");
203 /* Return true if target supports alias symbols. */
205 bool
206 sem_item::target_supports_symbol_aliases_p (void)
208 #if !defined (ASM_OUTPUT_DEF) || (!defined(ASM_OUTPUT_WEAK_ALIAS) && !defined (ASM_WEAKEN_DECL))
209 return false;
210 #else
211 return true;
212 #endif
215 /* Semantic function constructor that uses STACK as bitmap memory stack. */
217 sem_function::sem_function (bitmap_obstack *stack): sem_item (FUNC, stack),
218 m_checker (NULL), m_compared_func (NULL)
220 arg_types.create (0);
221 bb_sizes.create (0);
222 bb_sorted.create (0);
225 /* Constructor based on callgraph node _NODE with computed hash _HASH.
226 Bitmap STACK is used for memory allocation. */
227 sem_function::sem_function (cgraph_node *node, hashval_t hash,
228 bitmap_obstack *stack):
229 sem_item (FUNC, node, hash, stack),
230 m_checker (NULL), m_compared_func (NULL)
232 arg_types.create (0);
233 bb_sizes.create (0);
234 bb_sorted.create (0);
237 sem_function::~sem_function ()
239 for (unsigned i = 0; i < bb_sorted.length (); i++)
240 delete (bb_sorted[i]);
242 arg_types.release ();
243 bb_sizes.release ();
244 bb_sorted.release ();
247 /* Calculates hash value based on a BASIC_BLOCK. */
249 hashval_t
250 sem_function::get_bb_hash (const sem_bb *basic_block)
252 inchash::hash hstate;
254 hstate.add_int (basic_block->nondbg_stmt_count);
255 hstate.add_int (basic_block->edge_count);
257 return hstate.end ();
260 /* References independent hash function. */
262 hashval_t
263 sem_function::get_hash (void)
265 if(!hash)
267 inchash::hash hstate;
268 hstate.add_int (177454); /* Random number for function type. */
270 hstate.add_int (arg_count);
271 hstate.add_int (cfg_checksum);
272 hstate.add_int (gcode_hash);
274 for (unsigned i = 0; i < bb_sorted.length (); i++)
275 hstate.merge_hash (get_bb_hash (bb_sorted[i]));
277 for (unsigned i = 0; i < bb_sizes.length (); i++)
278 hstate.add_int (bb_sizes[i]);
280 hash = hstate.end ();
283 return hash;
286 /* For a given symbol table nodes N1 and N2, we check that FUNCTION_DECLs
287 point to a same function. Comparison can be skipped if IGNORED_NODES
288 contains these nodes. */
290 bool
291 sem_function::compare_cgraph_references (hash_map <symtab_node *, sem_item *>
292 &ignored_nodes,
293 symtab_node *n1, symtab_node *n2)
295 if (n1 == n2 || (ignored_nodes.get (n1) && ignored_nodes.get (n2)))
296 return true;
298 /* TODO: add more precise comparison for weakrefs, etc. */
300 return return_false_with_msg ("different references");
303 /* If cgraph edges E1 and E2 are indirect calls, verify that
304 ECF flags are the same. */
306 bool sem_function::compare_edge_flags (cgraph_edge *e1, cgraph_edge *e2)
308 if (e1->indirect_info && e2->indirect_info)
310 int e1_flags = e1->indirect_info->ecf_flags;
311 int e2_flags = e2->indirect_info->ecf_flags;
313 if (e1_flags != e2_flags)
314 return return_false_with_msg ("ICF flags are different");
316 else if (e1->indirect_info || e2->indirect_info)
317 return false;
319 return true;
322 /* Fast equality function based on knowledge known in WPA. */
324 bool
325 sem_function::equals_wpa (sem_item *item,
326 hash_map <symtab_node *, sem_item *> &ignored_nodes)
328 gcc_assert (item->type == FUNC);
330 m_compared_func = static_cast<sem_function *> (item);
332 if (arg_types.length () != m_compared_func->arg_types.length ())
333 return return_false_with_msg ("different number of arguments");
335 /* Checking types of arguments. */
336 for (unsigned i = 0; i < arg_types.length (); i++)
338 /* This guard is here for function pointer with attributes (pr59927.c). */
339 if (!arg_types[i] || !m_compared_func->arg_types[i])
340 return return_false_with_msg ("NULL argument type");
342 /* Polymorphic comparison is executed just for non-leaf functions. */
343 bool is_not_leaf = get_node ()->callees != NULL
344 || get_node ()->indirect_calls != NULL;
346 if (!func_checker::compatible_types_p (arg_types[i],
347 m_compared_func->arg_types[i],
348 is_not_leaf, i == 0))
349 return return_false_with_msg ("argument type is different");
352 /* Result type checking. */
353 if (!func_checker::compatible_types_p (result_type,
354 m_compared_func->result_type))
355 return return_false_with_msg ("result types are different");
357 if (node->num_references () != item->node->num_references ())
358 return return_false_with_msg ("different number of references");
360 ipa_ref *ref = NULL, *ref2 = NULL;
361 for (unsigned i = 0; node->iterate_reference (i, ref); i++)
363 item->node->iterate_reference (i, ref2);
365 if (!compare_cgraph_references (ignored_nodes, ref->referred, ref2->referred))
366 return false;
369 cgraph_edge *e1 = dyn_cast <cgraph_node *> (node)->callees;
370 cgraph_edge *e2 = dyn_cast <cgraph_node *> (item->node)->callees;
372 while (e1 && e2)
374 if (!compare_cgraph_references (ignored_nodes, e1->callee, e2->callee))
375 return false;
377 e1 = e1->next_callee;
378 e2 = e2->next_callee;
381 if (e1 || e2)
382 return return_false_with_msg ("different number of edges");
384 return true;
387 /* Returns true if the item equals to ITEM given as argument. */
389 bool
390 sem_function::equals (sem_item *item,
391 hash_map <symtab_node *, sem_item *> &ignored_nodes)
393 gcc_assert (item->type == FUNC);
394 bool eq = equals_private (item, ignored_nodes);
396 if (m_checker != NULL)
398 delete m_checker;
399 m_checker = NULL;
402 if (dump_file && (dump_flags & TDF_DETAILS))
403 fprintf (dump_file,
404 "Equals called for:%s:%s (%u:%u) (%s:%s) with result: %s\n\n",
405 name(), item->name (), node->order, item->node->order, asm_name (),
406 item->asm_name (), eq ? "true" : "false");
408 return eq;
411 /* Processes function equality comparison. */
413 bool
414 sem_function::equals_private (sem_item *item,
415 hash_map <symtab_node *, sem_item *> &ignored_nodes)
417 if (item->type != FUNC)
418 return false;
420 basic_block bb1, bb2;
421 edge e1, e2;
422 edge_iterator ei1, ei2;
423 bool result = true;
424 tree arg1, arg2;
426 m_compared_func = static_cast<sem_function *> (item);
428 gcc_assert (decl != item->decl);
430 if (bb_sorted.length () != m_compared_func->bb_sorted.length ()
431 || edge_count != m_compared_func->edge_count
432 || cfg_checksum != m_compared_func->cfg_checksum)
433 return return_false ();
435 if (!equals_wpa (item, ignored_nodes))
436 return false;
438 /* Checking function TARGET and OPTIMIZATION flags. */
439 cl_target_option *tar1 = target_opts_for_fn (decl);
440 cl_target_option *tar2 = target_opts_for_fn (m_compared_func->decl);
442 if (tar1 != NULL && tar2 != NULL)
444 if (!cl_target_option_eq (tar1, tar2))
446 if (dump_file && (dump_flags & TDF_DETAILS))
448 fprintf (dump_file, "Source target flags\n");
449 cl_target_option_print (dump_file, 2, tar1);
450 fprintf (dump_file, "Target target flags\n");
451 cl_target_option_print (dump_file, 2, tar2);
454 return return_false_with_msg ("Target flags are different");
457 else if (tar1 != NULL || tar2 != NULL)
458 return return_false_with_msg ("Target flags are different");
460 cl_optimization *opt1 = opts_for_fn (decl);
461 cl_optimization *opt2 = opts_for_fn (m_compared_func->decl);
463 if (opt1 != NULL && opt2 != NULL)
465 if (memcmp (opt1, opt2, sizeof(cl_optimization)))
467 if (dump_file && (dump_flags & TDF_DETAILS))
469 fprintf (dump_file, "Source optimization flags\n");
470 cl_optimization_print (dump_file, 2, opt1);
471 fprintf (dump_file, "Target optimization flags\n");
472 cl_optimization_print (dump_file, 2, opt2);
475 return return_false_with_msg ("optimization flags are different");
478 else if (opt1 != NULL || opt2 != NULL)
479 return return_false_with_msg ("optimization flags are different");
481 /* Checking function arguments. */
482 tree decl1 = DECL_ATTRIBUTES (decl);
483 tree decl2 = DECL_ATTRIBUTES (m_compared_func->decl);
485 m_checker = new func_checker (decl, m_compared_func->decl,
486 compare_polymorphic_p (),
487 false,
488 &refs_set,
489 &m_compared_func->refs_set);
490 while (decl1)
492 if (decl2 == NULL)
493 return return_false ();
495 if (get_attribute_name (decl1) != get_attribute_name (decl2))
496 return return_false ();
498 tree attr_value1 = TREE_VALUE (decl1);
499 tree attr_value2 = TREE_VALUE (decl2);
501 if (attr_value1 && attr_value2)
503 bool ret = m_checker->compare_operand (TREE_VALUE (attr_value1),
504 TREE_VALUE (attr_value2));
505 if (!ret)
506 return return_false_with_msg ("attribute values are different");
508 else if (!attr_value1 && !attr_value2)
510 else
511 return return_false ();
513 decl1 = TREE_CHAIN (decl1);
514 decl2 = TREE_CHAIN (decl2);
517 if (decl1 != decl2)
518 return return_false();
521 for (arg1 = DECL_ARGUMENTS (decl),
522 arg2 = DECL_ARGUMENTS (m_compared_func->decl);
523 arg1; arg1 = DECL_CHAIN (arg1), arg2 = DECL_CHAIN (arg2))
524 if (!m_checker->compare_decl (arg1, arg2))
525 return return_false ();
527 /* Fill-up label dictionary. */
528 for (unsigned i = 0; i < bb_sorted.length (); ++i)
530 m_checker->parse_labels (bb_sorted[i]);
531 m_checker->parse_labels (m_compared_func->bb_sorted[i]);
534 /* Checking all basic blocks. */
535 for (unsigned i = 0; i < bb_sorted.length (); ++i)
536 if(!m_checker->compare_bb (bb_sorted[i], m_compared_func->bb_sorted[i]))
537 return return_false();
539 dump_message ("All BBs are equal\n");
541 auto_vec <int> bb_dict;
543 /* Basic block edges check. */
544 for (unsigned i = 0; i < bb_sorted.length (); ++i)
546 bb1 = bb_sorted[i]->bb;
547 bb2 = m_compared_func->bb_sorted[i]->bb;
549 ei2 = ei_start (bb2->preds);
551 for (ei1 = ei_start (bb1->preds); ei_cond (ei1, &e1); ei_next (&ei1))
553 ei_cond (ei2, &e2);
555 if (e1->flags != e2->flags)
556 return return_false_with_msg ("flags comparison returns false");
558 if (!bb_dict_test (bb_dict, e1->src->index, e2->src->index))
559 return return_false_with_msg ("edge comparison returns false");
561 if (!bb_dict_test (bb_dict, e1->dest->index, e2->dest->index))
562 return return_false_with_msg ("BB comparison returns false");
564 if (!m_checker->compare_edge (e1, e2))
565 return return_false_with_msg ("edge comparison returns false");
567 ei_next (&ei2);
571 /* Basic block PHI nodes comparison. */
572 for (unsigned i = 0; i < bb_sorted.length (); i++)
573 if (!compare_phi_node (bb_sorted[i]->bb, m_compared_func->bb_sorted[i]->bb))
574 return return_false_with_msg ("PHI node comparison returns false");
576 return result;
579 /* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can
580 be applied. */
581 bool
582 sem_function::merge (sem_item *alias_item)
584 gcc_assert (alias_item->type == FUNC);
586 sem_function *alias_func = static_cast<sem_function *> (alias_item);
588 cgraph_node *original = get_node ();
589 cgraph_node *local_original = original;
590 cgraph_node *alias = alias_func->get_node ();
591 bool original_address_matters;
592 bool alias_address_matters;
594 bool create_thunk = false;
595 bool create_alias = false;
596 bool redirect_callers = false;
597 bool original_discardable = false;
599 /* Do not attempt to mix functions from different user sections;
600 we do not know what user intends with those. */
601 if (((DECL_SECTION_NAME (original->decl) && !original->implicit_section)
602 || (DECL_SECTION_NAME (alias->decl) && !alias->implicit_section))
603 && DECL_SECTION_NAME (original->decl) != DECL_SECTION_NAME (alias->decl))
605 if (dump_file)
606 fprintf (dump_file,
607 "Not unifying; original and alias are in different sections.\n\n");
608 return false;
611 /* See if original is in a section that can be discarded if the main
612 symbol is not used. */
613 if (DECL_EXTERNAL (original->decl))
614 original_discardable = true;
615 if (original->resolution == LDPR_PREEMPTED_REG
616 || original->resolution == LDPR_PREEMPTED_IR)
617 original_discardable = true;
618 if (original->can_be_discarded_p ())
619 original_discardable = true;
621 /* See if original and/or alias address can be compared for equality. */
622 original_address_matters
623 = (!DECL_VIRTUAL_P (original->decl)
624 && (original->externally_visible
625 || original->address_taken_from_non_vtable_p ()));
626 alias_address_matters
627 = (!DECL_VIRTUAL_P (alias->decl)
628 && (alias->externally_visible
629 || alias->address_taken_from_non_vtable_p ()));
631 /* If alias and original can be compared for address equality, we need
632 to create a thunk. Also we can not create extra aliases into discardable
633 section (or we risk link failures when section is discarded). */
634 if ((original_address_matters
635 && alias_address_matters)
636 || original_discardable)
638 create_thunk = !stdarg_p (TREE_TYPE (alias->decl));
639 create_alias = false;
640 /* When both alias and original are not overwritable, we can save
641 the extra thunk wrapper for direct calls. */
642 redirect_callers
643 = (!original_discardable
644 && alias->get_availability () > AVAIL_INTERPOSABLE
645 && original->get_availability () > AVAIL_INTERPOSABLE
646 && !alias->instrumented_version);
648 else
650 create_alias = true;
651 create_thunk = false;
652 redirect_callers = false;
655 if (create_alias && (DECL_COMDAT_GROUP (alias->decl)
656 || !sem_item::target_supports_symbol_aliases_p ()))
658 create_alias = false;
659 create_thunk = true;
662 /* We want thunk to always jump to the local function body
663 unless the body is comdat and may be optimized out. */
664 if ((create_thunk || redirect_callers)
665 && (!original_discardable
666 || (DECL_COMDAT_GROUP (original->decl)
667 && (DECL_COMDAT_GROUP (original->decl)
668 == DECL_COMDAT_GROUP (alias->decl)))))
669 local_original
670 = dyn_cast <cgraph_node *> (original->noninterposable_alias ());
672 if (!local_original)
674 if (dump_file)
675 fprintf (dump_file, "Noninterposable alias cannot be created.\n\n");
677 return false;
680 if (!decl_binds_to_current_def_p (alias->decl))
682 if (dump_file)
683 fprintf (dump_file, "Declaration does not bind to currect definition.\n\n");
684 return false;
687 if (redirect_callers)
689 /* If alias is non-overwritable then
690 all direct calls are safe to be redirected to the original. */
691 bool redirected = false;
692 while (alias->callers)
694 cgraph_edge *e = alias->callers;
695 e->redirect_callee (local_original);
696 push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
698 if (e->call_stmt)
699 e->redirect_call_stmt_to_callee ();
701 pop_cfun ();
702 redirected = true;
705 alias->icf_merged = true;
707 /* The alias function is removed if symbol address
708 does not matter. */
709 if (!alias_address_matters)
710 alias->remove ();
712 if (dump_file && redirected)
713 fprintf (dump_file, "Callgraph local calls have been redirected.\n\n");
715 /* If the condtion above is not met, we are lucky and can turn the
716 function into real alias. */
717 else if (create_alias)
719 alias->icf_merged = true;
721 /* Remove the function's body. */
722 ipa_merge_profiles (original, alias);
723 alias->release_body (true);
724 alias->reset ();
726 /* Create the alias. */
727 cgraph_node::create_alias (alias_func->decl, decl);
728 alias->resolve_alias (original);
730 /* Workaround for PR63566 that forces equal calling convention
731 to be used. */
732 alias->local.local = false;
733 original->local.local = false;
735 if (dump_file)
736 fprintf (dump_file, "Callgraph alias has been created.\n\n");
738 else if (create_thunk)
740 if (DECL_COMDAT_GROUP (alias->decl))
742 if (dump_file)
743 fprintf (dump_file, "Callgraph thunk cannot be created because of COMDAT\n");
745 return 0;
748 if (DECL_STATIC_CHAIN (alias->decl))
750 if (dump_file)
751 fprintf (dump_file, "Thunk creation is risky for static-chain functions.\n\n");
753 return 0;
756 alias->icf_merged = true;
757 ipa_merge_profiles (local_original, alias);
758 alias->create_wrapper (local_original);
760 if (dump_file)
761 fprintf (dump_file, "Callgraph thunk has been created.\n\n");
763 else if (dump_file)
764 fprintf (dump_file, "Callgraph merge operation cannot be performed.\n\n");
766 return true;
769 /* Semantic item initialization function. */
771 void
772 sem_function::init (void)
774 if (in_lto_p)
775 get_node ()->get_untransformed_body ();
777 tree fndecl = node->decl;
778 function *func = DECL_STRUCT_FUNCTION (fndecl);
780 gcc_assert (func);
781 gcc_assert (SSANAMES (func));
783 ssa_names_size = SSANAMES (func)->length ();
784 node = node;
786 decl = fndecl;
787 region_tree = func->eh->region_tree;
789 /* iterating all function arguments. */
790 arg_count = count_formal_params (fndecl);
792 edge_count = n_edges_for_fn (func);
793 cfg_checksum = coverage_compute_cfg_checksum (func);
795 inchash::hash hstate;
797 basic_block bb;
798 FOR_EACH_BB_FN (bb, func)
800 unsigned nondbg_stmt_count = 0;
802 edge e;
803 for (edge_iterator ei = ei_start (bb->preds); ei_cond (ei, &e); ei_next (&ei))
804 cfg_checksum = iterative_hash_host_wide_int (e->flags,
805 cfg_checksum);
807 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
808 gsi_next (&gsi))
810 gimple stmt = gsi_stmt (gsi);
812 if (gimple_code (stmt) != GIMPLE_DEBUG)
814 hash_stmt (&hstate, stmt);
815 nondbg_stmt_count++;
819 gcode_hash = hstate.end ();
820 bb_sizes.safe_push (nondbg_stmt_count);
822 /* Inserting basic block to hash table. */
823 sem_bb *semantic_bb = new sem_bb (bb, nondbg_stmt_count,
824 EDGE_COUNT (bb->preds) + EDGE_COUNT (bb->succs));
826 bb_sorted.safe_push (semantic_bb);
829 parse_tree_args ();
832 /* Improve accumulated hash for HSTATE based on a gimple statement STMT. */
834 void
835 sem_function::hash_stmt (inchash::hash *hstate, gimple stmt)
837 enum gimple_code code = gimple_code (stmt);
839 hstate->add_int (code);
841 if (code == GIMPLE_CALL)
843 /* Checking of argument. */
844 for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i)
846 tree argument = gimple_call_arg (stmt, i);
848 switch (TREE_CODE (argument))
850 case INTEGER_CST:
851 if (tree_fits_shwi_p (argument))
852 hstate->add_wide_int (tree_to_shwi (argument));
853 else if (tree_fits_uhwi_p (argument))
854 hstate->add_wide_int (tree_to_uhwi (argument));
855 break;
856 case REAL_CST:
857 REAL_VALUE_TYPE c;
858 HOST_WIDE_INT n;
860 c = TREE_REAL_CST (argument);
861 n = real_to_integer (&c);
863 hstate->add_wide_int (n);
864 break;
865 case ADDR_EXPR:
867 tree addr_operand = TREE_OPERAND (argument, 0);
869 if (TREE_CODE (addr_operand) == STRING_CST)
870 hstate->add (TREE_STRING_POINTER (addr_operand),
871 TREE_STRING_LENGTH (addr_operand));
872 break;
874 default:
875 break;
882 /* Return true if polymorphic comparison must be processed. */
884 bool
885 sem_function::compare_polymorphic_p (void)
887 return get_node ()->callees != NULL
888 || get_node ()->indirect_calls != NULL
889 || m_compared_func->get_node ()->callees != NULL
890 || m_compared_func->get_node ()->indirect_calls != NULL;
893 /* For a given call graph NODE, the function constructs new
894 semantic function item. */
896 sem_function *
897 sem_function::parse (cgraph_node *node, bitmap_obstack *stack)
899 tree fndecl = node->decl;
900 function *func = DECL_STRUCT_FUNCTION (fndecl);
902 /* TODO: add support for thunks and aliases. */
904 if (!func || !node->has_gimple_body_p ())
905 return NULL;
907 if (lookup_attribute_by_prefix ("omp ", DECL_ATTRIBUTES (node->decl)) != NULL)
908 return NULL;
910 sem_function *f = new sem_function (node, 0, stack);
912 f->init ();
914 return f;
917 /* Parses function arguments and result type. */
919 void
920 sem_function::parse_tree_args (void)
922 tree result;
924 if (arg_types.exists ())
925 arg_types.release ();
927 arg_types.create (4);
928 tree fnargs = DECL_ARGUMENTS (decl);
930 for (tree parm = fnargs; parm; parm = DECL_CHAIN (parm))
931 arg_types.safe_push (DECL_ARG_TYPE (parm));
933 /* Function result type. */
934 result = DECL_RESULT (decl);
935 result_type = result ? TREE_TYPE (result) : NULL;
937 /* During WPA, we can get arguments by following method. */
938 if (!fnargs)
940 tree type = TYPE_ARG_TYPES (TREE_TYPE (decl));
941 for (tree parm = type; parm; parm = TREE_CHAIN (parm))
942 arg_types.safe_push (TYPE_CANONICAL (TREE_VALUE (parm)));
944 result_type = TREE_TYPE (TREE_TYPE (decl));
948 /* For given basic blocks BB1 and BB2 (from functions FUNC1 and FUNC),
949 return true if phi nodes are semantically equivalent in these blocks . */
951 bool
952 sem_function::compare_phi_node (basic_block bb1, basic_block bb2)
954 gphi_iterator si1, si2;
955 gphi *phi1, *phi2;
956 unsigned size1, size2, i;
957 tree t1, t2;
958 edge e1, e2;
960 gcc_assert (bb1 != NULL);
961 gcc_assert (bb2 != NULL);
963 si2 = gsi_start_phis (bb2);
964 for (si1 = gsi_start_phis (bb1); !gsi_end_p (si1);
965 gsi_next (&si1))
967 gsi_next_nonvirtual_phi (&si1);
968 gsi_next_nonvirtual_phi (&si2);
970 if (gsi_end_p (si1) && gsi_end_p (si2))
971 break;
973 if (gsi_end_p (si1) || gsi_end_p (si2))
974 return return_false();
976 phi1 = si1.phi ();
977 phi2 = si2.phi ();
979 tree phi_result1 = gimple_phi_result (phi1);
980 tree phi_result2 = gimple_phi_result (phi2);
982 if (!m_checker->compare_operand (phi_result1, phi_result2))
983 return return_false_with_msg ("PHI results are different");
985 size1 = gimple_phi_num_args (phi1);
986 size2 = gimple_phi_num_args (phi2);
988 if (size1 != size2)
989 return return_false ();
991 for (i = 0; i < size1; ++i)
993 t1 = gimple_phi_arg (phi1, i)->def;
994 t2 = gimple_phi_arg (phi2, i)->def;
996 if (!m_checker->compare_operand (t1, t2))
997 return return_false ();
999 e1 = gimple_phi_arg_edge (phi1, i);
1000 e2 = gimple_phi_arg_edge (phi2, i);
1002 if (!m_checker->compare_edge (e1, e2))
1003 return return_false ();
1006 gsi_next (&si2);
1009 return true;
1012 /* Returns true if tree T can be compared as a handled component. */
1014 bool
1015 sem_function::icf_handled_component_p (tree t)
1017 tree_code tc = TREE_CODE (t);
1019 return ((handled_component_p (t))
1020 || tc == ADDR_EXPR || tc == MEM_REF || tc == REALPART_EXPR
1021 || tc == IMAGPART_EXPR || tc == OBJ_TYPE_REF);
1024 /* Basic blocks dictionary BB_DICT returns true if SOURCE index BB
1025 corresponds to TARGET. */
1027 bool
1028 sem_function::bb_dict_test (auto_vec<int> bb_dict, int source, int target)
1030 source++;
1031 target++;
1033 if (bb_dict.length () <= (unsigned)source)
1034 bb_dict.safe_grow_cleared (source + 1);
1036 if (bb_dict[source] == 0)
1038 bb_dict[source] = target;
1039 return true;
1041 else
1042 return bb_dict[source] == target;
1045 /* Iterates all tree types in T1 and T2 and returns true if all types
1046 are compatible. If COMPARE_POLYMORPHIC is set to true,
1047 more strict comparison is executed. */
1049 bool
1050 sem_function::compare_type_list (tree t1, tree t2, bool compare_polymorphic)
1052 tree tv1, tv2;
1053 tree_code tc1, tc2;
1055 if (!t1 && !t2)
1056 return true;
1058 while (t1 != NULL && t2 != NULL)
1060 tv1 = TREE_VALUE (t1);
1061 tv2 = TREE_VALUE (t2);
1063 tc1 = TREE_CODE (tv1);
1064 tc2 = TREE_CODE (tv2);
1066 if (tc1 == NOP_EXPR && tc2 == NOP_EXPR)
1068 else if (tc1 == NOP_EXPR || tc2 == NOP_EXPR)
1069 return false;
1070 else if (!func_checker::compatible_types_p (tv1, tv2, compare_polymorphic))
1071 return false;
1073 t1 = TREE_CHAIN (t1);
1074 t2 = TREE_CHAIN (t2);
1077 return !(t1 || t2);
1081 /* Semantic variable constructor that uses STACK as bitmap memory stack. */
1083 sem_variable::sem_variable (bitmap_obstack *stack): sem_item (VAR, stack)
1087 /* Constructor based on varpool node _NODE with computed hash _HASH.
1088 Bitmap STACK is used for memory allocation. */
1090 sem_variable::sem_variable (varpool_node *node, hashval_t _hash,
1091 bitmap_obstack *stack): sem_item(VAR,
1092 node, _hash, stack)
1094 gcc_checking_assert (node);
1095 gcc_checking_assert (get_node ());
1098 /* Returns true if the item equals to ITEM given as argument. */
1100 bool
1101 sem_variable::equals (sem_item *item,
1102 hash_map <symtab_node *, sem_item *> & ARG_UNUSED (ignored_nodes))
1104 gcc_assert (item->type == VAR);
1106 sem_variable *v = static_cast<sem_variable *>(item);
1108 if (!ctor || !v->ctor)
1109 return return_false_with_msg ("ctor is missing for semantic variable");
1111 return sem_variable::equals (ctor, v->ctor);
1114 /* Compares trees T1 and T2 for semantic equality. */
1116 bool
1117 sem_variable::equals (tree t1, tree t2)
1119 tree_code tc1 = TREE_CODE (t1);
1120 tree_code tc2 = TREE_CODE (t2);
1122 if (tc1 != tc2)
1123 return false;
1125 switch (tc1)
1127 case CONSTRUCTOR:
1129 unsigned len1 = vec_safe_length (CONSTRUCTOR_ELTS (t1));
1130 unsigned len2 = vec_safe_length (CONSTRUCTOR_ELTS (t2));
1132 if (len1 != len2)
1133 return false;
1135 for (unsigned i = 0; i < len1; i++)
1136 if (!sem_variable::equals (CONSTRUCTOR_ELT (t1, i)->value,
1137 CONSTRUCTOR_ELT (t2, i)->value)
1138 || CONSTRUCTOR_ELT (t1, i)->index != CONSTRUCTOR_ELT (t2, i)->index)
1139 return false;
1141 return true;
1143 case MEM_REF:
1145 tree x1 = TREE_OPERAND (t1, 0);
1146 tree x2 = TREE_OPERAND (t2, 0);
1147 tree y1 = TREE_OPERAND (t1, 1);
1148 tree y2 = TREE_OPERAND (t2, 1);
1150 if (!func_checker::compatible_types_p (TREE_TYPE (x1), TREE_TYPE (x2),
1151 true))
1152 return return_false ();
1154 /* Type of the offset on MEM_REF does not matter. */
1155 return sem_variable::equals (x1, x2)
1156 && wi::to_offset (y1) == wi::to_offset (y2);
1158 case NOP_EXPR:
1159 case ADDR_EXPR:
1161 tree op1 = TREE_OPERAND (t1, 0);
1162 tree op2 = TREE_OPERAND (t2, 0);
1163 return sem_variable::equals (op1, op2);
1165 case FUNCTION_DECL:
1166 case VAR_DECL:
1167 case FIELD_DECL:
1168 case LABEL_DECL:
1169 return t1 == t2;
1170 case INTEGER_CST:
1171 return func_checker::compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2),
1172 true)
1173 && wi::to_offset (t1) == wi::to_offset (t2);
1174 case STRING_CST:
1175 case REAL_CST:
1176 case COMPLEX_CST:
1177 return operand_equal_p (t1, t2, OEP_ONLY_CONST);
1178 case COMPONENT_REF:
1179 case ARRAY_REF:
1180 case POINTER_PLUS_EXPR:
1182 tree x1 = TREE_OPERAND (t1, 0);
1183 tree x2 = TREE_OPERAND (t2, 0);
1184 tree y1 = TREE_OPERAND (t1, 1);
1185 tree y2 = TREE_OPERAND (t2, 1);
1187 return sem_variable::equals (x1, x2) && sem_variable::equals (y1, y2);
1189 case ERROR_MARK:
1190 return return_false_with_msg ("ERROR_MARK");
1191 default:
1192 return return_false_with_msg ("Unknown TREE code reached");
1196 /* Parser function that visits a varpool NODE. */
1198 sem_variable *
1199 sem_variable::parse (varpool_node *node, bitmap_obstack *stack)
1201 tree decl = node->decl;
1203 bool readonly = TYPE_P (decl) ? TYPE_READONLY (decl) : TREE_READONLY (decl);
1204 if (!readonly)
1205 return NULL;
1207 bool can_handle = DECL_VIRTUAL_P (decl)
1208 || flag_merge_constants >= 2
1209 || (!TREE_ADDRESSABLE (decl) && !node->externally_visible);
1211 if (!can_handle || DECL_EXTERNAL (decl))
1212 return NULL;
1214 tree ctor = ctor_for_folding (decl);
1215 if (!ctor)
1216 return NULL;
1218 sem_variable *v = new sem_variable (node, 0, stack);
1220 v->init ();
1222 return v;
1225 /* References independent hash function. */
1227 hashval_t
1228 sem_variable::get_hash (void)
1230 if (hash)
1231 return hash;
1233 inchash::hash hstate;
1235 hstate.add_int (456346417);
1236 hstate.add_int (TREE_CODE (ctor));
1238 if (TREE_CODE (ctor) == CONSTRUCTOR)
1240 unsigned length = vec_safe_length (CONSTRUCTOR_ELTS (ctor));
1241 hstate.add_int (length);
1244 hash = hstate.end ();
1246 return hash;
1249 /* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can
1250 be applied. */
1252 bool
1253 sem_variable::merge (sem_item *alias_item)
1255 gcc_assert (alias_item->type == VAR);
1257 if (!sem_item::target_supports_symbol_aliases_p ())
1259 if (dump_file)
1260 fprintf (dump_file, "Symbol aliases are not supported by target\n\n");
1261 return false;
1264 sem_variable *alias_var = static_cast<sem_variable *> (alias_item);
1266 varpool_node *original = get_node ();
1267 varpool_node *alias = alias_var->get_node ();
1268 bool original_discardable = false;
1270 /* See if original is in a section that can be discarded if the main
1271 symbol is not used. */
1272 if (DECL_EXTERNAL (original->decl))
1273 original_discardable = true;
1274 if (original->resolution == LDPR_PREEMPTED_REG
1275 || original->resolution == LDPR_PREEMPTED_IR)
1276 original_discardable = true;
1277 if (original->can_be_discarded_p ())
1278 original_discardable = true;
1280 gcc_assert (!TREE_ASM_WRITTEN (alias->decl));
1282 if (original_discardable || DECL_EXTERNAL (alias_var->decl) ||
1283 !compare_sections (alias_var))
1285 if (dump_file)
1286 fprintf (dump_file, "Varpool alias cannot be created\n\n");
1288 return false;
1290 else
1292 // alias cycle creation check
1293 varpool_node *n = original;
1295 while (n->alias)
1297 n = n->get_alias_target ();
1298 if (n == alias)
1300 if (dump_file)
1301 fprintf (dump_file, "Varpool alias cannot be created (alias cycle).\n\n");
1303 return false;
1307 alias->analyzed = false;
1309 DECL_INITIAL (alias->decl) = NULL;
1310 alias->need_bounds_init = false;
1311 alias->remove_all_references ();
1313 varpool_node::create_alias (alias_var->decl, decl);
1314 alias->resolve_alias (original);
1316 if (dump_file)
1317 fprintf (dump_file, "Varpool alias has been created.\n\n");
1319 return true;
1323 bool
1324 sem_variable::compare_sections (sem_variable *alias)
1326 const char *source = node->get_section ();
1327 const char *target = alias->node->get_section();
1329 if (source == NULL && target == NULL)
1330 return true;
1331 else if(!source || !target)
1332 return false;
1333 else
1334 return strcmp (source, target) == 0;
1337 /* Dump symbol to FILE. */
1339 void
1340 sem_variable::dump_to_file (FILE *file)
1342 gcc_assert (file);
1344 print_node (file, "", decl, 0);
1345 fprintf (file, "\n\n");
1348 /* Iterates though a constructor and identifies tree references
1349 we are interested in semantic function equality. */
1351 void
1352 sem_variable::parse_tree_refs (tree t)
1354 switch (TREE_CODE (t))
1356 case CONSTRUCTOR:
1358 unsigned length = vec_safe_length (CONSTRUCTOR_ELTS (t));
1360 for (unsigned i = 0; i < length; i++)
1361 parse_tree_refs(CONSTRUCTOR_ELT (t, i)->value);
1363 break;
1365 case NOP_EXPR:
1366 case ADDR_EXPR:
1368 tree op = TREE_OPERAND (t, 0);
1369 parse_tree_refs (op);
1370 break;
1372 case FUNCTION_DECL:
1374 tree_refs.safe_push (t);
1375 break;
1377 default:
1378 break;
1382 unsigned int sem_item_optimizer::class_id = 0;
1384 sem_item_optimizer::sem_item_optimizer (): worklist (0), m_classes (0),
1385 m_classes_count (0), m_cgraph_node_hooks (NULL), m_varpool_node_hooks (NULL)
1387 m_items.create (0);
1388 bitmap_obstack_initialize (&m_bmstack);
1391 sem_item_optimizer::~sem_item_optimizer ()
1393 for (unsigned int i = 0; i < m_items.length (); i++)
1394 delete m_items[i];
1396 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
1397 it != m_classes.end (); ++it)
1399 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
1400 delete (*it)->classes[i];
1402 (*it)->classes.release ();
1403 free (*it);
1406 m_items.release ();
1408 bitmap_obstack_release (&m_bmstack);
1411 /* Write IPA ICF summary for symbols. */
1413 void
1414 sem_item_optimizer::write_summary (void)
1416 unsigned int count = 0;
1418 output_block *ob = create_output_block (LTO_section_ipa_icf);
1419 lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
1420 ob->symbol = NULL;
1422 /* Calculate number of symbols to be serialized. */
1423 for (lto_symtab_encoder_iterator lsei = lsei_start_in_partition (encoder);
1424 !lsei_end_p (lsei);
1425 lsei_next_in_partition (&lsei))
1427 symtab_node *node = lsei_node (lsei);
1429 if (m_symtab_node_map.get (node))
1430 count++;
1433 streamer_write_uhwi (ob, count);
1435 /* Process all of the symbols. */
1436 for (lto_symtab_encoder_iterator lsei = lsei_start_in_partition (encoder);
1437 !lsei_end_p (lsei);
1438 lsei_next_in_partition (&lsei))
1440 symtab_node *node = lsei_node (lsei);
1442 sem_item **item = m_symtab_node_map.get (node);
1444 if (item && *item)
1446 int node_ref = lto_symtab_encoder_encode (encoder, node);
1447 streamer_write_uhwi_stream (ob->main_stream, node_ref);
1449 streamer_write_uhwi (ob, (*item)->get_hash ());
1453 streamer_write_char_stream (ob->main_stream, 0);
1454 produce_asm (ob, NULL);
1455 destroy_output_block (ob);
1458 /* Reads a section from LTO stream file FILE_DATA. Input block for DATA
1459 contains LEN bytes. */
1461 void
1462 sem_item_optimizer::read_section (lto_file_decl_data *file_data,
1463 const char *data, size_t len)
1465 const lto_function_header *header =
1466 (const lto_function_header *) data;
1467 const int cfg_offset = sizeof (lto_function_header);
1468 const int main_offset = cfg_offset + header->cfg_size;
1469 const int string_offset = main_offset + header->main_size;
1470 data_in *data_in;
1471 unsigned int i;
1472 unsigned int count;
1474 lto_input_block ib_main ((const char *) data + main_offset, 0,
1475 header->main_size);
1477 data_in =
1478 lto_data_in_create (file_data, (const char *) data + string_offset,
1479 header->string_size, vNULL);
1481 count = streamer_read_uhwi (&ib_main);
1483 for (i = 0; i < count; i++)
1485 unsigned int index;
1486 symtab_node *node;
1487 lto_symtab_encoder_t encoder;
1489 index = streamer_read_uhwi (&ib_main);
1490 encoder = file_data->symtab_node_encoder;
1491 node = lto_symtab_encoder_deref (encoder, index);
1493 hashval_t hash = streamer_read_uhwi (&ib_main);
1495 gcc_assert (node->definition);
1497 if (dump_file)
1498 fprintf (dump_file, "Symbol added:%s (tree: %p, uid:%u)\n", node->asm_name (),
1499 (void *) node->decl, node->order);
1501 if (is_a<cgraph_node *> (node))
1503 cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
1505 m_items.safe_push (new sem_function (cnode, hash, &m_bmstack));
1507 else
1509 varpool_node *vnode = dyn_cast <varpool_node *> (node);
1511 m_items.safe_push (new sem_variable (vnode, hash, &m_bmstack));
1515 lto_free_section_data (file_data, LTO_section_ipa_icf, NULL, data,
1516 len);
1517 lto_data_in_delete (data_in);
1520 /* Read IPA IPA ICF summary for symbols. */
1522 void
1523 sem_item_optimizer::read_summary (void)
1525 lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
1526 lto_file_decl_data *file_data;
1527 unsigned int j = 0;
1529 while ((file_data = file_data_vec[j++]))
1531 size_t len;
1532 const char *data = lto_get_section_data (file_data,
1533 LTO_section_ipa_icf, NULL, &len);
1535 if (data)
1536 read_section (file_data, data, len);
1540 /* Register callgraph and varpool hooks. */
1542 void
1543 sem_item_optimizer::register_hooks (void)
1545 m_cgraph_node_hooks = symtab->add_cgraph_removal_hook
1546 (&sem_item_optimizer::cgraph_removal_hook, this);
1548 m_varpool_node_hooks = symtab->add_varpool_removal_hook
1549 (&sem_item_optimizer::varpool_removal_hook, this);
1552 /* Unregister callgraph and varpool hooks. */
1554 void
1555 sem_item_optimizer::unregister_hooks (void)
1557 if (m_cgraph_node_hooks)
1558 symtab->remove_cgraph_removal_hook (m_cgraph_node_hooks);
1560 if (m_varpool_node_hooks)
1561 symtab->remove_varpool_removal_hook (m_varpool_node_hooks);
1564 /* Adds a CLS to hashtable associated by hash value. */
1566 void
1567 sem_item_optimizer::add_class (congruence_class *cls)
1569 gcc_assert (cls->members.length ());
1571 congruence_class_group *group = get_group_by_hash (
1572 cls->members[0]->get_hash (),
1573 cls->members[0]->type);
1574 group->classes.safe_push (cls);
1577 /* Gets a congruence class group based on given HASH value and TYPE. */
1579 congruence_class_group *
1580 sem_item_optimizer::get_group_by_hash (hashval_t hash, sem_item_type type)
1582 congruence_class_group *item = XNEW (congruence_class_group);
1583 item->hash = hash;
1584 item->type = type;
1586 congruence_class_group **slot = m_classes.find_slot (item, INSERT);
1588 if (*slot)
1589 free (item);
1590 else
1592 item->classes.create (1);
1593 *slot = item;
1596 return *slot;
1599 /* Callgraph removal hook called for a NODE with a custom DATA. */
1601 void
1602 sem_item_optimizer::cgraph_removal_hook (cgraph_node *node, void *data)
1604 sem_item_optimizer *optimizer = (sem_item_optimizer *) data;
1605 optimizer->remove_symtab_node (node);
1608 /* Varpool removal hook called for a NODE with a custom DATA. */
1610 void
1611 sem_item_optimizer::varpool_removal_hook (varpool_node *node, void *data)
1613 sem_item_optimizer *optimizer = (sem_item_optimizer *) data;
1614 optimizer->remove_symtab_node (node);
1617 /* Remove symtab NODE triggered by symtab removal hooks. */
1619 void
1620 sem_item_optimizer::remove_symtab_node (symtab_node *node)
1622 gcc_assert (!m_classes.elements());
1624 m_removed_items_set.add (node);
1627 void
1628 sem_item_optimizer::remove_item (sem_item *item)
1630 if (m_symtab_node_map.get (item->node))
1631 m_symtab_node_map.remove (item->node);
1632 delete item;
1635 /* Removes all callgraph and varpool nodes that are marked by symtab
1636 as deleted. */
1638 void
1639 sem_item_optimizer::filter_removed_items (void)
1641 auto_vec <sem_item *> filtered;
1643 for (unsigned int i = 0; i < m_items.length(); i++)
1645 sem_item *item = m_items[i];
1647 if (!flag_ipa_icf_functions && item->type == FUNC)
1649 remove_item (item);
1650 continue;
1653 if (!flag_ipa_icf_variables && item->type == VAR)
1655 remove_item (item);
1656 continue;
1659 bool no_body_function = false;
1661 if (item->type == FUNC)
1663 cgraph_node *cnode = static_cast <sem_function *>(item)->get_node ();
1665 no_body_function = in_lto_p && (cnode->alias || cnode->body_removed);
1668 if(!m_removed_items_set.contains (m_items[i]->node)
1669 && !no_body_function)
1671 if (item->type == VAR || (!DECL_CXX_CONSTRUCTOR_P (item->decl)
1672 && !DECL_CXX_DESTRUCTOR_P (item->decl)))
1674 filtered.safe_push (m_items[i]);
1675 continue;
1679 remove_item (item);
1682 /* Clean-up of released semantic items. */
1684 m_items.release ();
1685 for (unsigned int i = 0; i < filtered.length(); i++)
1686 m_items.safe_push (filtered[i]);
1689 /* Optimizer entry point. */
1691 void
1692 sem_item_optimizer::execute (void)
1694 filter_removed_items ();
1695 build_hash_based_classes ();
1697 if (dump_file)
1698 fprintf (dump_file, "Dump after hash based groups\n");
1699 dump_cong_classes ();
1701 for (unsigned int i = 0; i < m_items.length(); i++)
1702 m_items[i]->init_wpa ();
1704 build_graph ();
1706 subdivide_classes_by_equality (true);
1708 if (dump_file)
1709 fprintf (dump_file, "Dump after WPA based types groups\n");
1711 dump_cong_classes ();
1713 process_cong_reduction ();
1714 verify_classes ();
1716 if (dump_file)
1717 fprintf (dump_file, "Dump after callgraph-based congruence reduction\n");
1719 dump_cong_classes ();
1721 parse_nonsingleton_classes ();
1722 subdivide_classes_by_equality ();
1724 if (dump_file)
1725 fprintf (dump_file, "Dump after full equality comparison of groups\n");
1727 dump_cong_classes ();
1729 unsigned int prev_class_count = m_classes_count;
1731 process_cong_reduction ();
1732 dump_cong_classes ();
1733 verify_classes ();
1734 merge_classes (prev_class_count);
1736 if (dump_file && (dump_flags & TDF_DETAILS))
1737 symtab_node::dump_table (dump_file);
1740 /* Function responsible for visiting all potential functions and
1741 read-only variables that can be merged. */
1743 void
1744 sem_item_optimizer::parse_funcs_and_vars (void)
1746 cgraph_node *cnode;
1748 if (flag_ipa_icf_functions)
1749 FOR_EACH_DEFINED_FUNCTION (cnode)
1751 sem_function *f = sem_function::parse (cnode, &m_bmstack);
1752 if (f)
1754 m_items.safe_push (f);
1755 m_symtab_node_map.put (cnode, f);
1757 if (dump_file)
1758 fprintf (dump_file, "Parsed function:%s\n", f->asm_name ());
1760 if (dump_file && (dump_flags & TDF_DETAILS))
1761 f->dump_to_file (dump_file);
1763 else if (dump_file)
1764 fprintf (dump_file, "Not parsed function:%s\n", cnode->asm_name ());
1767 varpool_node *vnode;
1769 if (flag_ipa_icf_variables)
1770 FOR_EACH_DEFINED_VARIABLE (vnode)
1772 sem_variable *v = sem_variable::parse (vnode, &m_bmstack);
1774 if (v)
1776 m_items.safe_push (v);
1777 m_symtab_node_map.put (vnode, v);
1782 /* Makes pairing between a congruence class CLS and semantic ITEM. */
1784 void
1785 sem_item_optimizer::add_item_to_class (congruence_class *cls, sem_item *item)
1787 item->index_in_class = cls->members.length ();
1788 cls->members.safe_push (item);
1789 item->cls = cls;
1792 /* Congruence classes are built by hash value. */
1794 void
1795 sem_item_optimizer::build_hash_based_classes (void)
1797 for (unsigned i = 0; i < m_items.length (); i++)
1799 sem_item *item = m_items[i];
1801 congruence_class_group *group = get_group_by_hash (item->get_hash (),
1802 item->type);
1804 if (!group->classes.length ())
1806 m_classes_count++;
1807 group->classes.safe_push (new congruence_class (class_id++));
1810 add_item_to_class (group->classes[0], item);
1814 /* Build references according to call graph. */
1816 void
1817 sem_item_optimizer::build_graph (void)
1819 for (unsigned i = 0; i < m_items.length (); i++)
1821 sem_item *item = m_items[i];
1822 m_symtab_node_map.put (item->node, item);
1825 for (unsigned i = 0; i < m_items.length (); i++)
1827 sem_item *item = m_items[i];
1829 if (item->type == FUNC)
1831 cgraph_node *cnode = dyn_cast <cgraph_node *> (item->node);
1833 cgraph_edge *e = cnode->callees;
1834 while (e)
1836 sem_item **slot = m_symtab_node_map.get (e->callee);
1837 if (slot)
1838 item->add_reference (*slot);
1840 e = e->next_callee;
1844 ipa_ref *ref = NULL;
1845 for (unsigned i = 0; item->node->iterate_reference (i, ref); i++)
1847 sem_item **slot = m_symtab_node_map.get (ref->referred);
1848 if (slot)
1849 item->add_reference (*slot);
1854 /* Semantic items in classes having more than one element and initialized.
1855 In case of WPA, we load function body. */
1857 void
1858 sem_item_optimizer::parse_nonsingleton_classes (void)
1860 unsigned int init_called_count = 0;
1862 for (unsigned i = 0; i < m_items.length (); i++)
1863 if (m_items[i]->cls->members.length () > 1)
1865 m_items[i]->init ();
1866 init_called_count++;
1869 if (dump_file)
1870 fprintf (dump_file, "Init called for %u items (%.2f%%).\n", init_called_count,
1871 m_items.length () ? 100.0f * init_called_count / m_items.length (): 0.0f);
1874 /* Equality function for semantic items is used to subdivide existing
1875 classes. If IN_WPA, fast equality function is invoked. */
1877 void
1878 sem_item_optimizer::subdivide_classes_by_equality (bool in_wpa)
1880 for (hash_table <congruence_class_group_hash>::iterator it = m_classes.begin ();
1881 it != m_classes.end (); ++it)
1883 unsigned int class_count = (*it)->classes.length ();
1885 for (unsigned i = 0; i < class_count; i++)
1887 congruence_class *c = (*it)->classes [i];
1889 if (c->members.length() > 1)
1891 auto_vec <sem_item *> new_vector;
1893 sem_item *first = c->members[0];
1894 new_vector.safe_push (first);
1896 unsigned class_split_first = (*it)->classes.length ();
1898 for (unsigned j = 1; j < c->members.length (); j++)
1900 sem_item *item = c->members[j];
1902 bool equals = in_wpa ? first->equals_wpa (item,
1903 m_symtab_node_map) : first->equals (item, m_symtab_node_map);
1905 if (equals)
1906 new_vector.safe_push (item);
1907 else
1909 bool integrated = false;
1911 for (unsigned k = class_split_first; k < (*it)->classes.length (); k++)
1913 sem_item *x = (*it)->classes[k]->members[0];
1914 bool equals = in_wpa ? x->equals_wpa (item,
1915 m_symtab_node_map) : x->equals (item, m_symtab_node_map);
1917 if (equals)
1919 integrated = true;
1920 add_item_to_class ((*it)->classes[k], item);
1922 break;
1926 if (!integrated)
1928 congruence_class *c = new congruence_class (class_id++);
1929 m_classes_count++;
1930 add_item_to_class (c, item);
1932 (*it)->classes.safe_push (c);
1937 // we replace newly created new_vector for the class we've just splitted
1938 c->members.release ();
1939 c->members.create (new_vector.length ());
1941 for (unsigned int j = 0; j < new_vector.length (); j++)
1942 add_item_to_class (c, new_vector[j]);
1947 verify_classes ();
1950 /* Verify congruence classes if checking is enabled. */
1952 void
1953 sem_item_optimizer::verify_classes (void)
1955 #if ENABLE_CHECKING
1956 for (hash_table <congruence_class_group_hash>::iterator it = m_classes.begin ();
1957 it != m_classes.end (); ++it)
1959 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
1961 congruence_class *cls = (*it)->classes[i];
1963 gcc_checking_assert (cls);
1964 gcc_checking_assert (cls->members.length () > 0);
1966 for (unsigned int j = 0; j < cls->members.length (); j++)
1968 sem_item *item = cls->members[j];
1970 gcc_checking_assert (item);
1971 gcc_checking_assert (item->cls == cls);
1973 for (unsigned k = 0; k < item->usages.length (); k++)
1975 sem_usage_pair *usage = item->usages[k];
1976 gcc_checking_assert (usage->item->index_in_class <
1977 usage->item->cls->members.length ());
1982 #endif
1985 /* Disposes split map traverse function. CLS_PTR is pointer to congruence
1986 class, BSLOT is bitmap slot we want to release. DATA is mandatory,
1987 but unused argument. */
1989 bool
1990 sem_item_optimizer::release_split_map (congruence_class * const &,
1991 bitmap const &b, traverse_split_pair *)
1993 bitmap bmp = b;
1995 BITMAP_FREE (bmp);
1997 return true;
2000 /* Process split operation for a class given as pointer CLS_PTR,
2001 where bitmap B splits congruence class members. DATA is used
2002 as argument of split pair. */
2004 bool
2005 sem_item_optimizer::traverse_congruence_split (congruence_class * const &cls,
2006 bitmap const &b, traverse_split_pair *pair)
2008 sem_item_optimizer *optimizer = pair->optimizer;
2009 const congruence_class *splitter_cls = pair->cls;
2011 /* If counted bits are greater than zero and less than the number of members
2012 a group will be splitted. */
2013 unsigned popcount = bitmap_count_bits (b);
2015 if (popcount > 0 && popcount < cls->members.length ())
2017 congruence_class* newclasses[2] = { new congruence_class (class_id++), new congruence_class (class_id++) };
2019 for (unsigned int i = 0; i < cls->members.length (); i++)
2021 int target = bitmap_bit_p (b, i);
2022 congruence_class *tc = newclasses[target];
2024 add_item_to_class (tc, cls->members[i]);
2027 #ifdef ENABLE_CHECKING
2028 for (unsigned int i = 0; i < 2; i++)
2029 gcc_checking_assert (newclasses[i]->members.length ());
2030 #endif
2032 if (splitter_cls == cls)
2033 optimizer->splitter_class_removed = true;
2035 /* Remove old class from worklist if presented. */
2036 bool in_worklist = cls->in_worklist;
2038 if (in_worklist)
2039 cls->in_worklist = false;
2041 congruence_class_group g;
2042 g.hash = cls->members[0]->get_hash ();
2043 g.type = cls->members[0]->type;
2045 congruence_class_group *slot = optimizer->m_classes.find(&g);
2047 for (unsigned int i = 0; i < slot->classes.length (); i++)
2048 if (slot->classes[i] == cls)
2050 slot->classes.ordered_remove (i);
2051 break;
2054 /* New class will be inserted and integrated to work list. */
2055 for (unsigned int i = 0; i < 2; i++)
2056 optimizer->add_class (newclasses[i]);
2058 /* Two classes replace one, so that increment just by one. */
2059 optimizer->m_classes_count++;
2061 /* If OLD class was presented in the worklist, we remove the class
2062 and replace it will both newly created classes. */
2063 if (in_worklist)
2064 for (unsigned int i = 0; i < 2; i++)
2065 optimizer->worklist_push (newclasses[i]);
2066 else /* Just smaller class is inserted. */
2068 unsigned int smaller_index = newclasses[0]->members.length () <
2069 newclasses[1]->members.length () ?
2070 0 : 1;
2071 optimizer->worklist_push (newclasses[smaller_index]);
2074 if (dump_file && (dump_flags & TDF_DETAILS))
2076 fprintf (dump_file, " congruence class splitted:\n");
2077 cls->dump (dump_file, 4);
2079 fprintf (dump_file, " newly created groups:\n");
2080 for (unsigned int i = 0; i < 2; i++)
2081 newclasses[i]->dump (dump_file, 4);
2084 /* Release class if not presented in work list. */
2085 if (!in_worklist)
2086 delete cls;
2090 return true;
2093 /* Tests if a class CLS used as INDEXth splits any congruence classes.
2094 Bitmap stack BMSTACK is used for bitmap allocation. */
2096 void
2097 sem_item_optimizer::do_congruence_step_for_index (congruence_class *cls,
2098 unsigned int index)
2100 hash_map <congruence_class *, bitmap> split_map;
2102 for (unsigned int i = 0; i < cls->members.length (); i++)
2104 sem_item *item = cls->members[i];
2106 /* Iterate all usages that have INDEX as usage of the item. */
2107 for (unsigned int j = 0; j < item->usages.length (); j++)
2109 sem_usage_pair *usage = item->usages[j];
2111 if (usage->index != index)
2112 continue;
2114 bitmap *slot = split_map.get (usage->item->cls);
2115 bitmap b;
2117 if(!slot)
2119 b = BITMAP_ALLOC (&m_bmstack);
2120 split_map.put (usage->item->cls, b);
2122 else
2123 b = *slot;
2125 #if ENABLE_CHECKING
2126 gcc_checking_assert (usage->item->cls);
2127 gcc_checking_assert (usage->item->index_in_class <
2128 usage->item->cls->members.length ());
2129 #endif
2131 bitmap_set_bit (b, usage->item->index_in_class);
2135 traverse_split_pair pair;
2136 pair.optimizer = this;
2137 pair.cls = cls;
2139 splitter_class_removed = false;
2140 split_map.traverse
2141 <traverse_split_pair *, sem_item_optimizer::traverse_congruence_split> (&pair);
2143 /* Bitmap clean-up. */
2144 split_map.traverse
2145 <traverse_split_pair *, sem_item_optimizer::release_split_map> (NULL);
2148 /* Every usage of a congruence class CLS is a candidate that can split the
2149 collection of classes. Bitmap stack BMSTACK is used for bitmap
2150 allocation. */
2152 void
2153 sem_item_optimizer::do_congruence_step (congruence_class *cls)
2155 bitmap_iterator bi;
2156 unsigned int i;
2158 bitmap usage = BITMAP_ALLOC (&m_bmstack);
2160 for (unsigned int i = 0; i < cls->members.length (); i++)
2161 bitmap_ior_into (usage, cls->members[i]->usage_index_bitmap);
2163 EXECUTE_IF_SET_IN_BITMAP (usage, 0, i, bi)
2165 if (dump_file && (dump_flags & TDF_DETAILS))
2166 fprintf (dump_file, " processing congruece step for class: %u, index: %u\n",
2167 cls->id, i);
2169 do_congruence_step_for_index (cls, i);
2171 if (splitter_class_removed)
2172 break;
2175 BITMAP_FREE (usage);
2178 /* Adds a newly created congruence class CLS to worklist. */
2180 void
2181 sem_item_optimizer::worklist_push (congruence_class *cls)
2183 /* Return if the class CLS is already presented in work list. */
2184 if (cls->in_worklist)
2185 return;
2187 cls->in_worklist = true;
2188 worklist.push_back (cls);
2191 /* Pops a class from worklist. */
2193 congruence_class *
2194 sem_item_optimizer::worklist_pop (void)
2196 congruence_class *cls;
2198 while (!worklist.empty ())
2200 cls = worklist.front ();
2201 worklist.pop_front ();
2202 if (cls->in_worklist)
2204 cls->in_worklist = false;
2206 return cls;
2208 else
2210 /* Work list item was already intended to be removed.
2211 The only reason for doing it is to split a class.
2212 Thus, the class CLS is deleted. */
2213 delete cls;
2217 return NULL;
2220 /* Iterative congruence reduction function. */
2222 void
2223 sem_item_optimizer::process_cong_reduction (void)
2225 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2226 it != m_classes.end (); ++it)
2227 for (unsigned i = 0; i < (*it)->classes.length (); i++)
2228 if ((*it)->classes[i]->is_class_used ())
2229 worklist_push ((*it)->classes[i]);
2231 if (dump_file)
2232 fprintf (dump_file, "Worklist has been filled with: %lu\n",
2233 (unsigned long) worklist.size ());
2235 if (dump_file && (dump_flags & TDF_DETAILS))
2236 fprintf (dump_file, "Congruence class reduction\n");
2238 congruence_class *cls;
2239 while ((cls = worklist_pop ()) != NULL)
2240 do_congruence_step (cls);
2243 /* Debug function prints all informations about congruence classes. */
2245 void
2246 sem_item_optimizer::dump_cong_classes (void)
2248 if (!dump_file)
2249 return;
2251 fprintf (dump_file,
2252 "Congruence classes: %u (unique hash values: %lu), with total: %u items\n",
2253 m_classes_count, (unsigned long) m_classes.elements(), m_items.length ());
2255 /* Histogram calculation. */
2256 unsigned int max_index = 0;
2257 unsigned int* histogram = XCNEWVEC (unsigned int, m_items.length () + 1);
2259 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2260 it != m_classes.end (); ++it)
2262 for (unsigned i = 0; i < (*it)->classes.length (); i++)
2264 unsigned int c = (*it)->classes[i]->members.length ();
2265 histogram[c]++;
2267 if (c > max_index)
2268 max_index = c;
2271 fprintf (dump_file,
2272 "Class size histogram [num of members]: number of classe number of classess\n");
2274 for (unsigned int i = 0; i <= max_index; i++)
2275 if (histogram[i])
2276 fprintf (dump_file, "[%u]: %u classes\n", i, histogram[i]);
2278 fprintf (dump_file, "\n\n");
2281 if (dump_flags & TDF_DETAILS)
2282 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2283 it != m_classes.end (); ++it)
2285 fprintf (dump_file, " group: with %u classes:\n", (*it)->classes.length ());
2287 for (unsigned i = 0; i < (*it)->classes.length (); i++)
2289 (*it)->classes[i]->dump (dump_file, 4);
2291 if(i < (*it)->classes.length () - 1)
2292 fprintf (dump_file, " ");
2296 free (histogram);
2299 /* After reduction is done, we can declare all items in a group
2300 to be equal. PREV_CLASS_COUNT is start number of classes
2301 before reduction. */
2303 void
2304 sem_item_optimizer::merge_classes (unsigned int prev_class_count)
2306 unsigned int item_count = m_items.length ();
2307 unsigned int class_count = m_classes_count;
2308 unsigned int equal_items = item_count - class_count;
2310 unsigned int non_singular_classes_count = 0;
2311 unsigned int non_singular_classes_sum = 0;
2313 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2314 it != m_classes.end (); ++it)
2315 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
2317 congruence_class *c = (*it)->classes[i];
2318 if (c->members.length () > 1)
2320 non_singular_classes_count++;
2321 non_singular_classes_sum += c->members.length ();
2325 if (dump_file)
2327 fprintf (dump_file, "\nItem count: %u\n", item_count);
2328 fprintf (dump_file, "Congruent classes before: %u, after: %u\n",
2329 prev_class_count, class_count);
2330 fprintf (dump_file, "Average class size before: %.2f, after: %.2f\n",
2331 prev_class_count ? 1.0f * item_count / prev_class_count : 0.0f,
2332 class_count ? 1.0f * item_count / class_count : 0.0f);
2333 fprintf (dump_file, "Average non-singular class size: %.2f, count: %u\n",
2334 non_singular_classes_count ? 1.0f * non_singular_classes_sum /
2335 non_singular_classes_count : 0.0f,
2336 non_singular_classes_count);
2337 fprintf (dump_file, "Equal symbols: %u\n", equal_items);
2338 fprintf (dump_file, "Fraction of visited symbols: %.2f%%\n\n",
2339 item_count ? 100.0f * equal_items / item_count : 0.0f);
2342 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2343 it != m_classes.end (); ++it)
2344 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
2346 congruence_class *c = (*it)->classes[i];
2348 if (c->members.length () == 1)
2349 continue;
2351 gcc_assert (c->members.length ());
2353 sem_item *source = c->members[0];
2355 for (unsigned int j = 1; j < c->members.length (); j++)
2357 sem_item *alias = c->members[j];
2359 if (dump_file)
2361 fprintf (dump_file, "Semantic equality hit:%s->%s\n",
2362 source->name (), alias->name ());
2363 fprintf (dump_file, "Assembler symbol names:%s->%s\n",
2364 source->asm_name (), alias->asm_name ());
2367 if (dump_file && (dump_flags & TDF_DETAILS))
2369 source->dump_to_file (dump_file);
2370 alias->dump_to_file (dump_file);
2373 source->merge (alias);
2378 /* Dump function prints all class members to a FILE with an INDENT. */
2380 void
2381 congruence_class::dump (FILE *file, unsigned int indent) const
2383 FPRINTF_SPACES (file, indent, "class with id: %u, hash: %u, items: %u\n",
2384 id, members[0]->get_hash (), members.length ());
2386 FPUTS_SPACES (file, indent + 2, "");
2387 for (unsigned i = 0; i < members.length (); i++)
2388 fprintf (file, "%s(%p/%u) ", members[i]->asm_name (), (void *) members[i]->decl,
2389 members[i]->node->order);
2391 fprintf (file, "\n");
2394 /* Returns true if there's a member that is used from another group. */
2396 bool
2397 congruence_class::is_class_used (void)
2399 for (unsigned int i = 0; i < members.length (); i++)
2400 if (members[i]->usages.length ())
2401 return true;
2403 return false;
2406 /* Initialization and computation of symtab node hash, there data
2407 are propagated later on. */
2409 static sem_item_optimizer *optimizer = NULL;
2411 /* Generate pass summary for IPA ICF pass. */
2413 static void
2414 ipa_icf_generate_summary (void)
2416 if (!optimizer)
2417 optimizer = new sem_item_optimizer ();
2419 optimizer->parse_funcs_and_vars ();
2422 /* Write pass summary for IPA ICF pass. */
2424 static void
2425 ipa_icf_write_summary (void)
2427 gcc_assert (optimizer);
2429 optimizer->write_summary ();
2432 /* Read pass summary for IPA ICF pass. */
2434 static void
2435 ipa_icf_read_summary (void)
2437 if (!optimizer)
2438 optimizer = new sem_item_optimizer ();
2440 optimizer->read_summary ();
2441 optimizer->register_hooks ();
2444 /* Semantic equality exection function. */
2446 static unsigned int
2447 ipa_icf_driver (void)
2449 gcc_assert (optimizer);
2451 optimizer->execute ();
2452 optimizer->unregister_hooks ();
2454 delete optimizer;
2455 optimizer = NULL;
2457 return 0;
2460 const pass_data pass_data_ipa_icf =
2462 IPA_PASS, /* type */
2463 "icf", /* name */
2464 OPTGROUP_IPA, /* optinfo_flags */
2465 TV_IPA_ICF, /* tv_id */
2466 0, /* properties_required */
2467 0, /* properties_provided */
2468 0, /* properties_destroyed */
2469 0, /* todo_flags_start */
2470 0, /* todo_flags_finish */
2473 class pass_ipa_icf : public ipa_opt_pass_d
2475 public:
2476 pass_ipa_icf (gcc::context *ctxt)
2477 : ipa_opt_pass_d (pass_data_ipa_icf, ctxt,
2478 ipa_icf_generate_summary, /* generate_summary */
2479 ipa_icf_write_summary, /* write_summary */
2480 ipa_icf_read_summary, /* read_summary */
2481 NULL, /*
2482 write_optimization_summary */
2483 NULL, /*
2484 read_optimization_summary */
2485 NULL, /* stmt_fixup */
2486 0, /* function_transform_todo_flags_start */
2487 NULL, /* function_transform */
2488 NULL) /* variable_transform */
2491 /* opt_pass methods: */
2492 virtual bool gate (function *)
2494 return flag_ipa_icf_variables || flag_ipa_icf_functions;
2497 virtual unsigned int execute (function *)
2499 return ipa_icf_driver();
2501 }; // class pass_ipa_icf
2503 } // ipa_icf namespace
2505 ipa_opt_pass_d *
2506 make_pass_ipa_icf (gcc::context *ctxt)
2508 return new ipa_icf::pass_ipa_icf (ctxt);