PR target/64876
[official-gcc.git] / gcc / ipa-icf.c
blobcf5e5d929687b0f96e73701374b59cb00a1328c3
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 "function.h"
73 #include "dominance.h"
74 #include "cfg.h"
75 #include "basic-block.h"
76 #include "tree-ssa-alias.h"
77 #include "internal-fn.h"
78 #include "gimple-expr.h"
79 #include "is-a.h"
80 #include "gimple.h"
81 #include "hashtab.h"
82 #include "rtl.h"
83 #include "flags.h"
84 #include "statistics.h"
85 #include "real.h"
86 #include "fixed-value.h"
87 #include "insn-config.h"
88 #include "expmed.h"
89 #include "dojump.h"
90 #include "explow.h"
91 #include "calls.h"
92 #include "emit-rtl.h"
93 #include "varasm.h"
94 #include "stmt.h"
95 #include "expr.h"
96 #include "gimple-iterator.h"
97 #include "gimple-ssa.h"
98 #include "tree-cfg.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"
107 #include "ipa-ref.h"
108 #include "cgraph.h"
109 #include "alloc-pool.h"
110 #include "symbol-summary.h"
111 #include "ipa-prop.h"
112 #include "ipa-inline.h"
113 #include "cfgloop.h"
114 #include "except.h"
115 #include "hash-table.h"
116 #include "coverage.h"
117 #include "attribs.h"
118 #include "print-tree.h"
119 #include "lto-streamer.h"
120 #include "data-streamer.h"
121 #include "ipa-utils.h"
122 #include <list>
123 #include "ipa-icf-gimple.h"
124 #include "ipa-icf.h"
126 using namespace ipa_icf_gimple;
128 namespace ipa_icf {
129 /* Constructor for key value pair, where _ITEM is key and _INDEX is a target. */
131 sem_usage_pair::sem_usage_pair (sem_item *_item, unsigned int _index):
132 item (_item), index (_index)
136 /* Semantic item constructor for a node of _TYPE, where STACK is used
137 for bitmap memory allocation. */
139 sem_item::sem_item (sem_item_type _type,
140 bitmap_obstack *stack): type(_type), hash(0)
142 setup (stack);
145 /* Semantic item constructor for a node of _TYPE, where STACK is used
146 for bitmap memory allocation. The item is based on symtab node _NODE
147 with computed _HASH. */
149 sem_item::sem_item (sem_item_type _type, symtab_node *_node,
150 hashval_t _hash, bitmap_obstack *stack): type(_type),
151 node (_node), hash (_hash)
153 decl = node->decl;
154 setup (stack);
157 /* Add reference to a semantic TARGET. */
159 void
160 sem_item::add_reference (sem_item *target)
162 refs.safe_push (target);
163 unsigned index = refs.length ();
164 target->usages.safe_push (new sem_usage_pair(this, index));
165 bitmap_set_bit (target->usage_index_bitmap, index);
166 refs_set.add (target->node);
169 /* Initialize internal data structures. Bitmap STACK is used for
170 bitmap memory allocation process. */
172 void
173 sem_item::setup (bitmap_obstack *stack)
175 gcc_checking_assert (node);
177 refs.create (0);
178 tree_refs.create (0);
179 usages.create (0);
180 usage_index_bitmap = BITMAP_ALLOC (stack);
183 sem_item::~sem_item ()
185 for (unsigned i = 0; i < usages.length (); i++)
186 delete usages[i];
188 refs.release ();
189 tree_refs.release ();
190 usages.release ();
192 BITMAP_FREE (usage_index_bitmap);
195 /* Dump function for debugging purpose. */
197 DEBUG_FUNCTION void
198 sem_item::dump (void)
200 if (dump_file)
202 fprintf (dump_file, "[%s] %s (%u) (tree:%p)\n", type == FUNC ? "func" : "var",
203 name(), node->order, (void *) node->decl);
204 fprintf (dump_file, " hash: %u\n", get_hash ());
205 fprintf (dump_file, " references: ");
207 for (unsigned i = 0; i < refs.length (); i++)
208 fprintf (dump_file, "%s%s ", refs[i]->name (),
209 i < refs.length() - 1 ? "," : "");
211 fprintf (dump_file, "\n");
215 /* Return true if target supports alias symbols. */
217 bool
218 sem_item::target_supports_symbol_aliases_p (void)
220 #if !defined (ASM_OUTPUT_DEF) || (!defined(ASM_OUTPUT_WEAK_ALIAS) && !defined (ASM_WEAKEN_DECL))
221 return false;
222 #else
223 return true;
224 #endif
227 /* Semantic function constructor that uses STACK as bitmap memory stack. */
229 sem_function::sem_function (bitmap_obstack *stack): sem_item (FUNC, 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 /* Constructor based on callgraph node _NODE with computed hash _HASH.
238 Bitmap STACK is used for memory allocation. */
239 sem_function::sem_function (cgraph_node *node, hashval_t hash,
240 bitmap_obstack *stack):
241 sem_item (FUNC, node, hash, stack),
242 m_checker (NULL), m_compared_func (NULL)
244 arg_types.create (0);
245 bb_sizes.create (0);
246 bb_sorted.create (0);
249 sem_function::~sem_function ()
251 for (unsigned i = 0; i < bb_sorted.length (); i++)
252 delete (bb_sorted[i]);
254 arg_types.release ();
255 bb_sizes.release ();
256 bb_sorted.release ();
259 /* Calculates hash value based on a BASIC_BLOCK. */
261 hashval_t
262 sem_function::get_bb_hash (const sem_bb *basic_block)
264 inchash::hash hstate;
266 hstate.add_int (basic_block->nondbg_stmt_count);
267 hstate.add_int (basic_block->edge_count);
269 return hstate.end ();
272 /* References independent hash function. */
274 hashval_t
275 sem_function::get_hash (void)
277 if(!hash)
279 inchash::hash hstate;
280 hstate.add_int (177454); /* Random number for function type. */
282 hstate.add_int (arg_count);
283 hstate.add_int (cfg_checksum);
284 hstate.add_int (gcode_hash);
286 for (unsigned i = 0; i < bb_sorted.length (); i++)
287 hstate.merge_hash (get_bb_hash (bb_sorted[i]));
289 for (unsigned i = 0; i < bb_sizes.length (); i++)
290 hstate.add_int (bb_sizes[i]);
292 hash = hstate.end ();
295 return hash;
298 /* For a given symbol table nodes N1 and N2, we check that FUNCTION_DECLs
299 point to a same function. Comparison can be skipped if IGNORED_NODES
300 contains these nodes. */
302 bool
303 sem_function::compare_cgraph_references (hash_map <symtab_node *, sem_item *>
304 &ignored_nodes,
305 symtab_node *n1, symtab_node *n2)
307 if (n1 == n2 || (ignored_nodes.get (n1) && ignored_nodes.get (n2)))
308 return true;
310 /* TODO: add more precise comparison for weakrefs, etc. */
312 return return_false_with_msg ("different references");
315 /* If cgraph edges E1 and E2 are indirect calls, verify that
316 ECF flags are the same. */
318 bool sem_function::compare_edge_flags (cgraph_edge *e1, cgraph_edge *e2)
320 if (e1->indirect_info && e2->indirect_info)
322 int e1_flags = e1->indirect_info->ecf_flags;
323 int e2_flags = e2->indirect_info->ecf_flags;
325 if (e1_flags != e2_flags)
326 return return_false_with_msg ("ICF flags are different");
328 else if (e1->indirect_info || e2->indirect_info)
329 return false;
331 return true;
334 /* Fast equality function based on knowledge known in WPA. */
336 bool
337 sem_function::equals_wpa (sem_item *item,
338 hash_map <symtab_node *, sem_item *> &ignored_nodes)
340 gcc_assert (item->type == FUNC);
342 m_compared_func = static_cast<sem_function *> (item);
344 if (arg_types.length () != m_compared_func->arg_types.length ())
345 return return_false_with_msg ("different number of arguments");
347 /* Checking types of arguments. */
348 for (unsigned i = 0; i < arg_types.length (); i++)
350 /* This guard is here for function pointer with attributes (pr59927.c). */
351 if (!arg_types[i] || !m_compared_func->arg_types[i])
352 return return_false_with_msg ("NULL argument type");
354 /* Polymorphic comparison is executed just for non-leaf functions. */
355 bool is_not_leaf = get_node ()->callees != NULL
356 || get_node ()->indirect_calls != NULL;
358 if (!func_checker::compatible_types_p (arg_types[i],
359 m_compared_func->arg_types[i],
360 is_not_leaf, i == 0))
361 return return_false_with_msg ("argument type is different");
364 /* Result type checking. */
365 if (!func_checker::compatible_types_p (result_type,
366 m_compared_func->result_type))
367 return return_false_with_msg ("result types are different");
369 if (node->num_references () != item->node->num_references ())
370 return return_false_with_msg ("different number of references");
372 ipa_ref *ref = NULL, *ref2 = NULL;
373 for (unsigned i = 0; node->iterate_reference (i, ref); i++)
375 item->node->iterate_reference (i, ref2);
377 if (!compare_cgraph_references (ignored_nodes, ref->referred, ref2->referred))
378 return false;
381 cgraph_edge *e1 = dyn_cast <cgraph_node *> (node)->callees;
382 cgraph_edge *e2 = dyn_cast <cgraph_node *> (item->node)->callees;
384 while (e1 && e2)
386 if (!compare_cgraph_references (ignored_nodes, e1->callee, e2->callee))
387 return false;
389 e1 = e1->next_callee;
390 e2 = e2->next_callee;
393 if (e1 || e2)
394 return return_false_with_msg ("different number of edges");
396 return true;
399 /* Returns true if the item equals to ITEM given as argument. */
401 bool
402 sem_function::equals (sem_item *item,
403 hash_map <symtab_node *, sem_item *> &ignored_nodes)
405 gcc_assert (item->type == FUNC);
406 bool eq = equals_private (item, ignored_nodes);
408 if (m_checker != NULL)
410 delete m_checker;
411 m_checker = NULL;
414 if (dump_file && (dump_flags & TDF_DETAILS))
415 fprintf (dump_file,
416 "Equals called for:%s:%s (%u:%u) (%s:%s) with result: %s\n\n",
417 name(), item->name (), node->order, item->node->order, asm_name (),
418 item->asm_name (), eq ? "true" : "false");
420 return eq;
423 /* Processes function equality comparison. */
425 bool
426 sem_function::equals_private (sem_item *item,
427 hash_map <symtab_node *, sem_item *> &ignored_nodes)
429 if (item->type != FUNC)
430 return false;
432 basic_block bb1, bb2;
433 edge e1, e2;
434 edge_iterator ei1, ei2;
435 bool result = true;
436 tree arg1, arg2;
438 m_compared_func = static_cast<sem_function *> (item);
440 gcc_assert (decl != item->decl);
442 if (bb_sorted.length () != m_compared_func->bb_sorted.length ()
443 || edge_count != m_compared_func->edge_count
444 || cfg_checksum != m_compared_func->cfg_checksum)
445 return return_false ();
447 if (!equals_wpa (item, ignored_nodes))
448 return false;
450 /* Checking function TARGET and OPTIMIZATION flags. */
451 cl_target_option *tar1 = target_opts_for_fn (decl);
452 cl_target_option *tar2 = target_opts_for_fn (m_compared_func->decl);
454 if (tar1 != NULL && tar2 != NULL)
456 if (!cl_target_option_eq (tar1, tar2))
458 if (dump_file && (dump_flags & TDF_DETAILS))
460 fprintf (dump_file, "target flags difference");
461 cl_target_option_print_diff (dump_file, 2, tar1, tar2);
464 return return_false_with_msg ("Target flags are different");
467 else if (tar1 != NULL || tar2 != NULL)
468 return return_false_with_msg ("Target flags are different");
470 cl_optimization *opt1 = opts_for_fn (decl);
471 cl_optimization *opt2 = opts_for_fn (m_compared_func->decl);
473 if (opt1 != NULL && opt2 != NULL)
475 if (memcmp (opt1, opt2, sizeof(cl_optimization)))
477 if (dump_file && (dump_flags & TDF_DETAILS))
479 fprintf (dump_file, "optimization flags difference");
480 cl_optimization_print_diff (dump_file, 2, opt1, opt2);
483 return return_false_with_msg ("optimization flags are different");
486 else if (opt1 != NULL || opt2 != NULL)
487 return return_false_with_msg ("optimization flags are different");
489 /* Checking function arguments. */
490 tree decl1 = DECL_ATTRIBUTES (decl);
491 tree decl2 = DECL_ATTRIBUTES (m_compared_func->decl);
493 m_checker = new func_checker (decl, m_compared_func->decl,
494 compare_polymorphic_p (),
495 false,
496 &refs_set,
497 &m_compared_func->refs_set);
498 while (decl1)
500 if (decl2 == NULL)
501 return return_false ();
503 if (get_attribute_name (decl1) != get_attribute_name (decl2))
504 return return_false ();
506 tree attr_value1 = TREE_VALUE (decl1);
507 tree attr_value2 = TREE_VALUE (decl2);
509 if (attr_value1 && attr_value2)
511 bool ret = m_checker->compare_operand (TREE_VALUE (attr_value1),
512 TREE_VALUE (attr_value2));
513 if (!ret)
514 return return_false_with_msg ("attribute values are different");
516 else if (!attr_value1 && !attr_value2)
518 else
519 return return_false ();
521 decl1 = TREE_CHAIN (decl1);
522 decl2 = TREE_CHAIN (decl2);
525 if (decl1 != decl2)
526 return return_false();
529 for (arg1 = DECL_ARGUMENTS (decl),
530 arg2 = DECL_ARGUMENTS (m_compared_func->decl);
531 arg1; arg1 = DECL_CHAIN (arg1), arg2 = DECL_CHAIN (arg2))
532 if (!m_checker->compare_decl (arg1, arg2))
533 return return_false ();
535 /* Fill-up label dictionary. */
536 for (unsigned i = 0; i < bb_sorted.length (); ++i)
538 m_checker->parse_labels (bb_sorted[i]);
539 m_checker->parse_labels (m_compared_func->bb_sorted[i]);
542 /* Checking all basic blocks. */
543 for (unsigned i = 0; i < bb_sorted.length (); ++i)
544 if(!m_checker->compare_bb (bb_sorted[i], m_compared_func->bb_sorted[i]))
545 return return_false();
547 dump_message ("All BBs are equal\n");
549 auto_vec <int> bb_dict;
551 /* Basic block edges check. */
552 for (unsigned i = 0; i < bb_sorted.length (); ++i)
554 bb1 = bb_sorted[i]->bb;
555 bb2 = m_compared_func->bb_sorted[i]->bb;
557 ei2 = ei_start (bb2->preds);
559 for (ei1 = ei_start (bb1->preds); ei_cond (ei1, &e1); ei_next (&ei1))
561 ei_cond (ei2, &e2);
563 if (e1->flags != e2->flags)
564 return return_false_with_msg ("flags comparison returns false");
566 if (!bb_dict_test (bb_dict, e1->src->index, e2->src->index))
567 return return_false_with_msg ("edge comparison returns false");
569 if (!bb_dict_test (bb_dict, e1->dest->index, e2->dest->index))
570 return return_false_with_msg ("BB comparison returns false");
572 if (!m_checker->compare_edge (e1, e2))
573 return return_false_with_msg ("edge comparison returns false");
575 ei_next (&ei2);
579 /* Basic block PHI nodes comparison. */
580 for (unsigned i = 0; i < bb_sorted.length (); i++)
581 if (!compare_phi_node (bb_sorted[i]->bb, m_compared_func->bb_sorted[i]->bb))
582 return return_false_with_msg ("PHI node comparison returns false");
584 return result;
587 /* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can
588 be applied. */
589 bool
590 sem_function::merge (sem_item *alias_item)
592 gcc_assert (alias_item->type == FUNC);
594 sem_function *alias_func = static_cast<sem_function *> (alias_item);
596 cgraph_node *original = get_node ();
597 cgraph_node *local_original = original;
598 cgraph_node *alias = alias_func->get_node ();
599 bool original_address_matters;
600 bool alias_address_matters;
602 bool create_thunk = false;
603 bool create_alias = false;
604 bool redirect_callers = false;
605 bool original_discardable = false;
607 /* Do not attempt to mix functions from different user sections;
608 we do not know what user intends with those. */
609 if (((DECL_SECTION_NAME (original->decl) && !original->implicit_section)
610 || (DECL_SECTION_NAME (alias->decl) && !alias->implicit_section))
611 && DECL_SECTION_NAME (original->decl) != DECL_SECTION_NAME (alias->decl))
613 if (dump_file)
614 fprintf (dump_file,
615 "Not unifying; original and alias are in different sections.\n\n");
616 return false;
619 /* See if original is in a section that can be discarded if the main
620 symbol is not used. */
621 if (DECL_EXTERNAL (original->decl))
622 original_discardable = true;
623 if (original->resolution == LDPR_PREEMPTED_REG
624 || original->resolution == LDPR_PREEMPTED_IR)
625 original_discardable = true;
626 if (original->can_be_discarded_p ())
627 original_discardable = true;
629 /* See if original and/or alias address can be compared for equality. */
630 original_address_matters
631 = (!DECL_VIRTUAL_P (original->decl)
632 && (original->externally_visible
633 || original->address_taken_from_non_vtable_p ()));
634 alias_address_matters
635 = (!DECL_VIRTUAL_P (alias->decl)
636 && (alias->externally_visible
637 || alias->address_taken_from_non_vtable_p ()));
639 /* If alias and original can be compared for address equality, we need
640 to create a thunk. Also we can not create extra aliases into discardable
641 section (or we risk link failures when section is discarded). */
642 if ((original_address_matters
643 && alias_address_matters)
644 || original_discardable)
646 create_thunk = !stdarg_p (TREE_TYPE (alias->decl));
647 create_alias = false;
648 /* When both alias and original are not overwritable, we can save
649 the extra thunk wrapper for direct calls. */
650 redirect_callers
651 = (!original_discardable
652 && alias->get_availability () > AVAIL_INTERPOSABLE
653 && original->get_availability () > AVAIL_INTERPOSABLE
654 && !alias->instrumented_version);
656 else
658 create_alias = true;
659 create_thunk = false;
660 redirect_callers = false;
663 if (create_alias && (DECL_COMDAT_GROUP (alias->decl)
664 || !sem_item::target_supports_symbol_aliases_p ()))
666 create_alias = false;
667 create_thunk = true;
670 /* We want thunk to always jump to the local function body
671 unless the body is comdat and may be optimized out. */
672 if ((create_thunk || redirect_callers)
673 && (!original_discardable
674 || (DECL_COMDAT_GROUP (original->decl)
675 && (DECL_COMDAT_GROUP (original->decl)
676 == DECL_COMDAT_GROUP (alias->decl)))))
677 local_original
678 = dyn_cast <cgraph_node *> (original->noninterposable_alias ());
680 if (!local_original)
682 if (dump_file)
683 fprintf (dump_file, "Noninterposable alias cannot be created.\n\n");
685 return false;
688 if (!decl_binds_to_current_def_p (alias->decl))
690 if (dump_file)
691 fprintf (dump_file, "Declaration does not bind to currect definition.\n\n");
692 return false;
695 if (redirect_callers)
697 /* If alias is non-overwritable then
698 all direct calls are safe to be redirected to the original. */
699 bool redirected = false;
700 while (alias->callers)
702 cgraph_edge *e = alias->callers;
703 e->redirect_callee (local_original);
704 push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
706 if (e->call_stmt)
707 e->redirect_call_stmt_to_callee ();
709 pop_cfun ();
710 redirected = true;
713 alias->icf_merged = true;
714 if (local_original->lto_file_data
715 && alias->lto_file_data
716 && local_original->lto_file_data != alias->lto_file_data)
717 local_original->merged = true;
719 /* The alias function is removed if symbol address
720 does not matter. */
721 if (!alias_address_matters)
722 alias->remove ();
724 if (dump_file && redirected)
725 fprintf (dump_file, "Callgraph local calls have been redirected.\n\n");
727 /* If the condtion above is not met, we are lucky and can turn the
728 function into real alias. */
729 else if (create_alias)
731 alias->icf_merged = true;
732 if (local_original->lto_file_data
733 && alias->lto_file_data
734 && local_original->lto_file_data != alias->lto_file_data)
735 local_original->merged = true;
737 /* Remove the function's body. */
738 ipa_merge_profiles (original, alias);
739 alias->release_body (true);
740 alias->reset ();
742 /* Create the alias. */
743 cgraph_node::create_alias (alias_func->decl, decl);
744 alias->resolve_alias (original);
746 /* Workaround for PR63566 that forces equal calling convention
747 to be used. */
748 alias->local.local = false;
749 original->local.local = false;
751 if (dump_file)
752 fprintf (dump_file, "Callgraph alias has been created.\n\n");
754 else if (create_thunk)
756 if (DECL_COMDAT_GROUP (alias->decl))
758 if (dump_file)
759 fprintf (dump_file, "Callgraph thunk cannot be created because of COMDAT\n");
761 return 0;
764 if (DECL_STATIC_CHAIN (alias->decl))
766 if (dump_file)
767 fprintf (dump_file, "Thunk creation is risky for static-chain functions.\n\n");
769 return 0;
772 alias->icf_merged = true;
773 if (local_original->lto_file_data
774 && alias->lto_file_data
775 && local_original->lto_file_data != alias->lto_file_data)
776 local_original->merged = true;
777 ipa_merge_profiles (local_original, alias, true);
778 alias->create_wrapper (local_original);
780 if (dump_file)
781 fprintf (dump_file, "Callgraph thunk has been created.\n\n");
783 else if (dump_file)
784 fprintf (dump_file, "Callgraph merge operation cannot be performed.\n\n");
786 return true;
789 /* Semantic item initialization function. */
791 void
792 sem_function::init (void)
794 if (in_lto_p)
795 get_node ()->get_untransformed_body ();
797 tree fndecl = node->decl;
798 function *func = DECL_STRUCT_FUNCTION (fndecl);
800 gcc_assert (func);
801 gcc_assert (SSANAMES (func));
803 ssa_names_size = SSANAMES (func)->length ();
804 node = node;
806 decl = fndecl;
807 region_tree = func->eh->region_tree;
809 /* iterating all function arguments. */
810 arg_count = count_formal_params (fndecl);
812 edge_count = n_edges_for_fn (func);
813 cfg_checksum = coverage_compute_cfg_checksum (func);
815 inchash::hash hstate;
817 basic_block bb;
818 FOR_EACH_BB_FN (bb, func)
820 unsigned nondbg_stmt_count = 0;
822 edge e;
823 for (edge_iterator ei = ei_start (bb->preds); ei_cond (ei, &e); ei_next (&ei))
824 cfg_checksum = iterative_hash_host_wide_int (e->flags,
825 cfg_checksum);
827 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
828 gsi_next (&gsi))
830 gimple stmt = gsi_stmt (gsi);
832 if (gimple_code (stmt) != GIMPLE_DEBUG)
834 hash_stmt (&hstate, stmt);
835 nondbg_stmt_count++;
839 gcode_hash = hstate.end ();
840 bb_sizes.safe_push (nondbg_stmt_count);
842 /* Inserting basic block to hash table. */
843 sem_bb *semantic_bb = new sem_bb (bb, nondbg_stmt_count,
844 EDGE_COUNT (bb->preds) + EDGE_COUNT (bb->succs));
846 bb_sorted.safe_push (semantic_bb);
849 parse_tree_args ();
852 /* Improve accumulated hash for HSTATE based on a gimple statement STMT. */
854 void
855 sem_function::hash_stmt (inchash::hash *hstate, gimple stmt)
857 enum gimple_code code = gimple_code (stmt);
859 hstate->add_int (code);
861 if (code == GIMPLE_CALL)
863 /* Checking of argument. */
864 for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i)
866 tree argument = gimple_call_arg (stmt, i);
868 switch (TREE_CODE (argument))
870 case INTEGER_CST:
871 if (tree_fits_shwi_p (argument))
872 hstate->add_wide_int (tree_to_shwi (argument));
873 else if (tree_fits_uhwi_p (argument))
874 hstate->add_wide_int (tree_to_uhwi (argument));
875 break;
876 case REAL_CST:
877 REAL_VALUE_TYPE c;
878 HOST_WIDE_INT n;
880 c = TREE_REAL_CST (argument);
881 n = real_to_integer (&c);
883 hstate->add_wide_int (n);
884 break;
885 case ADDR_EXPR:
887 tree addr_operand = TREE_OPERAND (argument, 0);
889 if (TREE_CODE (addr_operand) == STRING_CST)
890 hstate->add (TREE_STRING_POINTER (addr_operand),
891 TREE_STRING_LENGTH (addr_operand));
892 break;
894 default:
895 break;
902 /* Return true if polymorphic comparison must be processed. */
904 bool
905 sem_function::compare_polymorphic_p (void)
907 return get_node ()->callees != NULL
908 || get_node ()->indirect_calls != NULL
909 || m_compared_func->get_node ()->callees != NULL
910 || m_compared_func->get_node ()->indirect_calls != NULL;
913 /* For a given call graph NODE, the function constructs new
914 semantic function item. */
916 sem_function *
917 sem_function::parse (cgraph_node *node, bitmap_obstack *stack)
919 tree fndecl = node->decl;
920 function *func = DECL_STRUCT_FUNCTION (fndecl);
922 /* TODO: add support for thunks and aliases. */
924 if (!func || !node->has_gimple_body_p ())
925 return NULL;
927 if (lookup_attribute_by_prefix ("omp ", DECL_ATTRIBUTES (node->decl)) != NULL)
928 return NULL;
930 sem_function *f = new sem_function (node, 0, stack);
932 f->init ();
934 return f;
937 /* Parses function arguments and result type. */
939 void
940 sem_function::parse_tree_args (void)
942 tree result;
944 if (arg_types.exists ())
945 arg_types.release ();
947 arg_types.create (4);
948 tree fnargs = DECL_ARGUMENTS (decl);
950 for (tree parm = fnargs; parm; parm = DECL_CHAIN (parm))
951 arg_types.safe_push (DECL_ARG_TYPE (parm));
953 /* Function result type. */
954 result = DECL_RESULT (decl);
955 result_type = result ? TREE_TYPE (result) : NULL;
957 /* During WPA, we can get arguments by following method. */
958 if (!fnargs)
960 tree type = TYPE_ARG_TYPES (TREE_TYPE (decl));
961 for (tree parm = type; parm; parm = TREE_CHAIN (parm))
962 arg_types.safe_push (TYPE_CANONICAL (TREE_VALUE (parm)));
964 result_type = TREE_TYPE (TREE_TYPE (decl));
968 /* For given basic blocks BB1 and BB2 (from functions FUNC1 and FUNC),
969 return true if phi nodes are semantically equivalent in these blocks . */
971 bool
972 sem_function::compare_phi_node (basic_block bb1, basic_block bb2)
974 gphi_iterator si1, si2;
975 gphi *phi1, *phi2;
976 unsigned size1, size2, i;
977 tree t1, t2;
978 edge e1, e2;
980 gcc_assert (bb1 != NULL);
981 gcc_assert (bb2 != NULL);
983 si2 = gsi_start_phis (bb2);
984 for (si1 = gsi_start_phis (bb1); !gsi_end_p (si1);
985 gsi_next (&si1))
987 gsi_next_nonvirtual_phi (&si1);
988 gsi_next_nonvirtual_phi (&si2);
990 if (gsi_end_p (si1) && gsi_end_p (si2))
991 break;
993 if (gsi_end_p (si1) || gsi_end_p (si2))
994 return return_false();
996 phi1 = si1.phi ();
997 phi2 = si2.phi ();
999 tree phi_result1 = gimple_phi_result (phi1);
1000 tree phi_result2 = gimple_phi_result (phi2);
1002 if (!m_checker->compare_operand (phi_result1, phi_result2))
1003 return return_false_with_msg ("PHI results are different");
1005 size1 = gimple_phi_num_args (phi1);
1006 size2 = gimple_phi_num_args (phi2);
1008 if (size1 != size2)
1009 return return_false ();
1011 for (i = 0; i < size1; ++i)
1013 t1 = gimple_phi_arg (phi1, i)->def;
1014 t2 = gimple_phi_arg (phi2, i)->def;
1016 if (!m_checker->compare_operand (t1, t2))
1017 return return_false ();
1019 e1 = gimple_phi_arg_edge (phi1, i);
1020 e2 = gimple_phi_arg_edge (phi2, i);
1022 if (!m_checker->compare_edge (e1, e2))
1023 return return_false ();
1026 gsi_next (&si2);
1029 return true;
1032 /* Returns true if tree T can be compared as a handled component. */
1034 bool
1035 sem_function::icf_handled_component_p (tree t)
1037 tree_code tc = TREE_CODE (t);
1039 return ((handled_component_p (t))
1040 || tc == ADDR_EXPR || tc == MEM_REF || tc == REALPART_EXPR
1041 || tc == IMAGPART_EXPR || tc == OBJ_TYPE_REF);
1044 /* Basic blocks dictionary BB_DICT returns true if SOURCE index BB
1045 corresponds to TARGET. */
1047 bool
1048 sem_function::bb_dict_test (auto_vec<int> bb_dict, int source, int target)
1050 source++;
1051 target++;
1053 if (bb_dict.length () <= (unsigned)source)
1054 bb_dict.safe_grow_cleared (source + 1);
1056 if (bb_dict[source] == 0)
1058 bb_dict[source] = target;
1059 return true;
1061 else
1062 return bb_dict[source] == target;
1065 /* Iterates all tree types in T1 and T2 and returns true if all types
1066 are compatible. If COMPARE_POLYMORPHIC is set to true,
1067 more strict comparison is executed. */
1069 bool
1070 sem_function::compare_type_list (tree t1, tree t2, bool compare_polymorphic)
1072 tree tv1, tv2;
1073 tree_code tc1, tc2;
1075 if (!t1 && !t2)
1076 return true;
1078 while (t1 != NULL && t2 != NULL)
1080 tv1 = TREE_VALUE (t1);
1081 tv2 = TREE_VALUE (t2);
1083 tc1 = TREE_CODE (tv1);
1084 tc2 = TREE_CODE (tv2);
1086 if (tc1 == NOP_EXPR && tc2 == NOP_EXPR)
1088 else if (tc1 == NOP_EXPR || tc2 == NOP_EXPR)
1089 return false;
1090 else if (!func_checker::compatible_types_p (tv1, tv2, compare_polymorphic))
1091 return false;
1093 t1 = TREE_CHAIN (t1);
1094 t2 = TREE_CHAIN (t2);
1097 return !(t1 || t2);
1101 /* Semantic variable constructor that uses STACK as bitmap memory stack. */
1103 sem_variable::sem_variable (bitmap_obstack *stack): sem_item (VAR, stack)
1107 /* Constructor based on varpool node _NODE with computed hash _HASH.
1108 Bitmap STACK is used for memory allocation. */
1110 sem_variable::sem_variable (varpool_node *node, hashval_t _hash,
1111 bitmap_obstack *stack): sem_item(VAR,
1112 node, _hash, stack)
1114 gcc_checking_assert (node);
1115 gcc_checking_assert (get_node ());
1118 /* Returns true if the item equals to ITEM given as argument. */
1120 bool
1121 sem_variable::equals (sem_item *item,
1122 hash_map <symtab_node *, sem_item *> & ARG_UNUSED (ignored_nodes))
1124 gcc_assert (item->type == VAR);
1126 sem_variable *v = static_cast<sem_variable *>(item);
1128 if (!ctor || !v->ctor)
1129 return return_false_with_msg ("ctor is missing for semantic variable");
1131 return sem_variable::equals (ctor, v->ctor);
1134 /* Compares trees T1 and T2 for semantic equality. */
1136 bool
1137 sem_variable::equals (tree t1, tree t2)
1139 tree_code tc1 = TREE_CODE (t1);
1140 tree_code tc2 = TREE_CODE (t2);
1142 if (tc1 != tc2)
1143 return false;
1145 switch (tc1)
1147 case CONSTRUCTOR:
1149 unsigned len1 = vec_safe_length (CONSTRUCTOR_ELTS (t1));
1150 unsigned len2 = vec_safe_length (CONSTRUCTOR_ELTS (t2));
1152 if (len1 != len2)
1153 return false;
1155 for (unsigned i = 0; i < len1; i++)
1156 if (!sem_variable::equals (CONSTRUCTOR_ELT (t1, i)->value,
1157 CONSTRUCTOR_ELT (t2, i)->value)
1158 || CONSTRUCTOR_ELT (t1, i)->index != CONSTRUCTOR_ELT (t2, i)->index)
1159 return false;
1161 return true;
1163 case MEM_REF:
1165 tree x1 = TREE_OPERAND (t1, 0);
1166 tree x2 = TREE_OPERAND (t2, 0);
1167 tree y1 = TREE_OPERAND (t1, 1);
1168 tree y2 = TREE_OPERAND (t2, 1);
1170 if (!func_checker::compatible_types_p (TREE_TYPE (x1), TREE_TYPE (x2),
1171 true))
1172 return return_false ();
1174 /* Type of the offset on MEM_REF does not matter. */
1175 return sem_variable::equals (x1, x2)
1176 && wi::to_offset (y1) == wi::to_offset (y2);
1178 case NOP_EXPR:
1179 case ADDR_EXPR:
1181 tree op1 = TREE_OPERAND (t1, 0);
1182 tree op2 = TREE_OPERAND (t2, 0);
1183 return sem_variable::equals (op1, op2);
1185 case FUNCTION_DECL:
1186 case VAR_DECL:
1187 case FIELD_DECL:
1188 case LABEL_DECL:
1189 return t1 == t2;
1190 case INTEGER_CST:
1191 return func_checker::compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2),
1192 true)
1193 && wi::to_offset (t1) == wi::to_offset (t2);
1194 case STRING_CST:
1195 case REAL_CST:
1196 case COMPLEX_CST:
1197 return operand_equal_p (t1, t2, OEP_ONLY_CONST);
1198 case COMPONENT_REF:
1199 case ARRAY_REF:
1200 case POINTER_PLUS_EXPR:
1202 tree x1 = TREE_OPERAND (t1, 0);
1203 tree x2 = TREE_OPERAND (t2, 0);
1204 tree y1 = TREE_OPERAND (t1, 1);
1205 tree y2 = TREE_OPERAND (t2, 1);
1207 return sem_variable::equals (x1, x2) && sem_variable::equals (y1, y2);
1209 case ERROR_MARK:
1210 return return_false_with_msg ("ERROR_MARK");
1211 default:
1212 return return_false_with_msg ("Unknown TREE code reached");
1216 /* Parser function that visits a varpool NODE. */
1218 sem_variable *
1219 sem_variable::parse (varpool_node *node, bitmap_obstack *stack)
1221 tree decl = node->decl;
1223 bool readonly = TYPE_P (decl) ? TYPE_READONLY (decl) : TREE_READONLY (decl);
1224 if (!readonly)
1225 return NULL;
1227 bool can_handle = DECL_VIRTUAL_P (decl)
1228 || flag_merge_constants >= 2
1229 || (!TREE_ADDRESSABLE (decl) && !node->externally_visible);
1231 if (!can_handle || DECL_EXTERNAL (decl))
1232 return NULL;
1234 tree ctor = ctor_for_folding (decl);
1235 if (!ctor)
1236 return NULL;
1238 sem_variable *v = new sem_variable (node, 0, stack);
1240 v->init ();
1242 return v;
1245 /* References independent hash function. */
1247 hashval_t
1248 sem_variable::get_hash (void)
1250 if (hash)
1251 return hash;
1253 inchash::hash hstate;
1255 hstate.add_int (456346417);
1256 hstate.add_int (TREE_CODE (ctor));
1258 if (TREE_CODE (ctor) == CONSTRUCTOR)
1260 unsigned length = vec_safe_length (CONSTRUCTOR_ELTS (ctor));
1261 hstate.add_int (length);
1264 hash = hstate.end ();
1266 return hash;
1269 /* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can
1270 be applied. */
1272 bool
1273 sem_variable::merge (sem_item *alias_item)
1275 gcc_assert (alias_item->type == VAR);
1277 if (!sem_item::target_supports_symbol_aliases_p ())
1279 if (dump_file)
1280 fprintf (dump_file, "Symbol aliases are not supported by target\n\n");
1281 return false;
1284 sem_variable *alias_var = static_cast<sem_variable *> (alias_item);
1286 varpool_node *original = get_node ();
1287 varpool_node *alias = alias_var->get_node ();
1288 bool original_discardable = false;
1290 /* See if original is in a section that can be discarded if the main
1291 symbol is not used. */
1292 if (DECL_EXTERNAL (original->decl))
1293 original_discardable = true;
1294 if (original->resolution == LDPR_PREEMPTED_REG
1295 || original->resolution == LDPR_PREEMPTED_IR)
1296 original_discardable = true;
1297 if (original->can_be_discarded_p ())
1298 original_discardable = true;
1300 gcc_assert (!TREE_ASM_WRITTEN (alias->decl));
1302 if (original_discardable || DECL_EXTERNAL (alias_var->decl) ||
1303 !compare_sections (alias_var))
1305 if (dump_file)
1306 fprintf (dump_file, "Varpool alias cannot be created\n\n");
1308 return false;
1310 else
1312 // alias cycle creation check
1313 varpool_node *n = original;
1315 while (n->alias)
1317 n = n->get_alias_target ();
1318 if (n == alias)
1320 if (dump_file)
1321 fprintf (dump_file, "Varpool alias cannot be created (alias cycle).\n\n");
1323 return false;
1327 alias->analyzed = false;
1329 DECL_INITIAL (alias->decl) = NULL;
1330 alias->need_bounds_init = false;
1331 alias->remove_all_references ();
1333 varpool_node::create_alias (alias_var->decl, decl);
1334 alias->resolve_alias (original);
1336 if (dump_file)
1337 fprintf (dump_file, "Varpool alias has been created.\n\n");
1339 return true;
1343 bool
1344 sem_variable::compare_sections (sem_variable *alias)
1346 const char *source = node->get_section ();
1347 const char *target = alias->node->get_section();
1349 if (source == NULL && target == NULL)
1350 return true;
1351 else if(!source || !target)
1352 return false;
1353 else
1354 return strcmp (source, target) == 0;
1357 /* Dump symbol to FILE. */
1359 void
1360 sem_variable::dump_to_file (FILE *file)
1362 gcc_assert (file);
1364 print_node (file, "", decl, 0);
1365 fprintf (file, "\n\n");
1368 /* Iterates though a constructor and identifies tree references
1369 we are interested in semantic function equality. */
1371 void
1372 sem_variable::parse_tree_refs (tree t)
1374 switch (TREE_CODE (t))
1376 case CONSTRUCTOR:
1378 unsigned length = vec_safe_length (CONSTRUCTOR_ELTS (t));
1380 for (unsigned i = 0; i < length; i++)
1381 parse_tree_refs(CONSTRUCTOR_ELT (t, i)->value);
1383 break;
1385 case NOP_EXPR:
1386 case ADDR_EXPR:
1388 tree op = TREE_OPERAND (t, 0);
1389 parse_tree_refs (op);
1390 break;
1392 case FUNCTION_DECL:
1394 tree_refs.safe_push (t);
1395 break;
1397 default:
1398 break;
1402 unsigned int sem_item_optimizer::class_id = 0;
1404 sem_item_optimizer::sem_item_optimizer (): worklist (0), m_classes (0),
1405 m_classes_count (0), m_cgraph_node_hooks (NULL), m_varpool_node_hooks (NULL)
1407 m_items.create (0);
1408 bitmap_obstack_initialize (&m_bmstack);
1411 sem_item_optimizer::~sem_item_optimizer ()
1413 for (unsigned int i = 0; i < m_items.length (); i++)
1414 delete m_items[i];
1416 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
1417 it != m_classes.end (); ++it)
1419 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
1420 delete (*it)->classes[i];
1422 (*it)->classes.release ();
1423 free (*it);
1426 m_items.release ();
1428 bitmap_obstack_release (&m_bmstack);
1431 /* Write IPA ICF summary for symbols. */
1433 void
1434 sem_item_optimizer::write_summary (void)
1436 unsigned int count = 0;
1438 output_block *ob = create_output_block (LTO_section_ipa_icf);
1439 lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
1440 ob->symbol = NULL;
1442 /* Calculate number of symbols to be serialized. */
1443 for (lto_symtab_encoder_iterator lsei = lsei_start_in_partition (encoder);
1444 !lsei_end_p (lsei);
1445 lsei_next_in_partition (&lsei))
1447 symtab_node *node = lsei_node (lsei);
1449 if (m_symtab_node_map.get (node))
1450 count++;
1453 streamer_write_uhwi (ob, count);
1455 /* Process all of the symbols. */
1456 for (lto_symtab_encoder_iterator lsei = lsei_start_in_partition (encoder);
1457 !lsei_end_p (lsei);
1458 lsei_next_in_partition (&lsei))
1460 symtab_node *node = lsei_node (lsei);
1462 sem_item **item = m_symtab_node_map.get (node);
1464 if (item && *item)
1466 int node_ref = lto_symtab_encoder_encode (encoder, node);
1467 streamer_write_uhwi_stream (ob->main_stream, node_ref);
1469 streamer_write_uhwi (ob, (*item)->get_hash ());
1473 streamer_write_char_stream (ob->main_stream, 0);
1474 produce_asm (ob, NULL);
1475 destroy_output_block (ob);
1478 /* Reads a section from LTO stream file FILE_DATA. Input block for DATA
1479 contains LEN bytes. */
1481 void
1482 sem_item_optimizer::read_section (lto_file_decl_data *file_data,
1483 const char *data, size_t len)
1485 const lto_function_header *header =
1486 (const lto_function_header *) data;
1487 const int cfg_offset = sizeof (lto_function_header);
1488 const int main_offset = cfg_offset + header->cfg_size;
1489 const int string_offset = main_offset + header->main_size;
1490 data_in *data_in;
1491 unsigned int i;
1492 unsigned int count;
1494 lto_input_block ib_main ((const char *) data + main_offset, 0,
1495 header->main_size);
1497 data_in =
1498 lto_data_in_create (file_data, (const char *) data + string_offset,
1499 header->string_size, vNULL);
1501 count = streamer_read_uhwi (&ib_main);
1503 for (i = 0; i < count; i++)
1505 unsigned int index;
1506 symtab_node *node;
1507 lto_symtab_encoder_t encoder;
1509 index = streamer_read_uhwi (&ib_main);
1510 encoder = file_data->symtab_node_encoder;
1511 node = lto_symtab_encoder_deref (encoder, index);
1513 hashval_t hash = streamer_read_uhwi (&ib_main);
1515 gcc_assert (node->definition);
1517 if (dump_file)
1518 fprintf (dump_file, "Symbol added:%s (tree: %p, uid:%u)\n", node->asm_name (),
1519 (void *) node->decl, node->order);
1521 if (is_a<cgraph_node *> (node))
1523 cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
1525 m_items.safe_push (new sem_function (cnode, hash, &m_bmstack));
1527 else
1529 varpool_node *vnode = dyn_cast <varpool_node *> (node);
1531 m_items.safe_push (new sem_variable (vnode, hash, &m_bmstack));
1535 lto_free_section_data (file_data, LTO_section_ipa_icf, NULL, data,
1536 len);
1537 lto_data_in_delete (data_in);
1540 /* Read IPA IPA ICF summary for symbols. */
1542 void
1543 sem_item_optimizer::read_summary (void)
1545 lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
1546 lto_file_decl_data *file_data;
1547 unsigned int j = 0;
1549 while ((file_data = file_data_vec[j++]))
1551 size_t len;
1552 const char *data = lto_get_section_data (file_data,
1553 LTO_section_ipa_icf, NULL, &len);
1555 if (data)
1556 read_section (file_data, data, len);
1560 /* Register callgraph and varpool hooks. */
1562 void
1563 sem_item_optimizer::register_hooks (void)
1565 m_cgraph_node_hooks = symtab->add_cgraph_removal_hook
1566 (&sem_item_optimizer::cgraph_removal_hook, this);
1568 m_varpool_node_hooks = symtab->add_varpool_removal_hook
1569 (&sem_item_optimizer::varpool_removal_hook, this);
1572 /* Unregister callgraph and varpool hooks. */
1574 void
1575 sem_item_optimizer::unregister_hooks (void)
1577 if (m_cgraph_node_hooks)
1578 symtab->remove_cgraph_removal_hook (m_cgraph_node_hooks);
1580 if (m_varpool_node_hooks)
1581 symtab->remove_varpool_removal_hook (m_varpool_node_hooks);
1584 /* Adds a CLS to hashtable associated by hash value. */
1586 void
1587 sem_item_optimizer::add_class (congruence_class *cls)
1589 gcc_assert (cls->members.length ());
1591 congruence_class_group *group = get_group_by_hash (
1592 cls->members[0]->get_hash (),
1593 cls->members[0]->type);
1594 group->classes.safe_push (cls);
1597 /* Gets a congruence class group based on given HASH value and TYPE. */
1599 congruence_class_group *
1600 sem_item_optimizer::get_group_by_hash (hashval_t hash, sem_item_type type)
1602 congruence_class_group *item = XNEW (congruence_class_group);
1603 item->hash = hash;
1604 item->type = type;
1606 congruence_class_group **slot = m_classes.find_slot (item, INSERT);
1608 if (*slot)
1609 free (item);
1610 else
1612 item->classes.create (1);
1613 *slot = item;
1616 return *slot;
1619 /* Callgraph removal hook called for a NODE with a custom DATA. */
1621 void
1622 sem_item_optimizer::cgraph_removal_hook (cgraph_node *node, void *data)
1624 sem_item_optimizer *optimizer = (sem_item_optimizer *) data;
1625 optimizer->remove_symtab_node (node);
1628 /* Varpool removal hook called for a NODE with a custom DATA. */
1630 void
1631 sem_item_optimizer::varpool_removal_hook (varpool_node *node, void *data)
1633 sem_item_optimizer *optimizer = (sem_item_optimizer *) data;
1634 optimizer->remove_symtab_node (node);
1637 /* Remove symtab NODE triggered by symtab removal hooks. */
1639 void
1640 sem_item_optimizer::remove_symtab_node (symtab_node *node)
1642 gcc_assert (!m_classes.elements());
1644 m_removed_items_set.add (node);
1647 void
1648 sem_item_optimizer::remove_item (sem_item *item)
1650 if (m_symtab_node_map.get (item->node))
1651 m_symtab_node_map.remove (item->node);
1652 delete item;
1655 /* Removes all callgraph and varpool nodes that are marked by symtab
1656 as deleted. */
1658 void
1659 sem_item_optimizer::filter_removed_items (void)
1661 auto_vec <sem_item *> filtered;
1663 for (unsigned int i = 0; i < m_items.length(); i++)
1665 sem_item *item = m_items[i];
1667 if (m_removed_items_set.contains (item->node))
1669 remove_item (item);
1670 continue;
1673 if (item->type == FUNC)
1675 cgraph_node *cnode = static_cast <sem_function *>(item)->get_node ();
1677 bool no_body_function = in_lto_p && (cnode->alias || cnode->body_removed);
1678 if (no_body_function || !opt_for_fn (item->decl, flag_ipa_icf_functions)
1679 || DECL_CXX_CONSTRUCTOR_P (item->decl)
1680 || DECL_CXX_DESTRUCTOR_P (item->decl))
1681 remove_item (item);
1682 else
1683 filtered.safe_push (item);
1685 else /* VAR. */
1687 if (!flag_ipa_icf_variables)
1688 remove_item (item);
1689 else
1690 filtered.safe_push (item);
1694 /* Clean-up of released semantic items. */
1696 m_items.release ();
1697 for (unsigned int i = 0; i < filtered.length(); i++)
1698 m_items.safe_push (filtered[i]);
1701 /* Optimizer entry point. */
1703 void
1704 sem_item_optimizer::execute (void)
1706 filter_removed_items ();
1707 build_hash_based_classes ();
1709 if (dump_file)
1710 fprintf (dump_file, "Dump after hash based groups\n");
1711 dump_cong_classes ();
1713 for (unsigned int i = 0; i < m_items.length(); i++)
1714 m_items[i]->init_wpa ();
1716 build_graph ();
1718 subdivide_classes_by_equality (true);
1720 if (dump_file)
1721 fprintf (dump_file, "Dump after WPA based types groups\n");
1723 dump_cong_classes ();
1725 process_cong_reduction ();
1726 verify_classes ();
1728 if (dump_file)
1729 fprintf (dump_file, "Dump after callgraph-based congruence reduction\n");
1731 dump_cong_classes ();
1733 parse_nonsingleton_classes ();
1734 subdivide_classes_by_equality ();
1736 if (dump_file)
1737 fprintf (dump_file, "Dump after full equality comparison of groups\n");
1739 dump_cong_classes ();
1741 unsigned int prev_class_count = m_classes_count;
1743 process_cong_reduction ();
1744 dump_cong_classes ();
1745 verify_classes ();
1746 merge_classes (prev_class_count);
1748 if (dump_file && (dump_flags & TDF_DETAILS))
1749 symtab_node::dump_table (dump_file);
1752 /* Function responsible for visiting all potential functions and
1753 read-only variables that can be merged. */
1755 void
1756 sem_item_optimizer::parse_funcs_and_vars (void)
1758 cgraph_node *cnode;
1760 if (flag_ipa_icf_functions)
1761 FOR_EACH_DEFINED_FUNCTION (cnode)
1763 sem_function *f = sem_function::parse (cnode, &m_bmstack);
1764 if (f)
1766 m_items.safe_push (f);
1767 m_symtab_node_map.put (cnode, f);
1769 if (dump_file)
1770 fprintf (dump_file, "Parsed function:%s\n", f->asm_name ());
1772 if (dump_file && (dump_flags & TDF_DETAILS))
1773 f->dump_to_file (dump_file);
1775 else if (dump_file)
1776 fprintf (dump_file, "Not parsed function:%s\n", cnode->asm_name ());
1779 varpool_node *vnode;
1781 if (flag_ipa_icf_variables)
1782 FOR_EACH_DEFINED_VARIABLE (vnode)
1784 sem_variable *v = sem_variable::parse (vnode, &m_bmstack);
1786 if (v)
1788 m_items.safe_push (v);
1789 m_symtab_node_map.put (vnode, v);
1794 /* Makes pairing between a congruence class CLS and semantic ITEM. */
1796 void
1797 sem_item_optimizer::add_item_to_class (congruence_class *cls, sem_item *item)
1799 item->index_in_class = cls->members.length ();
1800 cls->members.safe_push (item);
1801 item->cls = cls;
1804 /* Congruence classes are built by hash value. */
1806 void
1807 sem_item_optimizer::build_hash_based_classes (void)
1809 for (unsigned i = 0; i < m_items.length (); i++)
1811 sem_item *item = m_items[i];
1813 congruence_class_group *group = get_group_by_hash (item->get_hash (),
1814 item->type);
1816 if (!group->classes.length ())
1818 m_classes_count++;
1819 group->classes.safe_push (new congruence_class (class_id++));
1822 add_item_to_class (group->classes[0], item);
1826 /* Build references according to call graph. */
1828 void
1829 sem_item_optimizer::build_graph (void)
1831 for (unsigned i = 0; i < m_items.length (); i++)
1833 sem_item *item = m_items[i];
1834 m_symtab_node_map.put (item->node, item);
1837 for (unsigned i = 0; i < m_items.length (); i++)
1839 sem_item *item = m_items[i];
1841 if (item->type == FUNC)
1843 cgraph_node *cnode = dyn_cast <cgraph_node *> (item->node);
1845 cgraph_edge *e = cnode->callees;
1846 while (e)
1848 sem_item **slot = m_symtab_node_map.get (e->callee);
1849 if (slot)
1850 item->add_reference (*slot);
1852 e = e->next_callee;
1856 ipa_ref *ref = NULL;
1857 for (unsigned i = 0; item->node->iterate_reference (i, ref); i++)
1859 sem_item **slot = m_symtab_node_map.get (ref->referred);
1860 if (slot)
1861 item->add_reference (*slot);
1866 /* Semantic items in classes having more than one element and initialized.
1867 In case of WPA, we load function body. */
1869 void
1870 sem_item_optimizer::parse_nonsingleton_classes (void)
1872 unsigned int init_called_count = 0;
1874 for (unsigned i = 0; i < m_items.length (); i++)
1875 if (m_items[i]->cls->members.length () > 1)
1877 m_items[i]->init ();
1878 init_called_count++;
1881 if (dump_file)
1882 fprintf (dump_file, "Init called for %u items (%.2f%%).\n", init_called_count,
1883 m_items.length () ? 100.0f * init_called_count / m_items.length (): 0.0f);
1886 /* Equality function for semantic items is used to subdivide existing
1887 classes. If IN_WPA, fast equality function is invoked. */
1889 void
1890 sem_item_optimizer::subdivide_classes_by_equality (bool in_wpa)
1892 for (hash_table <congruence_class_group_hash>::iterator it = m_classes.begin ();
1893 it != m_classes.end (); ++it)
1895 unsigned int class_count = (*it)->classes.length ();
1897 for (unsigned i = 0; i < class_count; i++)
1899 congruence_class *c = (*it)->classes [i];
1901 if (c->members.length() > 1)
1903 auto_vec <sem_item *> new_vector;
1905 sem_item *first = c->members[0];
1906 new_vector.safe_push (first);
1908 unsigned class_split_first = (*it)->classes.length ();
1910 for (unsigned j = 1; j < c->members.length (); j++)
1912 sem_item *item = c->members[j];
1914 bool equals = in_wpa ? first->equals_wpa (item,
1915 m_symtab_node_map) : first->equals (item, m_symtab_node_map);
1917 if (equals)
1918 new_vector.safe_push (item);
1919 else
1921 bool integrated = false;
1923 for (unsigned k = class_split_first; k < (*it)->classes.length (); k++)
1925 sem_item *x = (*it)->classes[k]->members[0];
1926 bool equals = in_wpa ? x->equals_wpa (item,
1927 m_symtab_node_map) : x->equals (item, m_symtab_node_map);
1929 if (equals)
1931 integrated = true;
1932 add_item_to_class ((*it)->classes[k], item);
1934 break;
1938 if (!integrated)
1940 congruence_class *c = new congruence_class (class_id++);
1941 m_classes_count++;
1942 add_item_to_class (c, item);
1944 (*it)->classes.safe_push (c);
1949 // we replace newly created new_vector for the class we've just splitted
1950 c->members.release ();
1951 c->members.create (new_vector.length ());
1953 for (unsigned int j = 0; j < new_vector.length (); j++)
1954 add_item_to_class (c, new_vector[j]);
1959 verify_classes ();
1962 /* Verify congruence classes if checking is enabled. */
1964 void
1965 sem_item_optimizer::verify_classes (void)
1967 #if ENABLE_CHECKING
1968 for (hash_table <congruence_class_group_hash>::iterator it = m_classes.begin ();
1969 it != m_classes.end (); ++it)
1971 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
1973 congruence_class *cls = (*it)->classes[i];
1975 gcc_checking_assert (cls);
1976 gcc_checking_assert (cls->members.length () > 0);
1978 for (unsigned int j = 0; j < cls->members.length (); j++)
1980 sem_item *item = cls->members[j];
1982 gcc_checking_assert (item);
1983 gcc_checking_assert (item->cls == cls);
1985 for (unsigned k = 0; k < item->usages.length (); k++)
1987 sem_usage_pair *usage = item->usages[k];
1988 gcc_checking_assert (usage->item->index_in_class <
1989 usage->item->cls->members.length ());
1994 #endif
1997 /* Disposes split map traverse function. CLS_PTR is pointer to congruence
1998 class, BSLOT is bitmap slot we want to release. DATA is mandatory,
1999 but unused argument. */
2001 bool
2002 sem_item_optimizer::release_split_map (congruence_class * const &,
2003 bitmap const &b, traverse_split_pair *)
2005 bitmap bmp = b;
2007 BITMAP_FREE (bmp);
2009 return true;
2012 /* Process split operation for a class given as pointer CLS_PTR,
2013 where bitmap B splits congruence class members. DATA is used
2014 as argument of split pair. */
2016 bool
2017 sem_item_optimizer::traverse_congruence_split (congruence_class * const &cls,
2018 bitmap const &b, traverse_split_pair *pair)
2020 sem_item_optimizer *optimizer = pair->optimizer;
2021 const congruence_class *splitter_cls = pair->cls;
2023 /* If counted bits are greater than zero and less than the number of members
2024 a group will be splitted. */
2025 unsigned popcount = bitmap_count_bits (b);
2027 if (popcount > 0 && popcount < cls->members.length ())
2029 congruence_class* newclasses[2] = { new congruence_class (class_id++), new congruence_class (class_id++) };
2031 for (unsigned int i = 0; i < cls->members.length (); i++)
2033 int target = bitmap_bit_p (b, i);
2034 congruence_class *tc = newclasses[target];
2036 add_item_to_class (tc, cls->members[i]);
2039 #ifdef ENABLE_CHECKING
2040 for (unsigned int i = 0; i < 2; i++)
2041 gcc_checking_assert (newclasses[i]->members.length ());
2042 #endif
2044 if (splitter_cls == cls)
2045 optimizer->splitter_class_removed = true;
2047 /* Remove old class from worklist if presented. */
2048 bool in_worklist = cls->in_worklist;
2050 if (in_worklist)
2051 cls->in_worklist = false;
2053 congruence_class_group g;
2054 g.hash = cls->members[0]->get_hash ();
2055 g.type = cls->members[0]->type;
2057 congruence_class_group *slot = optimizer->m_classes.find(&g);
2059 for (unsigned int i = 0; i < slot->classes.length (); i++)
2060 if (slot->classes[i] == cls)
2062 slot->classes.ordered_remove (i);
2063 break;
2066 /* New class will be inserted and integrated to work list. */
2067 for (unsigned int i = 0; i < 2; i++)
2068 optimizer->add_class (newclasses[i]);
2070 /* Two classes replace one, so that increment just by one. */
2071 optimizer->m_classes_count++;
2073 /* If OLD class was presented in the worklist, we remove the class
2074 and replace it will both newly created classes. */
2075 if (in_worklist)
2076 for (unsigned int i = 0; i < 2; i++)
2077 optimizer->worklist_push (newclasses[i]);
2078 else /* Just smaller class is inserted. */
2080 unsigned int smaller_index = newclasses[0]->members.length () <
2081 newclasses[1]->members.length () ?
2082 0 : 1;
2083 optimizer->worklist_push (newclasses[smaller_index]);
2086 if (dump_file && (dump_flags & TDF_DETAILS))
2088 fprintf (dump_file, " congruence class splitted:\n");
2089 cls->dump (dump_file, 4);
2091 fprintf (dump_file, " newly created groups:\n");
2092 for (unsigned int i = 0; i < 2; i++)
2093 newclasses[i]->dump (dump_file, 4);
2096 /* Release class if not presented in work list. */
2097 if (!in_worklist)
2098 delete cls;
2102 return true;
2105 /* Tests if a class CLS used as INDEXth splits any congruence classes.
2106 Bitmap stack BMSTACK is used for bitmap allocation. */
2108 void
2109 sem_item_optimizer::do_congruence_step_for_index (congruence_class *cls,
2110 unsigned int index)
2112 hash_map <congruence_class *, bitmap> split_map;
2114 for (unsigned int i = 0; i < cls->members.length (); i++)
2116 sem_item *item = cls->members[i];
2118 /* Iterate all usages that have INDEX as usage of the item. */
2119 for (unsigned int j = 0; j < item->usages.length (); j++)
2121 sem_usage_pair *usage = item->usages[j];
2123 if (usage->index != index)
2124 continue;
2126 bitmap *slot = split_map.get (usage->item->cls);
2127 bitmap b;
2129 if(!slot)
2131 b = BITMAP_ALLOC (&m_bmstack);
2132 split_map.put (usage->item->cls, b);
2134 else
2135 b = *slot;
2137 #if ENABLE_CHECKING
2138 gcc_checking_assert (usage->item->cls);
2139 gcc_checking_assert (usage->item->index_in_class <
2140 usage->item->cls->members.length ());
2141 #endif
2143 bitmap_set_bit (b, usage->item->index_in_class);
2147 traverse_split_pair pair;
2148 pair.optimizer = this;
2149 pair.cls = cls;
2151 splitter_class_removed = false;
2152 split_map.traverse
2153 <traverse_split_pair *, sem_item_optimizer::traverse_congruence_split> (&pair);
2155 /* Bitmap clean-up. */
2156 split_map.traverse
2157 <traverse_split_pair *, sem_item_optimizer::release_split_map> (NULL);
2160 /* Every usage of a congruence class CLS is a candidate that can split the
2161 collection of classes. Bitmap stack BMSTACK is used for bitmap
2162 allocation. */
2164 void
2165 sem_item_optimizer::do_congruence_step (congruence_class *cls)
2167 bitmap_iterator bi;
2168 unsigned int i;
2170 bitmap usage = BITMAP_ALLOC (&m_bmstack);
2172 for (unsigned int i = 0; i < cls->members.length (); i++)
2173 bitmap_ior_into (usage, cls->members[i]->usage_index_bitmap);
2175 EXECUTE_IF_SET_IN_BITMAP (usage, 0, i, bi)
2177 if (dump_file && (dump_flags & TDF_DETAILS))
2178 fprintf (dump_file, " processing congruece step for class: %u, index: %u\n",
2179 cls->id, i);
2181 do_congruence_step_for_index (cls, i);
2183 if (splitter_class_removed)
2184 break;
2187 BITMAP_FREE (usage);
2190 /* Adds a newly created congruence class CLS to worklist. */
2192 void
2193 sem_item_optimizer::worklist_push (congruence_class *cls)
2195 /* Return if the class CLS is already presented in work list. */
2196 if (cls->in_worklist)
2197 return;
2199 cls->in_worklist = true;
2200 worklist.push_back (cls);
2203 /* Pops a class from worklist. */
2205 congruence_class *
2206 sem_item_optimizer::worklist_pop (void)
2208 congruence_class *cls;
2210 while (!worklist.empty ())
2212 cls = worklist.front ();
2213 worklist.pop_front ();
2214 if (cls->in_worklist)
2216 cls->in_worklist = false;
2218 return cls;
2220 else
2222 /* Work list item was already intended to be removed.
2223 The only reason for doing it is to split a class.
2224 Thus, the class CLS is deleted. */
2225 delete cls;
2229 return NULL;
2232 /* Iterative congruence reduction function. */
2234 void
2235 sem_item_optimizer::process_cong_reduction (void)
2237 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2238 it != m_classes.end (); ++it)
2239 for (unsigned i = 0; i < (*it)->classes.length (); i++)
2240 if ((*it)->classes[i]->is_class_used ())
2241 worklist_push ((*it)->classes[i]);
2243 if (dump_file)
2244 fprintf (dump_file, "Worklist has been filled with: %lu\n",
2245 (unsigned long) worklist.size ());
2247 if (dump_file && (dump_flags & TDF_DETAILS))
2248 fprintf (dump_file, "Congruence class reduction\n");
2250 congruence_class *cls;
2251 while ((cls = worklist_pop ()) != NULL)
2252 do_congruence_step (cls);
2255 /* Debug function prints all informations about congruence classes. */
2257 void
2258 sem_item_optimizer::dump_cong_classes (void)
2260 if (!dump_file)
2261 return;
2263 fprintf (dump_file,
2264 "Congruence classes: %u (unique hash values: %lu), with total: %u items\n",
2265 m_classes_count, (unsigned long) m_classes.elements(), m_items.length ());
2267 /* Histogram calculation. */
2268 unsigned int max_index = 0;
2269 unsigned int* histogram = XCNEWVEC (unsigned int, m_items.length () + 1);
2271 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2272 it != m_classes.end (); ++it)
2274 for (unsigned i = 0; i < (*it)->classes.length (); i++)
2276 unsigned int c = (*it)->classes[i]->members.length ();
2277 histogram[c]++;
2279 if (c > max_index)
2280 max_index = c;
2283 fprintf (dump_file,
2284 "Class size histogram [num of members]: number of classe number of classess\n");
2286 for (unsigned int i = 0; i <= max_index; i++)
2287 if (histogram[i])
2288 fprintf (dump_file, "[%u]: %u classes\n", i, histogram[i]);
2290 fprintf (dump_file, "\n\n");
2293 if (dump_flags & TDF_DETAILS)
2294 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2295 it != m_classes.end (); ++it)
2297 fprintf (dump_file, " group: with %u classes:\n", (*it)->classes.length ());
2299 for (unsigned i = 0; i < (*it)->classes.length (); i++)
2301 (*it)->classes[i]->dump (dump_file, 4);
2303 if(i < (*it)->classes.length () - 1)
2304 fprintf (dump_file, " ");
2308 free (histogram);
2311 /* After reduction is done, we can declare all items in a group
2312 to be equal. PREV_CLASS_COUNT is start number of classes
2313 before reduction. */
2315 void
2316 sem_item_optimizer::merge_classes (unsigned int prev_class_count)
2318 unsigned int item_count = m_items.length ();
2319 unsigned int class_count = m_classes_count;
2320 unsigned int equal_items = item_count - class_count;
2322 unsigned int non_singular_classes_count = 0;
2323 unsigned int non_singular_classes_sum = 0;
2325 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2326 it != m_classes.end (); ++it)
2327 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
2329 congruence_class *c = (*it)->classes[i];
2330 if (c->members.length () > 1)
2332 non_singular_classes_count++;
2333 non_singular_classes_sum += c->members.length ();
2337 if (dump_file)
2339 fprintf (dump_file, "\nItem count: %u\n", item_count);
2340 fprintf (dump_file, "Congruent classes before: %u, after: %u\n",
2341 prev_class_count, class_count);
2342 fprintf (dump_file, "Average class size before: %.2f, after: %.2f\n",
2343 prev_class_count ? 1.0f * item_count / prev_class_count : 0.0f,
2344 class_count ? 1.0f * item_count / class_count : 0.0f);
2345 fprintf (dump_file, "Average non-singular class size: %.2f, count: %u\n",
2346 non_singular_classes_count ? 1.0f * non_singular_classes_sum /
2347 non_singular_classes_count : 0.0f,
2348 non_singular_classes_count);
2349 fprintf (dump_file, "Equal symbols: %u\n", equal_items);
2350 fprintf (dump_file, "Fraction of visited symbols: %.2f%%\n\n",
2351 item_count ? 100.0f * equal_items / item_count : 0.0f);
2354 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2355 it != m_classes.end (); ++it)
2356 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
2358 congruence_class *c = (*it)->classes[i];
2360 if (c->members.length () == 1)
2361 continue;
2363 gcc_assert (c->members.length ());
2365 sem_item *source = c->members[0];
2367 for (unsigned int j = 1; j < c->members.length (); j++)
2369 sem_item *alias = c->members[j];
2371 if (dump_file)
2373 fprintf (dump_file, "Semantic equality hit:%s->%s\n",
2374 source->name (), alias->name ());
2375 fprintf (dump_file, "Assembler symbol names:%s->%s\n",
2376 source->asm_name (), alias->asm_name ());
2379 if (lookup_attribute ("no_icf", DECL_ATTRIBUTES (alias->decl)))
2381 if (dump_file)
2382 fprintf (dump_file,
2383 "Merge operation is skipped due to no_icf "
2384 "attribute.\n\n");
2386 continue;
2389 if (dump_file && (dump_flags & TDF_DETAILS))
2391 source->dump_to_file (dump_file);
2392 alias->dump_to_file (dump_file);
2395 source->merge (alias);
2400 /* Dump function prints all class members to a FILE with an INDENT. */
2402 void
2403 congruence_class::dump (FILE *file, unsigned int indent) const
2405 FPRINTF_SPACES (file, indent, "class with id: %u, hash: %u, items: %u\n",
2406 id, members[0]->get_hash (), members.length ());
2408 FPUTS_SPACES (file, indent + 2, "");
2409 for (unsigned i = 0; i < members.length (); i++)
2410 fprintf (file, "%s(%p/%u) ", members[i]->asm_name (), (void *) members[i]->decl,
2411 members[i]->node->order);
2413 fprintf (file, "\n");
2416 /* Returns true if there's a member that is used from another group. */
2418 bool
2419 congruence_class::is_class_used (void)
2421 for (unsigned int i = 0; i < members.length (); i++)
2422 if (members[i]->usages.length ())
2423 return true;
2425 return false;
2428 /* Initialization and computation of symtab node hash, there data
2429 are propagated later on. */
2431 static sem_item_optimizer *optimizer = NULL;
2433 /* Generate pass summary for IPA ICF pass. */
2435 static void
2436 ipa_icf_generate_summary (void)
2438 if (!optimizer)
2439 optimizer = new sem_item_optimizer ();
2441 optimizer->parse_funcs_and_vars ();
2444 /* Write pass summary for IPA ICF pass. */
2446 static void
2447 ipa_icf_write_summary (void)
2449 gcc_assert (optimizer);
2451 optimizer->write_summary ();
2454 /* Read pass summary for IPA ICF pass. */
2456 static void
2457 ipa_icf_read_summary (void)
2459 if (!optimizer)
2460 optimizer = new sem_item_optimizer ();
2462 optimizer->read_summary ();
2463 optimizer->register_hooks ();
2466 /* Semantic equality exection function. */
2468 static unsigned int
2469 ipa_icf_driver (void)
2471 gcc_assert (optimizer);
2473 optimizer->execute ();
2474 optimizer->unregister_hooks ();
2476 delete optimizer;
2477 optimizer = NULL;
2479 return 0;
2482 const pass_data pass_data_ipa_icf =
2484 IPA_PASS, /* type */
2485 "icf", /* name */
2486 OPTGROUP_IPA, /* optinfo_flags */
2487 TV_IPA_ICF, /* tv_id */
2488 0, /* properties_required */
2489 0, /* properties_provided */
2490 0, /* properties_destroyed */
2491 0, /* todo_flags_start */
2492 0, /* todo_flags_finish */
2495 class pass_ipa_icf : public ipa_opt_pass_d
2497 public:
2498 pass_ipa_icf (gcc::context *ctxt)
2499 : ipa_opt_pass_d (pass_data_ipa_icf, ctxt,
2500 ipa_icf_generate_summary, /* generate_summary */
2501 ipa_icf_write_summary, /* write_summary */
2502 ipa_icf_read_summary, /* read_summary */
2503 NULL, /*
2504 write_optimization_summary */
2505 NULL, /*
2506 read_optimization_summary */
2507 NULL, /* stmt_fixup */
2508 0, /* function_transform_todo_flags_start */
2509 NULL, /* function_transform */
2510 NULL) /* variable_transform */
2513 /* opt_pass methods: */
2514 virtual bool gate (function *)
2516 return in_lto_p || flag_ipa_icf_variables || flag_ipa_icf_functions;
2519 virtual unsigned int execute (function *)
2521 return ipa_icf_driver();
2523 }; // class pass_ipa_icf
2525 } // ipa_icf namespace
2527 ipa_opt_pass_d *
2528 make_pass_ipa_icf (gcc::context *ctxt)
2530 return new ipa_icf::pass_ipa_icf (ctxt);