2015-02-10 David Wohlferd <dw@LimeGreenSocks.com>
[official-gcc.git] / gcc / ipa-icf.c
blob692946ae7b1741b7c72ff647120451946ce56b21
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 /* Set LOCAL_P of NODE to true if DATA is non-NULL.
588 Helper for call_for_symbol_thunks_and_aliases. */
590 static bool
591 set_local (cgraph_node *node, void *data)
593 node->local.local = data != NULL;
594 return false;
597 /* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can
598 be applied. */
599 bool
600 sem_function::merge (sem_item *alias_item)
602 gcc_assert (alias_item->type == FUNC);
604 sem_function *alias_func = static_cast<sem_function *> (alias_item);
606 cgraph_node *original = get_node ();
607 cgraph_node *local_original = original;
608 cgraph_node *alias = alias_func->get_node ();
609 bool original_address_matters;
610 bool alias_address_matters;
612 bool create_thunk = false;
613 bool create_alias = false;
614 bool redirect_callers = false;
615 bool original_discardable = false;
617 /* Do not attempt to mix functions from different user sections;
618 we do not know what user intends with those. */
619 if (((DECL_SECTION_NAME (original->decl) && !original->implicit_section)
620 || (DECL_SECTION_NAME (alias->decl) && !alias->implicit_section))
621 && DECL_SECTION_NAME (original->decl) != DECL_SECTION_NAME (alias->decl))
623 if (dump_file)
624 fprintf (dump_file,
625 "Not unifying; original and alias are in different sections.\n\n");
626 return false;
629 /* See if original is in a section that can be discarded if the main
630 symbol is not used. */
631 if (DECL_EXTERNAL (original->decl))
632 original_discardable = true;
633 if (original->resolution == LDPR_PREEMPTED_REG
634 || original->resolution == LDPR_PREEMPTED_IR)
635 original_discardable = true;
636 if (original->can_be_discarded_p ())
637 original_discardable = true;
639 /* See if original and/or alias address can be compared for equality. */
640 original_address_matters
641 = (!DECL_VIRTUAL_P (original->decl)
642 && (original->externally_visible
643 || original->address_taken_from_non_vtable_p ()));
644 alias_address_matters
645 = (!DECL_VIRTUAL_P (alias->decl)
646 && (alias->externally_visible
647 || alias->address_taken_from_non_vtable_p ()));
649 /* If alias and original can be compared for address equality, we need
650 to create a thunk. Also we can not create extra aliases into discardable
651 section (or we risk link failures when section is discarded). */
652 if ((original_address_matters
653 && alias_address_matters)
654 || original_discardable)
656 create_thunk = !stdarg_p (TREE_TYPE (alias->decl));
657 create_alias = false;
658 /* When both alias and original are not overwritable, we can save
659 the extra thunk wrapper for direct calls. */
660 redirect_callers
661 = (!original_discardable
662 && alias->get_availability () > AVAIL_INTERPOSABLE
663 && original->get_availability () > AVAIL_INTERPOSABLE
664 && !alias->instrumented_version);
666 else
668 create_alias = true;
669 create_thunk = false;
670 redirect_callers = false;
673 if (create_alias && (DECL_COMDAT_GROUP (alias->decl)
674 || !sem_item::target_supports_symbol_aliases_p ()))
676 create_alias = false;
677 create_thunk = true;
680 /* We want thunk to always jump to the local function body
681 unless the body is comdat and may be optimized out. */
682 if ((create_thunk || redirect_callers)
683 && (!original_discardable
684 || (DECL_COMDAT_GROUP (original->decl)
685 && (DECL_COMDAT_GROUP (original->decl)
686 == DECL_COMDAT_GROUP (alias->decl)))))
687 local_original
688 = dyn_cast <cgraph_node *> (original->noninterposable_alias ());
690 if (!local_original)
692 if (dump_file)
693 fprintf (dump_file, "Noninterposable alias cannot be created.\n\n");
695 return false;
698 if (!decl_binds_to_current_def_p (alias->decl))
700 if (dump_file)
701 fprintf (dump_file, "Declaration does not bind to currect definition.\n\n");
702 return false;
705 if (redirect_callers)
707 /* If alias is non-overwritable then
708 all direct calls are safe to be redirected to the original. */
709 bool redirected = false;
710 while (alias->callers)
712 cgraph_edge *e = alias->callers;
713 e->redirect_callee (local_original);
714 push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
716 if (e->call_stmt)
717 e->redirect_call_stmt_to_callee ();
719 pop_cfun ();
720 redirected = true;
723 alias->icf_merged = true;
724 if (local_original->lto_file_data
725 && alias->lto_file_data
726 && local_original->lto_file_data != alias->lto_file_data)
727 local_original->merged = true;
729 /* The alias function is removed if symbol address
730 does not matter. */
731 if (!alias_address_matters)
732 alias->remove ();
734 if (dump_file && redirected)
735 fprintf (dump_file, "Callgraph local calls have been redirected.\n\n");
737 /* If the condtion above is not met, we are lucky and can turn the
738 function into real alias. */
739 else if (create_alias)
741 alias->icf_merged = true;
742 if (local_original->lto_file_data
743 && alias->lto_file_data
744 && local_original->lto_file_data != alias->lto_file_data)
745 local_original->merged = true;
747 /* Remove the function's body. */
748 ipa_merge_profiles (original, alias);
749 alias->release_body (true);
750 alias->reset ();
752 /* Create the alias. */
753 cgraph_node::create_alias (alias_func->decl, decl);
754 alias->resolve_alias (original);
756 original->call_for_symbol_thunks_and_aliases
757 (set_local, (void *)(size_t) original->local_p (), true);
759 if (dump_file)
760 fprintf (dump_file, "Callgraph alias has been created.\n\n");
762 else if (create_thunk)
764 if (DECL_COMDAT_GROUP (alias->decl))
766 if (dump_file)
767 fprintf (dump_file, "Callgraph thunk cannot be created because of COMDAT\n");
769 return 0;
772 if (DECL_STATIC_CHAIN (alias->decl))
774 if (dump_file)
775 fprintf (dump_file, "Thunk creation is risky for static-chain functions.\n\n");
777 return 0;
780 alias->icf_merged = true;
781 if (local_original->lto_file_data
782 && alias->lto_file_data
783 && local_original->lto_file_data != alias->lto_file_data)
784 local_original->merged = true;
785 ipa_merge_profiles (local_original, alias, true);
786 alias->create_wrapper (local_original);
788 if (dump_file)
789 fprintf (dump_file, "Callgraph thunk has been created.\n\n");
791 else if (dump_file)
792 fprintf (dump_file, "Callgraph merge operation cannot be performed.\n\n");
794 return true;
797 /* Semantic item initialization function. */
799 void
800 sem_function::init (void)
802 if (in_lto_p)
803 get_node ()->get_untransformed_body ();
805 tree fndecl = node->decl;
806 function *func = DECL_STRUCT_FUNCTION (fndecl);
808 gcc_assert (func);
809 gcc_assert (SSANAMES (func));
811 ssa_names_size = SSANAMES (func)->length ();
812 node = node;
814 decl = fndecl;
815 region_tree = func->eh->region_tree;
817 /* iterating all function arguments. */
818 arg_count = count_formal_params (fndecl);
820 edge_count = n_edges_for_fn (func);
821 cfg_checksum = coverage_compute_cfg_checksum (func);
823 inchash::hash hstate;
825 basic_block bb;
826 FOR_EACH_BB_FN (bb, func)
828 unsigned nondbg_stmt_count = 0;
830 edge e;
831 for (edge_iterator ei = ei_start (bb->preds); ei_cond (ei, &e); ei_next (&ei))
832 cfg_checksum = iterative_hash_host_wide_int (e->flags,
833 cfg_checksum);
835 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
836 gsi_next (&gsi))
838 gimple stmt = gsi_stmt (gsi);
840 if (gimple_code (stmt) != GIMPLE_DEBUG)
842 hash_stmt (&hstate, stmt);
843 nondbg_stmt_count++;
847 gcode_hash = hstate.end ();
848 bb_sizes.safe_push (nondbg_stmt_count);
850 /* Inserting basic block to hash table. */
851 sem_bb *semantic_bb = new sem_bb (bb, nondbg_stmt_count,
852 EDGE_COUNT (bb->preds) + EDGE_COUNT (bb->succs));
854 bb_sorted.safe_push (semantic_bb);
857 parse_tree_args ();
860 /* Improve accumulated hash for HSTATE based on a gimple statement STMT. */
862 void
863 sem_function::hash_stmt (inchash::hash *hstate, gimple stmt)
865 enum gimple_code code = gimple_code (stmt);
867 hstate->add_int (code);
869 if (code == GIMPLE_CALL)
871 /* Checking of argument. */
872 for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i)
874 tree argument = gimple_call_arg (stmt, i);
876 switch (TREE_CODE (argument))
878 case INTEGER_CST:
879 if (tree_fits_shwi_p (argument))
880 hstate->add_wide_int (tree_to_shwi (argument));
881 else if (tree_fits_uhwi_p (argument))
882 hstate->add_wide_int (tree_to_uhwi (argument));
883 break;
884 case REAL_CST:
885 REAL_VALUE_TYPE c;
886 HOST_WIDE_INT n;
888 c = TREE_REAL_CST (argument);
889 n = real_to_integer (&c);
891 hstate->add_wide_int (n);
892 break;
893 case ADDR_EXPR:
895 tree addr_operand = TREE_OPERAND (argument, 0);
897 if (TREE_CODE (addr_operand) == STRING_CST)
898 hstate->add (TREE_STRING_POINTER (addr_operand),
899 TREE_STRING_LENGTH (addr_operand));
900 break;
902 default:
903 break;
910 /* Return true if polymorphic comparison must be processed. */
912 bool
913 sem_function::compare_polymorphic_p (void)
915 return get_node ()->callees != NULL
916 || get_node ()->indirect_calls != NULL
917 || m_compared_func->get_node ()->callees != NULL
918 || m_compared_func->get_node ()->indirect_calls != NULL;
921 /* For a given call graph NODE, the function constructs new
922 semantic function item. */
924 sem_function *
925 sem_function::parse (cgraph_node *node, bitmap_obstack *stack)
927 tree fndecl = node->decl;
928 function *func = DECL_STRUCT_FUNCTION (fndecl);
930 /* TODO: add support for thunks and aliases. */
932 if (!func || !node->has_gimple_body_p ())
933 return NULL;
935 if (lookup_attribute_by_prefix ("omp ", DECL_ATTRIBUTES (node->decl)) != NULL)
936 return NULL;
938 sem_function *f = new sem_function (node, 0, stack);
940 f->init ();
942 return f;
945 /* Parses function arguments and result type. */
947 void
948 sem_function::parse_tree_args (void)
950 tree result;
952 if (arg_types.exists ())
953 arg_types.release ();
955 arg_types.create (4);
956 tree fnargs = DECL_ARGUMENTS (decl);
958 for (tree parm = fnargs; parm; parm = DECL_CHAIN (parm))
959 arg_types.safe_push (DECL_ARG_TYPE (parm));
961 /* Function result type. */
962 result = DECL_RESULT (decl);
963 result_type = result ? TREE_TYPE (result) : NULL;
965 /* During WPA, we can get arguments by following method. */
966 if (!fnargs)
968 tree type = TYPE_ARG_TYPES (TREE_TYPE (decl));
969 for (tree parm = type; parm; parm = TREE_CHAIN (parm))
970 arg_types.safe_push (TYPE_CANONICAL (TREE_VALUE (parm)));
972 result_type = TREE_TYPE (TREE_TYPE (decl));
976 /* For given basic blocks BB1 and BB2 (from functions FUNC1 and FUNC),
977 return true if phi nodes are semantically equivalent in these blocks . */
979 bool
980 sem_function::compare_phi_node (basic_block bb1, basic_block bb2)
982 gphi_iterator si1, si2;
983 gphi *phi1, *phi2;
984 unsigned size1, size2, i;
985 tree t1, t2;
986 edge e1, e2;
988 gcc_assert (bb1 != NULL);
989 gcc_assert (bb2 != NULL);
991 si2 = gsi_start_phis (bb2);
992 for (si1 = gsi_start_phis (bb1); !gsi_end_p (si1);
993 gsi_next (&si1))
995 gsi_next_nonvirtual_phi (&si1);
996 gsi_next_nonvirtual_phi (&si2);
998 if (gsi_end_p (si1) && gsi_end_p (si2))
999 break;
1001 if (gsi_end_p (si1) || gsi_end_p (si2))
1002 return return_false();
1004 phi1 = si1.phi ();
1005 phi2 = si2.phi ();
1007 tree phi_result1 = gimple_phi_result (phi1);
1008 tree phi_result2 = gimple_phi_result (phi2);
1010 if (!m_checker->compare_operand (phi_result1, phi_result2))
1011 return return_false_with_msg ("PHI results are different");
1013 size1 = gimple_phi_num_args (phi1);
1014 size2 = gimple_phi_num_args (phi2);
1016 if (size1 != size2)
1017 return return_false ();
1019 for (i = 0; i < size1; ++i)
1021 t1 = gimple_phi_arg (phi1, i)->def;
1022 t2 = gimple_phi_arg (phi2, i)->def;
1024 if (!m_checker->compare_operand (t1, t2))
1025 return return_false ();
1027 e1 = gimple_phi_arg_edge (phi1, i);
1028 e2 = gimple_phi_arg_edge (phi2, i);
1030 if (!m_checker->compare_edge (e1, e2))
1031 return return_false ();
1034 gsi_next (&si2);
1037 return true;
1040 /* Returns true if tree T can be compared as a handled component. */
1042 bool
1043 sem_function::icf_handled_component_p (tree t)
1045 tree_code tc = TREE_CODE (t);
1047 return ((handled_component_p (t))
1048 || tc == ADDR_EXPR || tc == MEM_REF || tc == REALPART_EXPR
1049 || tc == IMAGPART_EXPR || tc == OBJ_TYPE_REF);
1052 /* Basic blocks dictionary BB_DICT returns true if SOURCE index BB
1053 corresponds to TARGET. */
1055 bool
1056 sem_function::bb_dict_test (auto_vec<int> bb_dict, int source, int target)
1058 source++;
1059 target++;
1061 if (bb_dict.length () <= (unsigned)source)
1062 bb_dict.safe_grow_cleared (source + 1);
1064 if (bb_dict[source] == 0)
1066 bb_dict[source] = target;
1067 return true;
1069 else
1070 return bb_dict[source] == target;
1073 /* Iterates all tree types in T1 and T2 and returns true if all types
1074 are compatible. If COMPARE_POLYMORPHIC is set to true,
1075 more strict comparison is executed. */
1077 bool
1078 sem_function::compare_type_list (tree t1, tree t2, bool compare_polymorphic)
1080 tree tv1, tv2;
1081 tree_code tc1, tc2;
1083 if (!t1 && !t2)
1084 return true;
1086 while (t1 != NULL && t2 != NULL)
1088 tv1 = TREE_VALUE (t1);
1089 tv2 = TREE_VALUE (t2);
1091 tc1 = TREE_CODE (tv1);
1092 tc2 = TREE_CODE (tv2);
1094 if (tc1 == NOP_EXPR && tc2 == NOP_EXPR)
1096 else if (tc1 == NOP_EXPR || tc2 == NOP_EXPR)
1097 return false;
1098 else if (!func_checker::compatible_types_p (tv1, tv2, compare_polymorphic))
1099 return false;
1101 t1 = TREE_CHAIN (t1);
1102 t2 = TREE_CHAIN (t2);
1105 return !(t1 || t2);
1109 /* Semantic variable constructor that uses STACK as bitmap memory stack. */
1111 sem_variable::sem_variable (bitmap_obstack *stack): sem_item (VAR, stack)
1115 /* Constructor based on varpool node _NODE with computed hash _HASH.
1116 Bitmap STACK is used for memory allocation. */
1118 sem_variable::sem_variable (varpool_node *node, hashval_t _hash,
1119 bitmap_obstack *stack): sem_item(VAR,
1120 node, _hash, stack)
1122 gcc_checking_assert (node);
1123 gcc_checking_assert (get_node ());
1126 /* Returns true if the item equals to ITEM given as argument. */
1128 bool
1129 sem_variable::equals (sem_item *item,
1130 hash_map <symtab_node *, sem_item *> & ARG_UNUSED (ignored_nodes))
1132 gcc_assert (item->type == VAR);
1134 sem_variable *v = static_cast<sem_variable *>(item);
1136 if (!ctor || !v->ctor)
1137 return return_false_with_msg ("ctor is missing for semantic variable");
1139 return sem_variable::equals (ctor, v->ctor);
1142 /* Compares trees T1 and T2 for semantic equality. */
1144 bool
1145 sem_variable::equals (tree t1, tree t2)
1147 tree_code tc1 = TREE_CODE (t1);
1148 tree_code tc2 = TREE_CODE (t2);
1150 if (tc1 != tc2)
1151 return false;
1153 switch (tc1)
1155 case CONSTRUCTOR:
1157 unsigned len1 = vec_safe_length (CONSTRUCTOR_ELTS (t1));
1158 unsigned len2 = vec_safe_length (CONSTRUCTOR_ELTS (t2));
1160 if (len1 != len2)
1161 return false;
1163 for (unsigned i = 0; i < len1; i++)
1164 if (!sem_variable::equals (CONSTRUCTOR_ELT (t1, i)->value,
1165 CONSTRUCTOR_ELT (t2, i)->value)
1166 || CONSTRUCTOR_ELT (t1, i)->index != CONSTRUCTOR_ELT (t2, i)->index)
1167 return false;
1169 return true;
1171 case MEM_REF:
1173 tree x1 = TREE_OPERAND (t1, 0);
1174 tree x2 = TREE_OPERAND (t2, 0);
1175 tree y1 = TREE_OPERAND (t1, 1);
1176 tree y2 = TREE_OPERAND (t2, 1);
1178 if (!func_checker::compatible_types_p (TREE_TYPE (x1), TREE_TYPE (x2),
1179 true))
1180 return return_false ();
1182 /* Type of the offset on MEM_REF does not matter. */
1183 return sem_variable::equals (x1, x2)
1184 && wi::to_offset (y1) == wi::to_offset (y2);
1186 case NOP_EXPR:
1187 case ADDR_EXPR:
1189 tree op1 = TREE_OPERAND (t1, 0);
1190 tree op2 = TREE_OPERAND (t2, 0);
1191 return sem_variable::equals (op1, op2);
1193 case FUNCTION_DECL:
1194 case VAR_DECL:
1195 case FIELD_DECL:
1196 case LABEL_DECL:
1197 return t1 == t2;
1198 case INTEGER_CST:
1199 return func_checker::compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2),
1200 true)
1201 && wi::to_offset (t1) == wi::to_offset (t2);
1202 case STRING_CST:
1203 case REAL_CST:
1204 case COMPLEX_CST:
1205 return operand_equal_p (t1, t2, OEP_ONLY_CONST);
1206 case COMPONENT_REF:
1207 case ARRAY_REF:
1208 case POINTER_PLUS_EXPR:
1210 tree x1 = TREE_OPERAND (t1, 0);
1211 tree x2 = TREE_OPERAND (t2, 0);
1212 tree y1 = TREE_OPERAND (t1, 1);
1213 tree y2 = TREE_OPERAND (t2, 1);
1215 return sem_variable::equals (x1, x2) && sem_variable::equals (y1, y2);
1217 case ERROR_MARK:
1218 return return_false_with_msg ("ERROR_MARK");
1219 default:
1220 return return_false_with_msg ("Unknown TREE code reached");
1224 /* Parser function that visits a varpool NODE. */
1226 sem_variable *
1227 sem_variable::parse (varpool_node *node, bitmap_obstack *stack)
1229 tree decl = node->decl;
1231 bool readonly = TYPE_P (decl) ? TYPE_READONLY (decl) : TREE_READONLY (decl);
1232 if (!readonly)
1233 return NULL;
1235 bool can_handle = DECL_VIRTUAL_P (decl)
1236 || flag_merge_constants >= 2
1237 || (!TREE_ADDRESSABLE (decl) && !node->externally_visible);
1239 if (!can_handle || DECL_EXTERNAL (decl))
1240 return NULL;
1242 tree ctor = ctor_for_folding (decl);
1243 if (!ctor)
1244 return NULL;
1246 sem_variable *v = new sem_variable (node, 0, stack);
1248 v->init ();
1250 return v;
1253 /* References independent hash function. */
1255 hashval_t
1256 sem_variable::get_hash (void)
1258 if (hash)
1259 return hash;
1261 inchash::hash hstate;
1263 hstate.add_int (456346417);
1264 hstate.add_int (TREE_CODE (ctor));
1266 if (TREE_CODE (ctor) == CONSTRUCTOR)
1268 unsigned length = vec_safe_length (CONSTRUCTOR_ELTS (ctor));
1269 hstate.add_int (length);
1272 hash = hstate.end ();
1274 return hash;
1277 /* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can
1278 be applied. */
1280 bool
1281 sem_variable::merge (sem_item *alias_item)
1283 gcc_assert (alias_item->type == VAR);
1285 if (!sem_item::target_supports_symbol_aliases_p ())
1287 if (dump_file)
1288 fprintf (dump_file, "Symbol aliases are not supported by target\n\n");
1289 return false;
1292 sem_variable *alias_var = static_cast<sem_variable *> (alias_item);
1294 varpool_node *original = get_node ();
1295 varpool_node *alias = alias_var->get_node ();
1296 bool original_discardable = false;
1298 /* See if original is in a section that can be discarded if the main
1299 symbol is not used. */
1300 if (DECL_EXTERNAL (original->decl))
1301 original_discardable = true;
1302 if (original->resolution == LDPR_PREEMPTED_REG
1303 || original->resolution == LDPR_PREEMPTED_IR)
1304 original_discardable = true;
1305 if (original->can_be_discarded_p ())
1306 original_discardable = true;
1308 gcc_assert (!TREE_ASM_WRITTEN (alias->decl));
1310 if (original_discardable || DECL_EXTERNAL (alias_var->decl) ||
1311 !compare_sections (alias_var))
1313 if (dump_file)
1314 fprintf (dump_file, "Varpool alias cannot be created\n\n");
1316 return false;
1318 else
1320 // alias cycle creation check
1321 varpool_node *n = original;
1323 while (n->alias)
1325 n = n->get_alias_target ();
1326 if (n == alias)
1328 if (dump_file)
1329 fprintf (dump_file, "Varpool alias cannot be created (alias cycle).\n\n");
1331 return false;
1335 alias->analyzed = false;
1337 DECL_INITIAL (alias->decl) = NULL;
1338 alias->need_bounds_init = false;
1339 alias->remove_all_references ();
1341 varpool_node::create_alias (alias_var->decl, decl);
1342 alias->resolve_alias (original);
1344 if (dump_file)
1345 fprintf (dump_file, "Varpool alias has been created.\n\n");
1347 return true;
1351 bool
1352 sem_variable::compare_sections (sem_variable *alias)
1354 const char *source = node->get_section ();
1355 const char *target = alias->node->get_section();
1357 if (source == NULL && target == NULL)
1358 return true;
1359 else if(!source || !target)
1360 return false;
1361 else
1362 return strcmp (source, target) == 0;
1365 /* Dump symbol to FILE. */
1367 void
1368 sem_variable::dump_to_file (FILE *file)
1370 gcc_assert (file);
1372 print_node (file, "", decl, 0);
1373 fprintf (file, "\n\n");
1376 /* Iterates though a constructor and identifies tree references
1377 we are interested in semantic function equality. */
1379 void
1380 sem_variable::parse_tree_refs (tree t)
1382 switch (TREE_CODE (t))
1384 case CONSTRUCTOR:
1386 unsigned length = vec_safe_length (CONSTRUCTOR_ELTS (t));
1388 for (unsigned i = 0; i < length; i++)
1389 parse_tree_refs(CONSTRUCTOR_ELT (t, i)->value);
1391 break;
1393 case NOP_EXPR:
1394 case ADDR_EXPR:
1396 tree op = TREE_OPERAND (t, 0);
1397 parse_tree_refs (op);
1398 break;
1400 case FUNCTION_DECL:
1402 tree_refs.safe_push (t);
1403 break;
1405 default:
1406 break;
1410 unsigned int sem_item_optimizer::class_id = 0;
1412 sem_item_optimizer::sem_item_optimizer (): worklist (0), m_classes (0),
1413 m_classes_count (0), m_cgraph_node_hooks (NULL), m_varpool_node_hooks (NULL)
1415 m_items.create (0);
1416 bitmap_obstack_initialize (&m_bmstack);
1419 sem_item_optimizer::~sem_item_optimizer ()
1421 for (unsigned int i = 0; i < m_items.length (); i++)
1422 delete m_items[i];
1424 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
1425 it != m_classes.end (); ++it)
1427 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
1428 delete (*it)->classes[i];
1430 (*it)->classes.release ();
1431 free (*it);
1434 m_items.release ();
1436 bitmap_obstack_release (&m_bmstack);
1439 /* Write IPA ICF summary for symbols. */
1441 void
1442 sem_item_optimizer::write_summary (void)
1444 unsigned int count = 0;
1446 output_block *ob = create_output_block (LTO_section_ipa_icf);
1447 lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
1448 ob->symbol = NULL;
1450 /* Calculate number of symbols to be serialized. */
1451 for (lto_symtab_encoder_iterator lsei = lsei_start_in_partition (encoder);
1452 !lsei_end_p (lsei);
1453 lsei_next_in_partition (&lsei))
1455 symtab_node *node = lsei_node (lsei);
1457 if (m_symtab_node_map.get (node))
1458 count++;
1461 streamer_write_uhwi (ob, count);
1463 /* Process all of the symbols. */
1464 for (lto_symtab_encoder_iterator lsei = lsei_start_in_partition (encoder);
1465 !lsei_end_p (lsei);
1466 lsei_next_in_partition (&lsei))
1468 symtab_node *node = lsei_node (lsei);
1470 sem_item **item = m_symtab_node_map.get (node);
1472 if (item && *item)
1474 int node_ref = lto_symtab_encoder_encode (encoder, node);
1475 streamer_write_uhwi_stream (ob->main_stream, node_ref);
1477 streamer_write_uhwi (ob, (*item)->get_hash ());
1481 streamer_write_char_stream (ob->main_stream, 0);
1482 produce_asm (ob, NULL);
1483 destroy_output_block (ob);
1486 /* Reads a section from LTO stream file FILE_DATA. Input block for DATA
1487 contains LEN bytes. */
1489 void
1490 sem_item_optimizer::read_section (lto_file_decl_data *file_data,
1491 const char *data, size_t len)
1493 const lto_function_header *header =
1494 (const lto_function_header *) data;
1495 const int cfg_offset = sizeof (lto_function_header);
1496 const int main_offset = cfg_offset + header->cfg_size;
1497 const int string_offset = main_offset + header->main_size;
1498 data_in *data_in;
1499 unsigned int i;
1500 unsigned int count;
1502 lto_input_block ib_main ((const char *) data + main_offset, 0,
1503 header->main_size);
1505 data_in =
1506 lto_data_in_create (file_data, (const char *) data + string_offset,
1507 header->string_size, vNULL);
1509 count = streamer_read_uhwi (&ib_main);
1511 for (i = 0; i < count; i++)
1513 unsigned int index;
1514 symtab_node *node;
1515 lto_symtab_encoder_t encoder;
1517 index = streamer_read_uhwi (&ib_main);
1518 encoder = file_data->symtab_node_encoder;
1519 node = lto_symtab_encoder_deref (encoder, index);
1521 hashval_t hash = streamer_read_uhwi (&ib_main);
1523 gcc_assert (node->definition);
1525 if (dump_file)
1526 fprintf (dump_file, "Symbol added:%s (tree: %p, uid:%u)\n", node->asm_name (),
1527 (void *) node->decl, node->order);
1529 if (is_a<cgraph_node *> (node))
1531 cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
1533 m_items.safe_push (new sem_function (cnode, hash, &m_bmstack));
1535 else
1537 varpool_node *vnode = dyn_cast <varpool_node *> (node);
1539 m_items.safe_push (new sem_variable (vnode, hash, &m_bmstack));
1543 lto_free_section_data (file_data, LTO_section_ipa_icf, NULL, data,
1544 len);
1545 lto_data_in_delete (data_in);
1548 /* Read IPA IPA ICF summary for symbols. */
1550 void
1551 sem_item_optimizer::read_summary (void)
1553 lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
1554 lto_file_decl_data *file_data;
1555 unsigned int j = 0;
1557 while ((file_data = file_data_vec[j++]))
1559 size_t len;
1560 const char *data = lto_get_section_data (file_data,
1561 LTO_section_ipa_icf, NULL, &len);
1563 if (data)
1564 read_section (file_data, data, len);
1568 /* Register callgraph and varpool hooks. */
1570 void
1571 sem_item_optimizer::register_hooks (void)
1573 if (!m_cgraph_node_hooks)
1574 m_cgraph_node_hooks = symtab->add_cgraph_removal_hook
1575 (&sem_item_optimizer::cgraph_removal_hook, this);
1577 if (!m_varpool_node_hooks)
1578 m_varpool_node_hooks = symtab->add_varpool_removal_hook
1579 (&sem_item_optimizer::varpool_removal_hook, this);
1582 /* Unregister callgraph and varpool hooks. */
1584 void
1585 sem_item_optimizer::unregister_hooks (void)
1587 if (m_cgraph_node_hooks)
1588 symtab->remove_cgraph_removal_hook (m_cgraph_node_hooks);
1590 if (m_varpool_node_hooks)
1591 symtab->remove_varpool_removal_hook (m_varpool_node_hooks);
1594 /* Adds a CLS to hashtable associated by hash value. */
1596 void
1597 sem_item_optimizer::add_class (congruence_class *cls)
1599 gcc_assert (cls->members.length ());
1601 congruence_class_group *group = get_group_by_hash (
1602 cls->members[0]->get_hash (),
1603 cls->members[0]->type);
1604 group->classes.safe_push (cls);
1607 /* Gets a congruence class group based on given HASH value and TYPE. */
1609 congruence_class_group *
1610 sem_item_optimizer::get_group_by_hash (hashval_t hash, sem_item_type type)
1612 congruence_class_group *item = XNEW (congruence_class_group);
1613 item->hash = hash;
1614 item->type = type;
1616 congruence_class_group **slot = m_classes.find_slot (item, INSERT);
1618 if (*slot)
1619 free (item);
1620 else
1622 item->classes.create (1);
1623 *slot = item;
1626 return *slot;
1629 /* Callgraph removal hook called for a NODE with a custom DATA. */
1631 void
1632 sem_item_optimizer::cgraph_removal_hook (cgraph_node *node, void *data)
1634 sem_item_optimizer *optimizer = (sem_item_optimizer *) data;
1635 optimizer->remove_symtab_node (node);
1638 /* Varpool removal hook called for a NODE with a custom DATA. */
1640 void
1641 sem_item_optimizer::varpool_removal_hook (varpool_node *node, void *data)
1643 sem_item_optimizer *optimizer = (sem_item_optimizer *) data;
1644 optimizer->remove_symtab_node (node);
1647 /* Remove symtab NODE triggered by symtab removal hooks. */
1649 void
1650 sem_item_optimizer::remove_symtab_node (symtab_node *node)
1652 gcc_assert (!m_classes.elements());
1654 m_removed_items_set.add (node);
1657 void
1658 sem_item_optimizer::remove_item (sem_item *item)
1660 if (m_symtab_node_map.get (item->node))
1661 m_symtab_node_map.remove (item->node);
1662 delete item;
1665 /* Removes all callgraph and varpool nodes that are marked by symtab
1666 as deleted. */
1668 void
1669 sem_item_optimizer::filter_removed_items (void)
1671 auto_vec <sem_item *> filtered;
1673 for (unsigned int i = 0; i < m_items.length(); i++)
1675 sem_item *item = m_items[i];
1677 if (m_removed_items_set.contains (item->node))
1679 remove_item (item);
1680 continue;
1683 if (item->type == FUNC)
1685 cgraph_node *cnode = static_cast <sem_function *>(item)->get_node ();
1687 bool no_body_function = in_lto_p && (cnode->alias || cnode->body_removed);
1688 if (no_body_function || !opt_for_fn (item->decl, flag_ipa_icf_functions)
1689 || DECL_CXX_CONSTRUCTOR_P (item->decl)
1690 || DECL_CXX_DESTRUCTOR_P (item->decl))
1691 remove_item (item);
1692 else
1693 filtered.safe_push (item);
1695 else /* VAR. */
1697 if (!flag_ipa_icf_variables)
1698 remove_item (item);
1699 else
1700 filtered.safe_push (item);
1704 /* Clean-up of released semantic items. */
1706 m_items.release ();
1707 for (unsigned int i = 0; i < filtered.length(); i++)
1708 m_items.safe_push (filtered[i]);
1711 /* Optimizer entry point. */
1713 void
1714 sem_item_optimizer::execute (void)
1716 filter_removed_items ();
1717 build_hash_based_classes ();
1719 if (dump_file)
1720 fprintf (dump_file, "Dump after hash based groups\n");
1721 dump_cong_classes ();
1723 for (unsigned int i = 0; i < m_items.length(); i++)
1724 m_items[i]->init_wpa ();
1726 build_graph ();
1728 subdivide_classes_by_equality (true);
1730 if (dump_file)
1731 fprintf (dump_file, "Dump after WPA based types groups\n");
1733 dump_cong_classes ();
1735 process_cong_reduction ();
1736 verify_classes ();
1738 if (dump_file)
1739 fprintf (dump_file, "Dump after callgraph-based congruence reduction\n");
1741 dump_cong_classes ();
1743 parse_nonsingleton_classes ();
1744 subdivide_classes_by_equality ();
1746 if (dump_file)
1747 fprintf (dump_file, "Dump after full equality comparison of groups\n");
1749 dump_cong_classes ();
1751 unsigned int prev_class_count = m_classes_count;
1753 process_cong_reduction ();
1754 dump_cong_classes ();
1755 verify_classes ();
1756 merge_classes (prev_class_count);
1758 if (dump_file && (dump_flags & TDF_DETAILS))
1759 symtab_node::dump_table (dump_file);
1762 /* Function responsible for visiting all potential functions and
1763 read-only variables that can be merged. */
1765 void
1766 sem_item_optimizer::parse_funcs_and_vars (void)
1768 cgraph_node *cnode;
1770 if (flag_ipa_icf_functions)
1771 FOR_EACH_DEFINED_FUNCTION (cnode)
1773 sem_function *f = sem_function::parse (cnode, &m_bmstack);
1774 if (f)
1776 m_items.safe_push (f);
1777 m_symtab_node_map.put (cnode, f);
1779 if (dump_file)
1780 fprintf (dump_file, "Parsed function:%s\n", f->asm_name ());
1782 if (dump_file && (dump_flags & TDF_DETAILS))
1783 f->dump_to_file (dump_file);
1785 else if (dump_file)
1786 fprintf (dump_file, "Not parsed function:%s\n", cnode->asm_name ());
1789 varpool_node *vnode;
1791 if (flag_ipa_icf_variables)
1792 FOR_EACH_DEFINED_VARIABLE (vnode)
1794 sem_variable *v = sem_variable::parse (vnode, &m_bmstack);
1796 if (v)
1798 m_items.safe_push (v);
1799 m_symtab_node_map.put (vnode, v);
1804 /* Makes pairing between a congruence class CLS and semantic ITEM. */
1806 void
1807 sem_item_optimizer::add_item_to_class (congruence_class *cls, sem_item *item)
1809 item->index_in_class = cls->members.length ();
1810 cls->members.safe_push (item);
1811 item->cls = cls;
1814 /* Congruence classes are built by hash value. */
1816 void
1817 sem_item_optimizer::build_hash_based_classes (void)
1819 for (unsigned i = 0; i < m_items.length (); i++)
1821 sem_item *item = m_items[i];
1823 congruence_class_group *group = get_group_by_hash (item->get_hash (),
1824 item->type);
1826 if (!group->classes.length ())
1828 m_classes_count++;
1829 group->classes.safe_push (new congruence_class (class_id++));
1832 add_item_to_class (group->classes[0], item);
1836 /* Build references according to call graph. */
1838 void
1839 sem_item_optimizer::build_graph (void)
1841 for (unsigned i = 0; i < m_items.length (); i++)
1843 sem_item *item = m_items[i];
1844 m_symtab_node_map.put (item->node, item);
1847 for (unsigned i = 0; i < m_items.length (); i++)
1849 sem_item *item = m_items[i];
1851 if (item->type == FUNC)
1853 cgraph_node *cnode = dyn_cast <cgraph_node *> (item->node);
1855 cgraph_edge *e = cnode->callees;
1856 while (e)
1858 sem_item **slot = m_symtab_node_map.get (e->callee);
1859 if (slot)
1860 item->add_reference (*slot);
1862 e = e->next_callee;
1866 ipa_ref *ref = NULL;
1867 for (unsigned i = 0; item->node->iterate_reference (i, ref); i++)
1869 sem_item **slot = m_symtab_node_map.get (ref->referred);
1870 if (slot)
1871 item->add_reference (*slot);
1876 /* Semantic items in classes having more than one element and initialized.
1877 In case of WPA, we load function body. */
1879 void
1880 sem_item_optimizer::parse_nonsingleton_classes (void)
1882 unsigned int init_called_count = 0;
1884 for (unsigned i = 0; i < m_items.length (); i++)
1885 if (m_items[i]->cls->members.length () > 1)
1887 m_items[i]->init ();
1888 init_called_count++;
1891 if (dump_file)
1892 fprintf (dump_file, "Init called for %u items (%.2f%%).\n", init_called_count,
1893 m_items.length () ? 100.0f * init_called_count / m_items.length (): 0.0f);
1896 /* Equality function for semantic items is used to subdivide existing
1897 classes. If IN_WPA, fast equality function is invoked. */
1899 void
1900 sem_item_optimizer::subdivide_classes_by_equality (bool in_wpa)
1902 for (hash_table <congruence_class_group_hash>::iterator it = m_classes.begin ();
1903 it != m_classes.end (); ++it)
1905 unsigned int class_count = (*it)->classes.length ();
1907 for (unsigned i = 0; i < class_count; i++)
1909 congruence_class *c = (*it)->classes [i];
1911 if (c->members.length() > 1)
1913 auto_vec <sem_item *> new_vector;
1915 sem_item *first = c->members[0];
1916 new_vector.safe_push (first);
1918 unsigned class_split_first = (*it)->classes.length ();
1920 for (unsigned j = 1; j < c->members.length (); j++)
1922 sem_item *item = c->members[j];
1924 bool equals = in_wpa ? first->equals_wpa (item,
1925 m_symtab_node_map) : first->equals (item, m_symtab_node_map);
1927 if (equals)
1928 new_vector.safe_push (item);
1929 else
1931 bool integrated = false;
1933 for (unsigned k = class_split_first; k < (*it)->classes.length (); k++)
1935 sem_item *x = (*it)->classes[k]->members[0];
1936 bool equals = in_wpa ? x->equals_wpa (item,
1937 m_symtab_node_map) : x->equals (item, m_symtab_node_map);
1939 if (equals)
1941 integrated = true;
1942 add_item_to_class ((*it)->classes[k], item);
1944 break;
1948 if (!integrated)
1950 congruence_class *c = new congruence_class (class_id++);
1951 m_classes_count++;
1952 add_item_to_class (c, item);
1954 (*it)->classes.safe_push (c);
1959 // we replace newly created new_vector for the class we've just splitted
1960 c->members.release ();
1961 c->members.create (new_vector.length ());
1963 for (unsigned int j = 0; j < new_vector.length (); j++)
1964 add_item_to_class (c, new_vector[j]);
1969 verify_classes ();
1972 /* Verify congruence classes if checking is enabled. */
1974 void
1975 sem_item_optimizer::verify_classes (void)
1977 #if ENABLE_CHECKING
1978 for (hash_table <congruence_class_group_hash>::iterator it = m_classes.begin ();
1979 it != m_classes.end (); ++it)
1981 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
1983 congruence_class *cls = (*it)->classes[i];
1985 gcc_checking_assert (cls);
1986 gcc_checking_assert (cls->members.length () > 0);
1988 for (unsigned int j = 0; j < cls->members.length (); j++)
1990 sem_item *item = cls->members[j];
1992 gcc_checking_assert (item);
1993 gcc_checking_assert (item->cls == cls);
1995 for (unsigned k = 0; k < item->usages.length (); k++)
1997 sem_usage_pair *usage = item->usages[k];
1998 gcc_checking_assert (usage->item->index_in_class <
1999 usage->item->cls->members.length ());
2004 #endif
2007 /* Disposes split map traverse function. CLS_PTR is pointer to congruence
2008 class, BSLOT is bitmap slot we want to release. DATA is mandatory,
2009 but unused argument. */
2011 bool
2012 sem_item_optimizer::release_split_map (congruence_class * const &,
2013 bitmap const &b, traverse_split_pair *)
2015 bitmap bmp = b;
2017 BITMAP_FREE (bmp);
2019 return true;
2022 /* Process split operation for a class given as pointer CLS_PTR,
2023 where bitmap B splits congruence class members. DATA is used
2024 as argument of split pair. */
2026 bool
2027 sem_item_optimizer::traverse_congruence_split (congruence_class * const &cls,
2028 bitmap const &b, traverse_split_pair *pair)
2030 sem_item_optimizer *optimizer = pair->optimizer;
2031 const congruence_class *splitter_cls = pair->cls;
2033 /* If counted bits are greater than zero and less than the number of members
2034 a group will be splitted. */
2035 unsigned popcount = bitmap_count_bits (b);
2037 if (popcount > 0 && popcount < cls->members.length ())
2039 congruence_class* newclasses[2] = { new congruence_class (class_id++), new congruence_class (class_id++) };
2041 for (unsigned int i = 0; i < cls->members.length (); i++)
2043 int target = bitmap_bit_p (b, i);
2044 congruence_class *tc = newclasses[target];
2046 add_item_to_class (tc, cls->members[i]);
2049 #ifdef ENABLE_CHECKING
2050 for (unsigned int i = 0; i < 2; i++)
2051 gcc_checking_assert (newclasses[i]->members.length ());
2052 #endif
2054 if (splitter_cls == cls)
2055 optimizer->splitter_class_removed = true;
2057 /* Remove old class from worklist if presented. */
2058 bool in_worklist = cls->in_worklist;
2060 if (in_worklist)
2061 cls->in_worklist = false;
2063 congruence_class_group g;
2064 g.hash = cls->members[0]->get_hash ();
2065 g.type = cls->members[0]->type;
2067 congruence_class_group *slot = optimizer->m_classes.find(&g);
2069 for (unsigned int i = 0; i < slot->classes.length (); i++)
2070 if (slot->classes[i] == cls)
2072 slot->classes.ordered_remove (i);
2073 break;
2076 /* New class will be inserted and integrated to work list. */
2077 for (unsigned int i = 0; i < 2; i++)
2078 optimizer->add_class (newclasses[i]);
2080 /* Two classes replace one, so that increment just by one. */
2081 optimizer->m_classes_count++;
2083 /* If OLD class was presented in the worklist, we remove the class
2084 and replace it will both newly created classes. */
2085 if (in_worklist)
2086 for (unsigned int i = 0; i < 2; i++)
2087 optimizer->worklist_push (newclasses[i]);
2088 else /* Just smaller class is inserted. */
2090 unsigned int smaller_index = newclasses[0]->members.length () <
2091 newclasses[1]->members.length () ?
2092 0 : 1;
2093 optimizer->worklist_push (newclasses[smaller_index]);
2096 if (dump_file && (dump_flags & TDF_DETAILS))
2098 fprintf (dump_file, " congruence class splitted:\n");
2099 cls->dump (dump_file, 4);
2101 fprintf (dump_file, " newly created groups:\n");
2102 for (unsigned int i = 0; i < 2; i++)
2103 newclasses[i]->dump (dump_file, 4);
2106 /* Release class if not presented in work list. */
2107 if (!in_worklist)
2108 delete cls;
2112 return true;
2115 /* Tests if a class CLS used as INDEXth splits any congruence classes.
2116 Bitmap stack BMSTACK is used for bitmap allocation. */
2118 void
2119 sem_item_optimizer::do_congruence_step_for_index (congruence_class *cls,
2120 unsigned int index)
2122 hash_map <congruence_class *, bitmap> split_map;
2124 for (unsigned int i = 0; i < cls->members.length (); i++)
2126 sem_item *item = cls->members[i];
2128 /* Iterate all usages that have INDEX as usage of the item. */
2129 for (unsigned int j = 0; j < item->usages.length (); j++)
2131 sem_usage_pair *usage = item->usages[j];
2133 if (usage->index != index)
2134 continue;
2136 bitmap *slot = split_map.get (usage->item->cls);
2137 bitmap b;
2139 if(!slot)
2141 b = BITMAP_ALLOC (&m_bmstack);
2142 split_map.put (usage->item->cls, b);
2144 else
2145 b = *slot;
2147 #if ENABLE_CHECKING
2148 gcc_checking_assert (usage->item->cls);
2149 gcc_checking_assert (usage->item->index_in_class <
2150 usage->item->cls->members.length ());
2151 #endif
2153 bitmap_set_bit (b, usage->item->index_in_class);
2157 traverse_split_pair pair;
2158 pair.optimizer = this;
2159 pair.cls = cls;
2161 splitter_class_removed = false;
2162 split_map.traverse
2163 <traverse_split_pair *, sem_item_optimizer::traverse_congruence_split> (&pair);
2165 /* Bitmap clean-up. */
2166 split_map.traverse
2167 <traverse_split_pair *, sem_item_optimizer::release_split_map> (NULL);
2170 /* Every usage of a congruence class CLS is a candidate that can split the
2171 collection of classes. Bitmap stack BMSTACK is used for bitmap
2172 allocation. */
2174 void
2175 sem_item_optimizer::do_congruence_step (congruence_class *cls)
2177 bitmap_iterator bi;
2178 unsigned int i;
2180 bitmap usage = BITMAP_ALLOC (&m_bmstack);
2182 for (unsigned int i = 0; i < cls->members.length (); i++)
2183 bitmap_ior_into (usage, cls->members[i]->usage_index_bitmap);
2185 EXECUTE_IF_SET_IN_BITMAP (usage, 0, i, bi)
2187 if (dump_file && (dump_flags & TDF_DETAILS))
2188 fprintf (dump_file, " processing congruece step for class: %u, index: %u\n",
2189 cls->id, i);
2191 do_congruence_step_for_index (cls, i);
2193 if (splitter_class_removed)
2194 break;
2197 BITMAP_FREE (usage);
2200 /* Adds a newly created congruence class CLS to worklist. */
2202 void
2203 sem_item_optimizer::worklist_push (congruence_class *cls)
2205 /* Return if the class CLS is already presented in work list. */
2206 if (cls->in_worklist)
2207 return;
2209 cls->in_worklist = true;
2210 worklist.push_back (cls);
2213 /* Pops a class from worklist. */
2215 congruence_class *
2216 sem_item_optimizer::worklist_pop (void)
2218 congruence_class *cls;
2220 while (!worklist.empty ())
2222 cls = worklist.front ();
2223 worklist.pop_front ();
2224 if (cls->in_worklist)
2226 cls->in_worklist = false;
2228 return cls;
2230 else
2232 /* Work list item was already intended to be removed.
2233 The only reason for doing it is to split a class.
2234 Thus, the class CLS is deleted. */
2235 delete cls;
2239 return NULL;
2242 /* Iterative congruence reduction function. */
2244 void
2245 sem_item_optimizer::process_cong_reduction (void)
2247 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2248 it != m_classes.end (); ++it)
2249 for (unsigned i = 0; i < (*it)->classes.length (); i++)
2250 if ((*it)->classes[i]->is_class_used ())
2251 worklist_push ((*it)->classes[i]);
2253 if (dump_file)
2254 fprintf (dump_file, "Worklist has been filled with: %lu\n",
2255 (unsigned long) worklist.size ());
2257 if (dump_file && (dump_flags & TDF_DETAILS))
2258 fprintf (dump_file, "Congruence class reduction\n");
2260 congruence_class *cls;
2261 while ((cls = worklist_pop ()) != NULL)
2262 do_congruence_step (cls);
2265 /* Debug function prints all informations about congruence classes. */
2267 void
2268 sem_item_optimizer::dump_cong_classes (void)
2270 if (!dump_file)
2271 return;
2273 fprintf (dump_file,
2274 "Congruence classes: %u (unique hash values: %lu), with total: %u items\n",
2275 m_classes_count, (unsigned long) m_classes.elements(), m_items.length ());
2277 /* Histogram calculation. */
2278 unsigned int max_index = 0;
2279 unsigned int* histogram = XCNEWVEC (unsigned int, m_items.length () + 1);
2281 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2282 it != m_classes.end (); ++it)
2284 for (unsigned i = 0; i < (*it)->classes.length (); i++)
2286 unsigned int c = (*it)->classes[i]->members.length ();
2287 histogram[c]++;
2289 if (c > max_index)
2290 max_index = c;
2293 fprintf (dump_file,
2294 "Class size histogram [num of members]: number of classe number of classess\n");
2296 for (unsigned int i = 0; i <= max_index; i++)
2297 if (histogram[i])
2298 fprintf (dump_file, "[%u]: %u classes\n", i, histogram[i]);
2300 fprintf (dump_file, "\n\n");
2303 if (dump_flags & TDF_DETAILS)
2304 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2305 it != m_classes.end (); ++it)
2307 fprintf (dump_file, " group: with %u classes:\n", (*it)->classes.length ());
2309 for (unsigned i = 0; i < (*it)->classes.length (); i++)
2311 (*it)->classes[i]->dump (dump_file, 4);
2313 if(i < (*it)->classes.length () - 1)
2314 fprintf (dump_file, " ");
2318 free (histogram);
2321 /* After reduction is done, we can declare all items in a group
2322 to be equal. PREV_CLASS_COUNT is start number of classes
2323 before reduction. */
2325 void
2326 sem_item_optimizer::merge_classes (unsigned int prev_class_count)
2328 unsigned int item_count = m_items.length ();
2329 unsigned int class_count = m_classes_count;
2330 unsigned int equal_items = item_count - class_count;
2332 unsigned int non_singular_classes_count = 0;
2333 unsigned int non_singular_classes_sum = 0;
2335 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2336 it != m_classes.end (); ++it)
2337 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
2339 congruence_class *c = (*it)->classes[i];
2340 if (c->members.length () > 1)
2342 non_singular_classes_count++;
2343 non_singular_classes_sum += c->members.length ();
2347 if (dump_file)
2349 fprintf (dump_file, "\nItem count: %u\n", item_count);
2350 fprintf (dump_file, "Congruent classes before: %u, after: %u\n",
2351 prev_class_count, class_count);
2352 fprintf (dump_file, "Average class size before: %.2f, after: %.2f\n",
2353 prev_class_count ? 1.0f * item_count / prev_class_count : 0.0f,
2354 class_count ? 1.0f * item_count / class_count : 0.0f);
2355 fprintf (dump_file, "Average non-singular class size: %.2f, count: %u\n",
2356 non_singular_classes_count ? 1.0f * non_singular_classes_sum /
2357 non_singular_classes_count : 0.0f,
2358 non_singular_classes_count);
2359 fprintf (dump_file, "Equal symbols: %u\n", equal_items);
2360 fprintf (dump_file, "Fraction of visited symbols: %.2f%%\n\n",
2361 item_count ? 100.0f * equal_items / item_count : 0.0f);
2364 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2365 it != m_classes.end (); ++it)
2366 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
2368 congruence_class *c = (*it)->classes[i];
2370 if (c->members.length () == 1)
2371 continue;
2373 gcc_assert (c->members.length ());
2375 sem_item *source = c->members[0];
2377 for (unsigned int j = 1; j < c->members.length (); j++)
2379 sem_item *alias = c->members[j];
2381 if (dump_file)
2383 fprintf (dump_file, "Semantic equality hit:%s->%s\n",
2384 source->name (), alias->name ());
2385 fprintf (dump_file, "Assembler symbol names:%s->%s\n",
2386 source->asm_name (), alias->asm_name ());
2389 if (lookup_attribute ("no_icf", DECL_ATTRIBUTES (alias->decl)))
2391 if (dump_file)
2392 fprintf (dump_file,
2393 "Merge operation is skipped due to no_icf "
2394 "attribute.\n\n");
2396 continue;
2399 if (dump_file && (dump_flags & TDF_DETAILS))
2401 source->dump_to_file (dump_file);
2402 alias->dump_to_file (dump_file);
2405 source->merge (alias);
2410 /* Dump function prints all class members to a FILE with an INDENT. */
2412 void
2413 congruence_class::dump (FILE *file, unsigned int indent) const
2415 FPRINTF_SPACES (file, indent, "class with id: %u, hash: %u, items: %u\n",
2416 id, members[0]->get_hash (), members.length ());
2418 FPUTS_SPACES (file, indent + 2, "");
2419 for (unsigned i = 0; i < members.length (); i++)
2420 fprintf (file, "%s(%p/%u) ", members[i]->asm_name (), (void *) members[i]->decl,
2421 members[i]->node->order);
2423 fprintf (file, "\n");
2426 /* Returns true if there's a member that is used from another group. */
2428 bool
2429 congruence_class::is_class_used (void)
2431 for (unsigned int i = 0; i < members.length (); i++)
2432 if (members[i]->usages.length ())
2433 return true;
2435 return false;
2438 /* Initialization and computation of symtab node hash, there data
2439 are propagated later on. */
2441 static sem_item_optimizer *optimizer = NULL;
2443 /* Generate pass summary for IPA ICF pass. */
2445 static void
2446 ipa_icf_generate_summary (void)
2448 if (!optimizer)
2449 optimizer = new sem_item_optimizer ();
2451 optimizer->register_hooks ();
2452 optimizer->parse_funcs_and_vars ();
2455 /* Write pass summary for IPA ICF pass. */
2457 static void
2458 ipa_icf_write_summary (void)
2460 gcc_assert (optimizer);
2462 optimizer->write_summary ();
2465 /* Read pass summary for IPA ICF pass. */
2467 static void
2468 ipa_icf_read_summary (void)
2470 if (!optimizer)
2471 optimizer = new sem_item_optimizer ();
2473 optimizer->read_summary ();
2474 optimizer->register_hooks ();
2477 /* Semantic equality exection function. */
2479 static unsigned int
2480 ipa_icf_driver (void)
2482 gcc_assert (optimizer);
2484 optimizer->execute ();
2485 optimizer->unregister_hooks ();
2487 delete optimizer;
2488 optimizer = NULL;
2490 return 0;
2493 const pass_data pass_data_ipa_icf =
2495 IPA_PASS, /* type */
2496 "icf", /* name */
2497 OPTGROUP_IPA, /* optinfo_flags */
2498 TV_IPA_ICF, /* tv_id */
2499 0, /* properties_required */
2500 0, /* properties_provided */
2501 0, /* properties_destroyed */
2502 0, /* todo_flags_start */
2503 0, /* todo_flags_finish */
2506 class pass_ipa_icf : public ipa_opt_pass_d
2508 public:
2509 pass_ipa_icf (gcc::context *ctxt)
2510 : ipa_opt_pass_d (pass_data_ipa_icf, ctxt,
2511 ipa_icf_generate_summary, /* generate_summary */
2512 ipa_icf_write_summary, /* write_summary */
2513 ipa_icf_read_summary, /* read_summary */
2514 NULL, /*
2515 write_optimization_summary */
2516 NULL, /*
2517 read_optimization_summary */
2518 NULL, /* stmt_fixup */
2519 0, /* function_transform_todo_flags_start */
2520 NULL, /* function_transform */
2521 NULL) /* variable_transform */
2524 /* opt_pass methods: */
2525 virtual bool gate (function *)
2527 return in_lto_p || flag_ipa_icf_variables || flag_ipa_icf_functions;
2530 virtual unsigned int execute (function *)
2532 return ipa_icf_driver();
2534 }; // class pass_ipa_icf
2536 } // ipa_icf namespace
2538 ipa_opt_pass_d *
2539 make_pass_ipa_icf (gcc::context *ctxt)
2541 return new ipa_icf::pass_ipa_icf (ctxt);