2015-02-22 Arnaud Charlet <charlet@adacore.com>
[official-gcc.git] / gcc / ipa-icf.c
blobe1af8bf3b09b2cd00ef280e1c2f97c2032b80692
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
655 || DECL_COMDAT_GROUP (alias->decl)
656 || !sem_item::target_supports_symbol_aliases_p ())
658 create_thunk = !stdarg_p (TREE_TYPE (alias->decl));
659 create_alias = false;
660 /* When both alias and original are not overwritable, we can save
661 the extra thunk wrapper for direct calls. */
662 redirect_callers
663 = (!original_discardable
664 && !DECL_COMDAT_GROUP (alias->decl)
665 && alias->get_availability () > AVAIL_INTERPOSABLE
666 && original->get_availability () > AVAIL_INTERPOSABLE
667 && !alias->instrumented_version);
669 else
671 create_alias = true;
672 create_thunk = false;
673 redirect_callers = false;
676 /* We want thunk to always jump to the local function body
677 unless the body is comdat and may be optimized out. */
678 if ((create_thunk || redirect_callers)
679 && (!original_discardable
680 || (DECL_COMDAT_GROUP (original->decl)
681 && (DECL_COMDAT_GROUP (original->decl)
682 == DECL_COMDAT_GROUP (alias->decl)))))
683 local_original
684 = dyn_cast <cgraph_node *> (original->noninterposable_alias ());
686 if (!local_original)
688 if (dump_file)
689 fprintf (dump_file, "Noninterposable alias cannot be created.\n\n");
691 return false;
694 if (!decl_binds_to_current_def_p (alias->decl))
696 if (dump_file)
697 fprintf (dump_file, "Declaration does not bind to currect definition.\n\n");
698 return false;
701 if (redirect_callers)
703 /* If alias is non-overwritable then
704 all direct calls are safe to be redirected to the original. */
705 bool redirected = false;
706 while (alias->callers)
708 cgraph_edge *e = alias->callers;
709 e->redirect_callee (local_original);
710 push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
712 if (e->call_stmt)
713 e->redirect_call_stmt_to_callee ();
715 pop_cfun ();
716 redirected = true;
719 alias->icf_merged = true;
720 if (local_original->lto_file_data
721 && alias->lto_file_data
722 && local_original->lto_file_data != alias->lto_file_data)
723 local_original->merged = true;
725 /* The alias function is removed if symbol address
726 does not matter. */
727 if (!alias_address_matters)
728 alias->remove ();
730 if (dump_file && redirected)
731 fprintf (dump_file, "Callgraph local calls have been redirected.\n\n");
733 /* If the condtion above is not met, we are lucky and can turn the
734 function into real alias. */
735 else if (create_alias)
737 alias->icf_merged = true;
738 if (local_original->lto_file_data
739 && alias->lto_file_data
740 && local_original->lto_file_data != alias->lto_file_data)
741 local_original->merged = true;
743 /* Remove the function's body. */
744 ipa_merge_profiles (original, alias);
745 alias->release_body (true);
746 alias->reset ();
748 /* Create the alias. */
749 cgraph_node::create_alias (alias_func->decl, decl);
750 alias->resolve_alias (original);
752 original->call_for_symbol_thunks_and_aliases
753 (set_local, (void *)(size_t) original->local_p (), true);
755 if (dump_file)
756 fprintf (dump_file, "Callgraph alias has been created.\n\n");
758 else if (create_thunk)
760 if (DECL_COMDAT_GROUP (alias->decl))
762 if (dump_file)
763 fprintf (dump_file, "Callgraph thunk cannot be created because of COMDAT\n");
765 return 0;
768 if (DECL_STATIC_CHAIN (alias->decl))
770 if (dump_file)
771 fprintf (dump_file, "Thunk creation is risky for static-chain functions.\n\n");
773 return 0;
776 alias->icf_merged = true;
777 if (local_original->lto_file_data
778 && alias->lto_file_data
779 && local_original->lto_file_data != alias->lto_file_data)
780 local_original->merged = true;
781 ipa_merge_profiles (local_original, alias, true);
782 alias->create_wrapper (local_original);
784 if (dump_file)
785 fprintf (dump_file, "Callgraph thunk has been created.\n\n");
787 else if (dump_file)
788 fprintf (dump_file, "Callgraph merge operation cannot be performed.\n\n");
790 return true;
793 /* Semantic item initialization function. */
795 void
796 sem_function::init (void)
798 if (in_lto_p)
799 get_node ()->get_untransformed_body ();
801 tree fndecl = node->decl;
802 function *func = DECL_STRUCT_FUNCTION (fndecl);
804 gcc_assert (func);
805 gcc_assert (SSANAMES (func));
807 ssa_names_size = SSANAMES (func)->length ();
808 node = node;
810 decl = fndecl;
811 region_tree = func->eh->region_tree;
813 /* iterating all function arguments. */
814 arg_count = count_formal_params (fndecl);
816 edge_count = n_edges_for_fn (func);
817 cfg_checksum = coverage_compute_cfg_checksum (func);
819 inchash::hash hstate;
821 basic_block bb;
822 FOR_EACH_BB_FN (bb, func)
824 unsigned nondbg_stmt_count = 0;
826 edge e;
827 for (edge_iterator ei = ei_start (bb->preds); ei_cond (ei, &e); ei_next (&ei))
828 cfg_checksum = iterative_hash_host_wide_int (e->flags,
829 cfg_checksum);
831 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
832 gsi_next (&gsi))
834 gimple stmt = gsi_stmt (gsi);
836 if (gimple_code (stmt) != GIMPLE_DEBUG)
838 hash_stmt (&hstate, stmt);
839 nondbg_stmt_count++;
843 gcode_hash = hstate.end ();
844 bb_sizes.safe_push (nondbg_stmt_count);
846 /* Inserting basic block to hash table. */
847 sem_bb *semantic_bb = new sem_bb (bb, nondbg_stmt_count,
848 EDGE_COUNT (bb->preds) + EDGE_COUNT (bb->succs));
850 bb_sorted.safe_push (semantic_bb);
853 parse_tree_args ();
856 /* Improve accumulated hash for HSTATE based on a gimple statement STMT. */
858 void
859 sem_function::hash_stmt (inchash::hash *hstate, gimple stmt)
861 enum gimple_code code = gimple_code (stmt);
863 hstate->add_int (code);
865 if (code == GIMPLE_CALL)
867 /* Checking of argument. */
868 for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i)
870 tree argument = gimple_call_arg (stmt, i);
872 switch (TREE_CODE (argument))
874 case INTEGER_CST:
875 if (tree_fits_shwi_p (argument))
876 hstate->add_wide_int (tree_to_shwi (argument));
877 else if (tree_fits_uhwi_p (argument))
878 hstate->add_wide_int (tree_to_uhwi (argument));
879 break;
880 case REAL_CST:
881 REAL_VALUE_TYPE c;
882 HOST_WIDE_INT n;
884 c = TREE_REAL_CST (argument);
885 n = real_to_integer (&c);
887 hstate->add_wide_int (n);
888 break;
889 case ADDR_EXPR:
891 tree addr_operand = TREE_OPERAND (argument, 0);
893 if (TREE_CODE (addr_operand) == STRING_CST)
894 hstate->add (TREE_STRING_POINTER (addr_operand),
895 TREE_STRING_LENGTH (addr_operand));
896 break;
898 default:
899 break;
906 /* Return true if polymorphic comparison must be processed. */
908 bool
909 sem_function::compare_polymorphic_p (void)
911 return get_node ()->callees != NULL
912 || get_node ()->indirect_calls != NULL
913 || m_compared_func->get_node ()->callees != NULL
914 || m_compared_func->get_node ()->indirect_calls != NULL;
917 /* For a given call graph NODE, the function constructs new
918 semantic function item. */
920 sem_function *
921 sem_function::parse (cgraph_node *node, bitmap_obstack *stack)
923 tree fndecl = node->decl;
924 function *func = DECL_STRUCT_FUNCTION (fndecl);
926 /* TODO: add support for thunks and aliases. */
928 if (!func || !node->has_gimple_body_p ())
929 return NULL;
931 if (lookup_attribute_by_prefix ("omp ", DECL_ATTRIBUTES (node->decl)) != NULL)
932 return NULL;
934 sem_function *f = new sem_function (node, 0, stack);
936 f->init ();
938 return f;
941 /* Parses function arguments and result type. */
943 void
944 sem_function::parse_tree_args (void)
946 tree result;
948 if (arg_types.exists ())
949 arg_types.release ();
951 arg_types.create (4);
952 tree fnargs = DECL_ARGUMENTS (decl);
954 for (tree parm = fnargs; parm; parm = DECL_CHAIN (parm))
955 arg_types.safe_push (DECL_ARG_TYPE (parm));
957 /* Function result type. */
958 result = DECL_RESULT (decl);
959 result_type = result ? TREE_TYPE (result) : NULL;
961 /* During WPA, we can get arguments by following method. */
962 if (!fnargs)
964 tree type = TYPE_ARG_TYPES (TREE_TYPE (decl));
965 for (tree parm = type; parm; parm = TREE_CHAIN (parm))
966 arg_types.safe_push (TYPE_CANONICAL (TREE_VALUE (parm)));
968 result_type = TREE_TYPE (TREE_TYPE (decl));
972 /* For given basic blocks BB1 and BB2 (from functions FUNC1 and FUNC),
973 return true if phi nodes are semantically equivalent in these blocks . */
975 bool
976 sem_function::compare_phi_node (basic_block bb1, basic_block bb2)
978 gphi_iterator si1, si2;
979 gphi *phi1, *phi2;
980 unsigned size1, size2, i;
981 tree t1, t2;
982 edge e1, e2;
984 gcc_assert (bb1 != NULL);
985 gcc_assert (bb2 != NULL);
987 si2 = gsi_start_phis (bb2);
988 for (si1 = gsi_start_phis (bb1); !gsi_end_p (si1);
989 gsi_next (&si1))
991 gsi_next_nonvirtual_phi (&si1);
992 gsi_next_nonvirtual_phi (&si2);
994 if (gsi_end_p (si1) && gsi_end_p (si2))
995 break;
997 if (gsi_end_p (si1) || gsi_end_p (si2))
998 return return_false();
1000 phi1 = si1.phi ();
1001 phi2 = si2.phi ();
1003 tree phi_result1 = gimple_phi_result (phi1);
1004 tree phi_result2 = gimple_phi_result (phi2);
1006 if (!m_checker->compare_operand (phi_result1, phi_result2))
1007 return return_false_with_msg ("PHI results are different");
1009 size1 = gimple_phi_num_args (phi1);
1010 size2 = gimple_phi_num_args (phi2);
1012 if (size1 != size2)
1013 return return_false ();
1015 for (i = 0; i < size1; ++i)
1017 t1 = gimple_phi_arg (phi1, i)->def;
1018 t2 = gimple_phi_arg (phi2, i)->def;
1020 if (!m_checker->compare_operand (t1, t2))
1021 return return_false ();
1023 e1 = gimple_phi_arg_edge (phi1, i);
1024 e2 = gimple_phi_arg_edge (phi2, i);
1026 if (!m_checker->compare_edge (e1, e2))
1027 return return_false ();
1030 gsi_next (&si2);
1033 return true;
1036 /* Returns true if tree T can be compared as a handled component. */
1038 bool
1039 sem_function::icf_handled_component_p (tree t)
1041 tree_code tc = TREE_CODE (t);
1043 return ((handled_component_p (t))
1044 || tc == ADDR_EXPR || tc == MEM_REF || tc == REALPART_EXPR
1045 || tc == IMAGPART_EXPR || tc == OBJ_TYPE_REF);
1048 /* Basic blocks dictionary BB_DICT returns true if SOURCE index BB
1049 corresponds to TARGET. */
1051 bool
1052 sem_function::bb_dict_test (vec<int> *bb_dict, int source, int target)
1054 source++;
1055 target++;
1057 if (bb_dict->length () <= (unsigned)source)
1058 bb_dict->safe_grow_cleared (source + 1);
1060 if ((*bb_dict)[source] == 0)
1062 (*bb_dict)[source] = target;
1063 return true;
1065 else
1066 return (*bb_dict)[source] == target;
1069 /* Iterates all tree types in T1 and T2 and returns true if all types
1070 are compatible. If COMPARE_POLYMORPHIC is set to true,
1071 more strict comparison is executed. */
1073 bool
1074 sem_function::compare_type_list (tree t1, tree t2, bool compare_polymorphic)
1076 tree tv1, tv2;
1077 tree_code tc1, tc2;
1079 if (!t1 && !t2)
1080 return true;
1082 while (t1 != NULL && t2 != NULL)
1084 tv1 = TREE_VALUE (t1);
1085 tv2 = TREE_VALUE (t2);
1087 tc1 = TREE_CODE (tv1);
1088 tc2 = TREE_CODE (tv2);
1090 if (tc1 == NOP_EXPR && tc2 == NOP_EXPR)
1092 else if (tc1 == NOP_EXPR || tc2 == NOP_EXPR)
1093 return false;
1094 else if (!func_checker::compatible_types_p (tv1, tv2, compare_polymorphic))
1095 return false;
1097 t1 = TREE_CHAIN (t1);
1098 t2 = TREE_CHAIN (t2);
1101 return !(t1 || t2);
1105 /* Semantic variable constructor that uses STACK as bitmap memory stack. */
1107 sem_variable::sem_variable (bitmap_obstack *stack): sem_item (VAR, stack)
1111 /* Constructor based on varpool node _NODE with computed hash _HASH.
1112 Bitmap STACK is used for memory allocation. */
1114 sem_variable::sem_variable (varpool_node *node, hashval_t _hash,
1115 bitmap_obstack *stack): sem_item(VAR,
1116 node, _hash, stack)
1118 gcc_checking_assert (node);
1119 gcc_checking_assert (get_node ());
1122 /* Returns true if the item equals to ITEM given as argument. */
1124 bool
1125 sem_variable::equals (sem_item *item,
1126 hash_map <symtab_node *, sem_item *> & ARG_UNUSED (ignored_nodes))
1128 gcc_assert (item->type == VAR);
1130 sem_variable *v = static_cast<sem_variable *>(item);
1132 if (!ctor || !v->ctor)
1133 return return_false_with_msg ("ctor is missing for semantic variable");
1135 return sem_variable::equals (ctor, v->ctor);
1138 /* Compares trees T1 and T2 for semantic equality. */
1140 bool
1141 sem_variable::equals (tree t1, tree t2)
1143 tree_code tc1 = TREE_CODE (t1);
1144 tree_code tc2 = TREE_CODE (t2);
1146 if (tc1 != tc2)
1147 return false;
1149 switch (tc1)
1151 case CONSTRUCTOR:
1153 unsigned len1 = vec_safe_length (CONSTRUCTOR_ELTS (t1));
1154 unsigned len2 = vec_safe_length (CONSTRUCTOR_ELTS (t2));
1156 if (len1 != len2)
1157 return false;
1159 for (unsigned i = 0; i < len1; i++)
1160 if (!sem_variable::equals (CONSTRUCTOR_ELT (t1, i)->value,
1161 CONSTRUCTOR_ELT (t2, i)->value)
1162 || CONSTRUCTOR_ELT (t1, i)->index != CONSTRUCTOR_ELT (t2, i)->index)
1163 return false;
1165 return true;
1167 case MEM_REF:
1169 tree x1 = TREE_OPERAND (t1, 0);
1170 tree x2 = TREE_OPERAND (t2, 0);
1171 tree y1 = TREE_OPERAND (t1, 1);
1172 tree y2 = TREE_OPERAND (t2, 1);
1174 if (!func_checker::compatible_types_p (TREE_TYPE (x1), TREE_TYPE (x2),
1175 true))
1176 return return_false ();
1178 /* Type of the offset on MEM_REF does not matter. */
1179 return sem_variable::equals (x1, x2)
1180 && wi::to_offset (y1) == wi::to_offset (y2);
1182 case NOP_EXPR:
1183 case ADDR_EXPR:
1185 tree op1 = TREE_OPERAND (t1, 0);
1186 tree op2 = TREE_OPERAND (t2, 0);
1187 return sem_variable::equals (op1, op2);
1189 case FUNCTION_DECL:
1190 case VAR_DECL:
1191 case FIELD_DECL:
1192 case LABEL_DECL:
1193 return t1 == t2;
1194 case INTEGER_CST:
1195 return func_checker::compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2),
1196 true)
1197 && wi::to_offset (t1) == wi::to_offset (t2);
1198 case STRING_CST:
1199 case REAL_CST:
1200 case COMPLEX_CST:
1201 return operand_equal_p (t1, t2, OEP_ONLY_CONST);
1202 case COMPONENT_REF:
1203 case ARRAY_REF:
1204 case POINTER_PLUS_EXPR:
1206 tree x1 = TREE_OPERAND (t1, 0);
1207 tree x2 = TREE_OPERAND (t2, 0);
1208 tree y1 = TREE_OPERAND (t1, 1);
1209 tree y2 = TREE_OPERAND (t2, 1);
1211 return sem_variable::equals (x1, x2) && sem_variable::equals (y1, y2);
1213 case ERROR_MARK:
1214 return return_false_with_msg ("ERROR_MARK");
1215 default:
1216 return return_false_with_msg ("Unknown TREE code reached");
1220 /* Parser function that visits a varpool NODE. */
1222 sem_variable *
1223 sem_variable::parse (varpool_node *node, bitmap_obstack *stack)
1225 tree decl = node->decl;
1227 bool readonly = TYPE_P (decl) ? TYPE_READONLY (decl) : TREE_READONLY (decl);
1228 if (!readonly)
1229 return NULL;
1231 bool can_handle = DECL_VIRTUAL_P (decl)
1232 || flag_merge_constants >= 2
1233 || (!TREE_ADDRESSABLE (decl) && !node->externally_visible);
1235 if (!can_handle || DECL_EXTERNAL (decl))
1236 return NULL;
1238 tree ctor = ctor_for_folding (decl);
1239 if (!ctor)
1240 return NULL;
1242 sem_variable *v = new sem_variable (node, 0, stack);
1244 v->init ();
1246 return v;
1249 /* References independent hash function. */
1251 hashval_t
1252 sem_variable::get_hash (void)
1254 if (hash)
1255 return hash;
1257 inchash::hash hstate;
1259 hstate.add_int (456346417);
1260 hstate.add_int (TREE_CODE (ctor));
1262 if (TREE_CODE (ctor) == CONSTRUCTOR)
1264 unsigned length = vec_safe_length (CONSTRUCTOR_ELTS (ctor));
1265 hstate.add_int (length);
1268 hash = hstate.end ();
1270 return hash;
1273 /* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can
1274 be applied. */
1276 bool
1277 sem_variable::merge (sem_item *alias_item)
1279 gcc_assert (alias_item->type == VAR);
1281 if (!sem_item::target_supports_symbol_aliases_p ())
1283 if (dump_file)
1284 fprintf (dump_file, "Symbol aliases are not supported by target\n\n");
1285 return false;
1288 sem_variable *alias_var = static_cast<sem_variable *> (alias_item);
1290 varpool_node *original = get_node ();
1291 varpool_node *alias = alias_var->get_node ();
1292 bool original_discardable = false;
1294 /* See if original is in a section that can be discarded if the main
1295 symbol is not used. */
1296 if (DECL_EXTERNAL (original->decl))
1297 original_discardable = true;
1298 if (original->resolution == LDPR_PREEMPTED_REG
1299 || original->resolution == LDPR_PREEMPTED_IR)
1300 original_discardable = true;
1301 if (original->can_be_discarded_p ())
1302 original_discardable = true;
1304 gcc_assert (!TREE_ASM_WRITTEN (alias->decl));
1306 if (original_discardable || DECL_EXTERNAL (alias_var->decl) ||
1307 !compare_sections (alias_var))
1309 if (dump_file)
1310 fprintf (dump_file, "Varpool alias cannot be created\n\n");
1312 return false;
1314 else
1316 // alias cycle creation check
1317 varpool_node *n = original;
1319 while (n->alias)
1321 n = n->get_alias_target ();
1322 if (n == alias)
1324 if (dump_file)
1325 fprintf (dump_file, "Varpool alias cannot be created (alias cycle).\n\n");
1327 return false;
1331 alias->analyzed = false;
1333 DECL_INITIAL (alias->decl) = NULL;
1334 alias->need_bounds_init = false;
1335 alias->remove_all_references ();
1337 varpool_node::create_alias (alias_var->decl, decl);
1338 alias->resolve_alias (original);
1340 if (dump_file)
1341 fprintf (dump_file, "Varpool alias has been created.\n\n");
1343 return true;
1347 bool
1348 sem_variable::compare_sections (sem_variable *alias)
1350 const char *source = node->get_section ();
1351 const char *target = alias->node->get_section();
1353 if (source == NULL && target == NULL)
1354 return true;
1355 else if(!source || !target)
1356 return false;
1357 else
1358 return strcmp (source, target) == 0;
1361 /* Dump symbol to FILE. */
1363 void
1364 sem_variable::dump_to_file (FILE *file)
1366 gcc_assert (file);
1368 print_node (file, "", decl, 0);
1369 fprintf (file, "\n\n");
1372 /* Iterates though a constructor and identifies tree references
1373 we are interested in semantic function equality. */
1375 void
1376 sem_variable::parse_tree_refs (tree t)
1378 switch (TREE_CODE (t))
1380 case CONSTRUCTOR:
1382 unsigned length = vec_safe_length (CONSTRUCTOR_ELTS (t));
1384 for (unsigned i = 0; i < length; i++)
1385 parse_tree_refs(CONSTRUCTOR_ELT (t, i)->value);
1387 break;
1389 case NOP_EXPR:
1390 case ADDR_EXPR:
1392 tree op = TREE_OPERAND (t, 0);
1393 parse_tree_refs (op);
1394 break;
1396 case FUNCTION_DECL:
1398 tree_refs.safe_push (t);
1399 break;
1401 default:
1402 break;
1406 unsigned int sem_item_optimizer::class_id = 0;
1408 sem_item_optimizer::sem_item_optimizer (): worklist (0), m_classes (0),
1409 m_classes_count (0), m_cgraph_node_hooks (NULL), m_varpool_node_hooks (NULL)
1411 m_items.create (0);
1412 bitmap_obstack_initialize (&m_bmstack);
1415 sem_item_optimizer::~sem_item_optimizer ()
1417 for (unsigned int i = 0; i < m_items.length (); i++)
1418 delete m_items[i];
1420 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
1421 it != m_classes.end (); ++it)
1423 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
1424 delete (*it)->classes[i];
1426 (*it)->classes.release ();
1427 free (*it);
1430 m_items.release ();
1432 bitmap_obstack_release (&m_bmstack);
1435 /* Write IPA ICF summary for symbols. */
1437 void
1438 sem_item_optimizer::write_summary (void)
1440 unsigned int count = 0;
1442 output_block *ob = create_output_block (LTO_section_ipa_icf);
1443 lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
1444 ob->symbol = NULL;
1446 /* Calculate number of symbols to be serialized. */
1447 for (lto_symtab_encoder_iterator lsei = lsei_start_in_partition (encoder);
1448 !lsei_end_p (lsei);
1449 lsei_next_in_partition (&lsei))
1451 symtab_node *node = lsei_node (lsei);
1453 if (m_symtab_node_map.get (node))
1454 count++;
1457 streamer_write_uhwi (ob, count);
1459 /* Process all of the symbols. */
1460 for (lto_symtab_encoder_iterator lsei = lsei_start_in_partition (encoder);
1461 !lsei_end_p (lsei);
1462 lsei_next_in_partition (&lsei))
1464 symtab_node *node = lsei_node (lsei);
1466 sem_item **item = m_symtab_node_map.get (node);
1468 if (item && *item)
1470 int node_ref = lto_symtab_encoder_encode (encoder, node);
1471 streamer_write_uhwi_stream (ob->main_stream, node_ref);
1473 streamer_write_uhwi (ob, (*item)->get_hash ());
1477 streamer_write_char_stream (ob->main_stream, 0);
1478 produce_asm (ob, NULL);
1479 destroy_output_block (ob);
1482 /* Reads a section from LTO stream file FILE_DATA. Input block for DATA
1483 contains LEN bytes. */
1485 void
1486 sem_item_optimizer::read_section (lto_file_decl_data *file_data,
1487 const char *data, size_t len)
1489 const lto_function_header *header =
1490 (const lto_function_header *) data;
1491 const int cfg_offset = sizeof (lto_function_header);
1492 const int main_offset = cfg_offset + header->cfg_size;
1493 const int string_offset = main_offset + header->main_size;
1494 data_in *data_in;
1495 unsigned int i;
1496 unsigned int count;
1498 lto_input_block ib_main ((const char *) data + main_offset, 0,
1499 header->main_size);
1501 data_in =
1502 lto_data_in_create (file_data, (const char *) data + string_offset,
1503 header->string_size, vNULL);
1505 count = streamer_read_uhwi (&ib_main);
1507 for (i = 0; i < count; i++)
1509 unsigned int index;
1510 symtab_node *node;
1511 lto_symtab_encoder_t encoder;
1513 index = streamer_read_uhwi (&ib_main);
1514 encoder = file_data->symtab_node_encoder;
1515 node = lto_symtab_encoder_deref (encoder, index);
1517 hashval_t hash = streamer_read_uhwi (&ib_main);
1519 gcc_assert (node->definition);
1521 if (dump_file)
1522 fprintf (dump_file, "Symbol added:%s (tree: %p, uid:%u)\n", node->asm_name (),
1523 (void *) node->decl, node->order);
1525 if (is_a<cgraph_node *> (node))
1527 cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
1529 m_items.safe_push (new sem_function (cnode, hash, &m_bmstack));
1531 else
1533 varpool_node *vnode = dyn_cast <varpool_node *> (node);
1535 m_items.safe_push (new sem_variable (vnode, hash, &m_bmstack));
1539 lto_free_section_data (file_data, LTO_section_ipa_icf, NULL, data,
1540 len);
1541 lto_data_in_delete (data_in);
1544 /* Read IPA IPA ICF summary for symbols. */
1546 void
1547 sem_item_optimizer::read_summary (void)
1549 lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
1550 lto_file_decl_data *file_data;
1551 unsigned int j = 0;
1553 while ((file_data = file_data_vec[j++]))
1555 size_t len;
1556 const char *data = lto_get_section_data (file_data,
1557 LTO_section_ipa_icf, NULL, &len);
1559 if (data)
1560 read_section (file_data, data, len);
1564 /* Register callgraph and varpool hooks. */
1566 void
1567 sem_item_optimizer::register_hooks (void)
1569 if (!m_cgraph_node_hooks)
1570 m_cgraph_node_hooks = symtab->add_cgraph_removal_hook
1571 (&sem_item_optimizer::cgraph_removal_hook, this);
1573 if (!m_varpool_node_hooks)
1574 m_varpool_node_hooks = symtab->add_varpool_removal_hook
1575 (&sem_item_optimizer::varpool_removal_hook, this);
1578 /* Unregister callgraph and varpool hooks. */
1580 void
1581 sem_item_optimizer::unregister_hooks (void)
1583 if (m_cgraph_node_hooks)
1584 symtab->remove_cgraph_removal_hook (m_cgraph_node_hooks);
1586 if (m_varpool_node_hooks)
1587 symtab->remove_varpool_removal_hook (m_varpool_node_hooks);
1590 /* Adds a CLS to hashtable associated by hash value. */
1592 void
1593 sem_item_optimizer::add_class (congruence_class *cls)
1595 gcc_assert (cls->members.length ());
1597 congruence_class_group *group = get_group_by_hash (
1598 cls->members[0]->get_hash (),
1599 cls->members[0]->type);
1600 group->classes.safe_push (cls);
1603 /* Gets a congruence class group based on given HASH value and TYPE. */
1605 congruence_class_group *
1606 sem_item_optimizer::get_group_by_hash (hashval_t hash, sem_item_type type)
1608 congruence_class_group *item = XNEW (congruence_class_group);
1609 item->hash = hash;
1610 item->type = type;
1612 congruence_class_group **slot = m_classes.find_slot (item, INSERT);
1614 if (*slot)
1615 free (item);
1616 else
1618 item->classes.create (1);
1619 *slot = item;
1622 return *slot;
1625 /* Callgraph removal hook called for a NODE with a custom DATA. */
1627 void
1628 sem_item_optimizer::cgraph_removal_hook (cgraph_node *node, void *data)
1630 sem_item_optimizer *optimizer = (sem_item_optimizer *) data;
1631 optimizer->remove_symtab_node (node);
1634 /* Varpool removal hook called for a NODE with a custom DATA. */
1636 void
1637 sem_item_optimizer::varpool_removal_hook (varpool_node *node, void *data)
1639 sem_item_optimizer *optimizer = (sem_item_optimizer *) data;
1640 optimizer->remove_symtab_node (node);
1643 /* Remove symtab NODE triggered by symtab removal hooks. */
1645 void
1646 sem_item_optimizer::remove_symtab_node (symtab_node *node)
1648 gcc_assert (!m_classes.elements());
1650 m_removed_items_set.add (node);
1653 void
1654 sem_item_optimizer::remove_item (sem_item *item)
1656 if (m_symtab_node_map.get (item->node))
1657 m_symtab_node_map.remove (item->node);
1658 delete item;
1661 /* Removes all callgraph and varpool nodes that are marked by symtab
1662 as deleted. */
1664 void
1665 sem_item_optimizer::filter_removed_items (void)
1667 auto_vec <sem_item *> filtered;
1669 for (unsigned int i = 0; i < m_items.length(); i++)
1671 sem_item *item = m_items[i];
1673 if (m_removed_items_set.contains (item->node))
1675 remove_item (item);
1676 continue;
1679 if (item->type == FUNC)
1681 cgraph_node *cnode = static_cast <sem_function *>(item)->get_node ();
1683 bool no_body_function = in_lto_p && (cnode->alias || cnode->body_removed);
1684 if (no_body_function || !opt_for_fn (item->decl, flag_ipa_icf_functions)
1685 || DECL_CXX_CONSTRUCTOR_P (item->decl)
1686 || DECL_CXX_DESTRUCTOR_P (item->decl))
1687 remove_item (item);
1688 else
1689 filtered.safe_push (item);
1691 else /* VAR. */
1693 if (!flag_ipa_icf_variables)
1694 remove_item (item);
1695 else
1696 filtered.safe_push (item);
1700 /* Clean-up of released semantic items. */
1702 m_items.release ();
1703 for (unsigned int i = 0; i < filtered.length(); i++)
1704 m_items.safe_push (filtered[i]);
1707 /* Optimizer entry point. */
1709 void
1710 sem_item_optimizer::execute (void)
1712 filter_removed_items ();
1713 unregister_hooks ();
1715 build_hash_based_classes ();
1717 if (dump_file)
1718 fprintf (dump_file, "Dump after hash based groups\n");
1719 dump_cong_classes ();
1721 for (unsigned int i = 0; i < m_items.length(); i++)
1722 m_items[i]->init_wpa ();
1724 build_graph ();
1726 subdivide_classes_by_equality (true);
1728 if (dump_file)
1729 fprintf (dump_file, "Dump after WPA based types groups\n");
1731 dump_cong_classes ();
1733 process_cong_reduction ();
1734 verify_classes ();
1736 if (dump_file)
1737 fprintf (dump_file, "Dump after callgraph-based congruence reduction\n");
1739 dump_cong_classes ();
1741 parse_nonsingleton_classes ();
1742 subdivide_classes_by_equality ();
1744 if (dump_file)
1745 fprintf (dump_file, "Dump after full equality comparison of groups\n");
1747 dump_cong_classes ();
1749 unsigned int prev_class_count = m_classes_count;
1751 process_cong_reduction ();
1752 dump_cong_classes ();
1753 verify_classes ();
1754 merge_classes (prev_class_count);
1756 if (dump_file && (dump_flags & TDF_DETAILS))
1757 symtab_node::dump_table (dump_file);
1760 /* Function responsible for visiting all potential functions and
1761 read-only variables that can be merged. */
1763 void
1764 sem_item_optimizer::parse_funcs_and_vars (void)
1766 cgraph_node *cnode;
1768 if (flag_ipa_icf_functions)
1769 FOR_EACH_DEFINED_FUNCTION (cnode)
1771 sem_function *f = sem_function::parse (cnode, &m_bmstack);
1772 if (f)
1774 m_items.safe_push (f);
1775 m_symtab_node_map.put (cnode, f);
1777 if (dump_file)
1778 fprintf (dump_file, "Parsed function:%s\n", f->asm_name ());
1780 if (dump_file && (dump_flags & TDF_DETAILS))
1781 f->dump_to_file (dump_file);
1783 else if (dump_file)
1784 fprintf (dump_file, "Not parsed function:%s\n", cnode->asm_name ());
1787 varpool_node *vnode;
1789 if (flag_ipa_icf_variables)
1790 FOR_EACH_DEFINED_VARIABLE (vnode)
1792 sem_variable *v = sem_variable::parse (vnode, &m_bmstack);
1794 if (v)
1796 m_items.safe_push (v);
1797 m_symtab_node_map.put (vnode, v);
1802 /* Makes pairing between a congruence class CLS and semantic ITEM. */
1804 void
1805 sem_item_optimizer::add_item_to_class (congruence_class *cls, sem_item *item)
1807 item->index_in_class = cls->members.length ();
1808 cls->members.safe_push (item);
1809 item->cls = cls;
1812 /* Congruence classes are built by hash value. */
1814 void
1815 sem_item_optimizer::build_hash_based_classes (void)
1817 for (unsigned i = 0; i < m_items.length (); i++)
1819 sem_item *item = m_items[i];
1821 congruence_class_group *group = get_group_by_hash (item->get_hash (),
1822 item->type);
1824 if (!group->classes.length ())
1826 m_classes_count++;
1827 group->classes.safe_push (new congruence_class (class_id++));
1830 add_item_to_class (group->classes[0], item);
1834 /* Build references according to call graph. */
1836 void
1837 sem_item_optimizer::build_graph (void)
1839 for (unsigned i = 0; i < m_items.length (); i++)
1841 sem_item *item = m_items[i];
1842 m_symtab_node_map.put (item->node, item);
1845 for (unsigned i = 0; i < m_items.length (); i++)
1847 sem_item *item = m_items[i];
1849 if (item->type == FUNC)
1851 cgraph_node *cnode = dyn_cast <cgraph_node *> (item->node);
1853 cgraph_edge *e = cnode->callees;
1854 while (e)
1856 sem_item **slot = m_symtab_node_map.get (e->callee);
1857 if (slot)
1858 item->add_reference (*slot);
1860 e = e->next_callee;
1864 ipa_ref *ref = NULL;
1865 for (unsigned i = 0; item->node->iterate_reference (i, ref); i++)
1867 sem_item **slot = m_symtab_node_map.get (ref->referred);
1868 if (slot)
1869 item->add_reference (*slot);
1874 /* Semantic items in classes having more than one element and initialized.
1875 In case of WPA, we load function body. */
1877 void
1878 sem_item_optimizer::parse_nonsingleton_classes (void)
1880 unsigned int init_called_count = 0;
1882 for (unsigned i = 0; i < m_items.length (); i++)
1883 if (m_items[i]->cls->members.length () > 1)
1885 m_items[i]->init ();
1886 init_called_count++;
1889 if (dump_file)
1890 fprintf (dump_file, "Init called for %u items (%.2f%%).\n", init_called_count,
1891 m_items.length () ? 100.0f * init_called_count / m_items.length (): 0.0f);
1894 /* Equality function for semantic items is used to subdivide existing
1895 classes. If IN_WPA, fast equality function is invoked. */
1897 void
1898 sem_item_optimizer::subdivide_classes_by_equality (bool in_wpa)
1900 for (hash_table <congruence_class_group_hash>::iterator it = m_classes.begin ();
1901 it != m_classes.end (); ++it)
1903 unsigned int class_count = (*it)->classes.length ();
1905 for (unsigned i = 0; i < class_count; i++)
1907 congruence_class *c = (*it)->classes [i];
1909 if (c->members.length() > 1)
1911 auto_vec <sem_item *> new_vector;
1913 sem_item *first = c->members[0];
1914 new_vector.safe_push (first);
1916 unsigned class_split_first = (*it)->classes.length ();
1918 for (unsigned j = 1; j < c->members.length (); j++)
1920 sem_item *item = c->members[j];
1922 bool equals = in_wpa ? first->equals_wpa (item,
1923 m_symtab_node_map) : first->equals (item, m_symtab_node_map);
1925 if (equals)
1926 new_vector.safe_push (item);
1927 else
1929 bool integrated = false;
1931 for (unsigned k = class_split_first; k < (*it)->classes.length (); k++)
1933 sem_item *x = (*it)->classes[k]->members[0];
1934 bool equals = in_wpa ? x->equals_wpa (item,
1935 m_symtab_node_map) : x->equals (item, m_symtab_node_map);
1937 if (equals)
1939 integrated = true;
1940 add_item_to_class ((*it)->classes[k], item);
1942 break;
1946 if (!integrated)
1948 congruence_class *c = new congruence_class (class_id++);
1949 m_classes_count++;
1950 add_item_to_class (c, item);
1952 (*it)->classes.safe_push (c);
1957 // we replace newly created new_vector for the class we've just splitted
1958 c->members.release ();
1959 c->members.create (new_vector.length ());
1961 for (unsigned int j = 0; j < new_vector.length (); j++)
1962 add_item_to_class (c, new_vector[j]);
1967 verify_classes ();
1970 /* Verify congruence classes if checking is enabled. */
1972 void
1973 sem_item_optimizer::verify_classes (void)
1975 #if ENABLE_CHECKING
1976 for (hash_table <congruence_class_group_hash>::iterator it = m_classes.begin ();
1977 it != m_classes.end (); ++it)
1979 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
1981 congruence_class *cls = (*it)->classes[i];
1983 gcc_checking_assert (cls);
1984 gcc_checking_assert (cls->members.length () > 0);
1986 for (unsigned int j = 0; j < cls->members.length (); j++)
1988 sem_item *item = cls->members[j];
1990 gcc_checking_assert (item);
1991 gcc_checking_assert (item->cls == cls);
1993 for (unsigned k = 0; k < item->usages.length (); k++)
1995 sem_usage_pair *usage = item->usages[k];
1996 gcc_checking_assert (usage->item->index_in_class <
1997 usage->item->cls->members.length ());
2002 #endif
2005 /* Disposes split map traverse function. CLS_PTR is pointer to congruence
2006 class, BSLOT is bitmap slot we want to release. DATA is mandatory,
2007 but unused argument. */
2009 bool
2010 sem_item_optimizer::release_split_map (congruence_class * const &,
2011 bitmap const &b, traverse_split_pair *)
2013 bitmap bmp = b;
2015 BITMAP_FREE (bmp);
2017 return true;
2020 /* Process split operation for a class given as pointer CLS_PTR,
2021 where bitmap B splits congruence class members. DATA is used
2022 as argument of split pair. */
2024 bool
2025 sem_item_optimizer::traverse_congruence_split (congruence_class * const &cls,
2026 bitmap const &b, traverse_split_pair *pair)
2028 sem_item_optimizer *optimizer = pair->optimizer;
2029 const congruence_class *splitter_cls = pair->cls;
2031 /* If counted bits are greater than zero and less than the number of members
2032 a group will be splitted. */
2033 unsigned popcount = bitmap_count_bits (b);
2035 if (popcount > 0 && popcount < cls->members.length ())
2037 congruence_class* newclasses[2] = { new congruence_class (class_id++), new congruence_class (class_id++) };
2039 for (unsigned int i = 0; i < cls->members.length (); i++)
2041 int target = bitmap_bit_p (b, i);
2042 congruence_class *tc = newclasses[target];
2044 add_item_to_class (tc, cls->members[i]);
2047 #ifdef ENABLE_CHECKING
2048 for (unsigned int i = 0; i < 2; i++)
2049 gcc_checking_assert (newclasses[i]->members.length ());
2050 #endif
2052 if (splitter_cls == cls)
2053 optimizer->splitter_class_removed = true;
2055 /* Remove old class from worklist if presented. */
2056 bool in_worklist = cls->in_worklist;
2058 if (in_worklist)
2059 cls->in_worklist = false;
2061 congruence_class_group g;
2062 g.hash = cls->members[0]->get_hash ();
2063 g.type = cls->members[0]->type;
2065 congruence_class_group *slot = optimizer->m_classes.find(&g);
2067 for (unsigned int i = 0; i < slot->classes.length (); i++)
2068 if (slot->classes[i] == cls)
2070 slot->classes.ordered_remove (i);
2071 break;
2074 /* New class will be inserted and integrated to work list. */
2075 for (unsigned int i = 0; i < 2; i++)
2076 optimizer->add_class (newclasses[i]);
2078 /* Two classes replace one, so that increment just by one. */
2079 optimizer->m_classes_count++;
2081 /* If OLD class was presented in the worklist, we remove the class
2082 and replace it will both newly created classes. */
2083 if (in_worklist)
2084 for (unsigned int i = 0; i < 2; i++)
2085 optimizer->worklist_push (newclasses[i]);
2086 else /* Just smaller class is inserted. */
2088 unsigned int smaller_index = newclasses[0]->members.length () <
2089 newclasses[1]->members.length () ?
2090 0 : 1;
2091 optimizer->worklist_push (newclasses[smaller_index]);
2094 if (dump_file && (dump_flags & TDF_DETAILS))
2096 fprintf (dump_file, " congruence class splitted:\n");
2097 cls->dump (dump_file, 4);
2099 fprintf (dump_file, " newly created groups:\n");
2100 for (unsigned int i = 0; i < 2; i++)
2101 newclasses[i]->dump (dump_file, 4);
2104 /* Release class if not presented in work list. */
2105 if (!in_worklist)
2106 delete cls;
2110 return true;
2113 /* Tests if a class CLS used as INDEXth splits any congruence classes.
2114 Bitmap stack BMSTACK is used for bitmap allocation. */
2116 void
2117 sem_item_optimizer::do_congruence_step_for_index (congruence_class *cls,
2118 unsigned int index)
2120 hash_map <congruence_class *, bitmap> split_map;
2122 for (unsigned int i = 0; i < cls->members.length (); i++)
2124 sem_item *item = cls->members[i];
2126 /* Iterate all usages that have INDEX as usage of the item. */
2127 for (unsigned int j = 0; j < item->usages.length (); j++)
2129 sem_usage_pair *usage = item->usages[j];
2131 if (usage->index != index)
2132 continue;
2134 bitmap *slot = split_map.get (usage->item->cls);
2135 bitmap b;
2137 if(!slot)
2139 b = BITMAP_ALLOC (&m_bmstack);
2140 split_map.put (usage->item->cls, b);
2142 else
2143 b = *slot;
2145 #if ENABLE_CHECKING
2146 gcc_checking_assert (usage->item->cls);
2147 gcc_checking_assert (usage->item->index_in_class <
2148 usage->item->cls->members.length ());
2149 #endif
2151 bitmap_set_bit (b, usage->item->index_in_class);
2155 traverse_split_pair pair;
2156 pair.optimizer = this;
2157 pair.cls = cls;
2159 splitter_class_removed = false;
2160 split_map.traverse
2161 <traverse_split_pair *, sem_item_optimizer::traverse_congruence_split> (&pair);
2163 /* Bitmap clean-up. */
2164 split_map.traverse
2165 <traverse_split_pair *, sem_item_optimizer::release_split_map> (NULL);
2168 /* Every usage of a congruence class CLS is a candidate that can split the
2169 collection of classes. Bitmap stack BMSTACK is used for bitmap
2170 allocation. */
2172 void
2173 sem_item_optimizer::do_congruence_step (congruence_class *cls)
2175 bitmap_iterator bi;
2176 unsigned int i;
2178 bitmap usage = BITMAP_ALLOC (&m_bmstack);
2180 for (unsigned int i = 0; i < cls->members.length (); i++)
2181 bitmap_ior_into (usage, cls->members[i]->usage_index_bitmap);
2183 EXECUTE_IF_SET_IN_BITMAP (usage, 0, i, bi)
2185 if (dump_file && (dump_flags & TDF_DETAILS))
2186 fprintf (dump_file, " processing congruece step for class: %u, index: %u\n",
2187 cls->id, i);
2189 do_congruence_step_for_index (cls, i);
2191 if (splitter_class_removed)
2192 break;
2195 BITMAP_FREE (usage);
2198 /* Adds a newly created congruence class CLS to worklist. */
2200 void
2201 sem_item_optimizer::worklist_push (congruence_class *cls)
2203 /* Return if the class CLS is already presented in work list. */
2204 if (cls->in_worklist)
2205 return;
2207 cls->in_worklist = true;
2208 worklist.push_back (cls);
2211 /* Pops a class from worklist. */
2213 congruence_class *
2214 sem_item_optimizer::worklist_pop (void)
2216 congruence_class *cls;
2218 while (!worklist.empty ())
2220 cls = worklist.front ();
2221 worklist.pop_front ();
2222 if (cls->in_worklist)
2224 cls->in_worklist = false;
2226 return cls;
2228 else
2230 /* Work list item was already intended to be removed.
2231 The only reason for doing it is to split a class.
2232 Thus, the class CLS is deleted. */
2233 delete cls;
2237 return NULL;
2240 /* Iterative congruence reduction function. */
2242 void
2243 sem_item_optimizer::process_cong_reduction (void)
2245 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2246 it != m_classes.end (); ++it)
2247 for (unsigned i = 0; i < (*it)->classes.length (); i++)
2248 if ((*it)->classes[i]->is_class_used ())
2249 worklist_push ((*it)->classes[i]);
2251 if (dump_file)
2252 fprintf (dump_file, "Worklist has been filled with: %lu\n",
2253 (unsigned long) worklist.size ());
2255 if (dump_file && (dump_flags & TDF_DETAILS))
2256 fprintf (dump_file, "Congruence class reduction\n");
2258 congruence_class *cls;
2259 while ((cls = worklist_pop ()) != NULL)
2260 do_congruence_step (cls);
2263 /* Debug function prints all informations about congruence classes. */
2265 void
2266 sem_item_optimizer::dump_cong_classes (void)
2268 if (!dump_file)
2269 return;
2271 fprintf (dump_file,
2272 "Congruence classes: %u (unique hash values: %lu), with total: %u items\n",
2273 m_classes_count, (unsigned long) m_classes.elements(), m_items.length ());
2275 /* Histogram calculation. */
2276 unsigned int max_index = 0;
2277 unsigned int* histogram = XCNEWVEC (unsigned int, m_items.length () + 1);
2279 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2280 it != m_classes.end (); ++it)
2282 for (unsigned i = 0; i < (*it)->classes.length (); i++)
2284 unsigned int c = (*it)->classes[i]->members.length ();
2285 histogram[c]++;
2287 if (c > max_index)
2288 max_index = c;
2291 fprintf (dump_file,
2292 "Class size histogram [num of members]: number of classe number of classess\n");
2294 for (unsigned int i = 0; i <= max_index; i++)
2295 if (histogram[i])
2296 fprintf (dump_file, "[%u]: %u classes\n", i, histogram[i]);
2298 fprintf (dump_file, "\n\n");
2301 if (dump_flags & TDF_DETAILS)
2302 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2303 it != m_classes.end (); ++it)
2305 fprintf (dump_file, " group: with %u classes:\n", (*it)->classes.length ());
2307 for (unsigned i = 0; i < (*it)->classes.length (); i++)
2309 (*it)->classes[i]->dump (dump_file, 4);
2311 if(i < (*it)->classes.length () - 1)
2312 fprintf (dump_file, " ");
2316 free (histogram);
2319 /* After reduction is done, we can declare all items in a group
2320 to be equal. PREV_CLASS_COUNT is start number of classes
2321 before reduction. */
2323 void
2324 sem_item_optimizer::merge_classes (unsigned int prev_class_count)
2326 unsigned int item_count = m_items.length ();
2327 unsigned int class_count = m_classes_count;
2328 unsigned int equal_items = item_count - class_count;
2330 unsigned int non_singular_classes_count = 0;
2331 unsigned int non_singular_classes_sum = 0;
2333 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2334 it != m_classes.end (); ++it)
2335 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
2337 congruence_class *c = (*it)->classes[i];
2338 if (c->members.length () > 1)
2340 non_singular_classes_count++;
2341 non_singular_classes_sum += c->members.length ();
2345 if (dump_file)
2347 fprintf (dump_file, "\nItem count: %u\n", item_count);
2348 fprintf (dump_file, "Congruent classes before: %u, after: %u\n",
2349 prev_class_count, class_count);
2350 fprintf (dump_file, "Average class size before: %.2f, after: %.2f\n",
2351 prev_class_count ? 1.0f * item_count / prev_class_count : 0.0f,
2352 class_count ? 1.0f * item_count / class_count : 0.0f);
2353 fprintf (dump_file, "Average non-singular class size: %.2f, count: %u\n",
2354 non_singular_classes_count ? 1.0f * non_singular_classes_sum /
2355 non_singular_classes_count : 0.0f,
2356 non_singular_classes_count);
2357 fprintf (dump_file, "Equal symbols: %u\n", equal_items);
2358 fprintf (dump_file, "Fraction of visited symbols: %.2f%%\n\n",
2359 item_count ? 100.0f * equal_items / item_count : 0.0f);
2362 for (hash_table<congruence_class_group_hash>::iterator it = m_classes.begin ();
2363 it != m_classes.end (); ++it)
2364 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
2366 congruence_class *c = (*it)->classes[i];
2368 if (c->members.length () == 1)
2369 continue;
2371 gcc_assert (c->members.length ());
2373 sem_item *source = c->members[0];
2375 for (unsigned int j = 1; j < c->members.length (); j++)
2377 sem_item *alias = c->members[j];
2379 if (dump_file)
2381 fprintf (dump_file, "Semantic equality hit:%s->%s\n",
2382 source->name (), alias->name ());
2383 fprintf (dump_file, "Assembler symbol names:%s->%s\n",
2384 source->asm_name (), alias->asm_name ());
2387 if (lookup_attribute ("no_icf", DECL_ATTRIBUTES (alias->decl)))
2389 if (dump_file)
2390 fprintf (dump_file,
2391 "Merge operation is skipped due to no_icf "
2392 "attribute.\n\n");
2394 continue;
2397 if (dump_file && (dump_flags & TDF_DETAILS))
2399 source->dump_to_file (dump_file);
2400 alias->dump_to_file (dump_file);
2403 source->merge (alias);
2408 /* Dump function prints all class members to a FILE with an INDENT. */
2410 void
2411 congruence_class::dump (FILE *file, unsigned int indent) const
2413 FPRINTF_SPACES (file, indent, "class with id: %u, hash: %u, items: %u\n",
2414 id, members[0]->get_hash (), members.length ());
2416 FPUTS_SPACES (file, indent + 2, "");
2417 for (unsigned i = 0; i < members.length (); i++)
2418 fprintf (file, "%s(%p/%u) ", members[i]->asm_name (), (void *) members[i]->decl,
2419 members[i]->node->order);
2421 fprintf (file, "\n");
2424 /* Returns true if there's a member that is used from another group. */
2426 bool
2427 congruence_class::is_class_used (void)
2429 for (unsigned int i = 0; i < members.length (); i++)
2430 if (members[i]->usages.length ())
2431 return true;
2433 return false;
2436 /* Initialization and computation of symtab node hash, there data
2437 are propagated later on. */
2439 static sem_item_optimizer *optimizer = NULL;
2441 /* Generate pass summary for IPA ICF pass. */
2443 static void
2444 ipa_icf_generate_summary (void)
2446 if (!optimizer)
2447 optimizer = new sem_item_optimizer ();
2449 optimizer->register_hooks ();
2450 optimizer->parse_funcs_and_vars ();
2453 /* Write pass summary for IPA ICF pass. */
2455 static void
2456 ipa_icf_write_summary (void)
2458 gcc_assert (optimizer);
2460 optimizer->write_summary ();
2463 /* Read pass summary for IPA ICF pass. */
2465 static void
2466 ipa_icf_read_summary (void)
2468 if (!optimizer)
2469 optimizer = new sem_item_optimizer ();
2471 optimizer->read_summary ();
2472 optimizer->register_hooks ();
2475 /* Semantic equality exection function. */
2477 static unsigned int
2478 ipa_icf_driver (void)
2480 gcc_assert (optimizer);
2482 optimizer->execute ();
2484 delete optimizer;
2485 optimizer = NULL;
2487 return 0;
2490 const pass_data pass_data_ipa_icf =
2492 IPA_PASS, /* type */
2493 "icf", /* name */
2494 OPTGROUP_IPA, /* optinfo_flags */
2495 TV_IPA_ICF, /* tv_id */
2496 0, /* properties_required */
2497 0, /* properties_provided */
2498 0, /* properties_destroyed */
2499 0, /* todo_flags_start */
2500 0, /* todo_flags_finish */
2503 class pass_ipa_icf : public ipa_opt_pass_d
2505 public:
2506 pass_ipa_icf (gcc::context *ctxt)
2507 : ipa_opt_pass_d (pass_data_ipa_icf, ctxt,
2508 ipa_icf_generate_summary, /* generate_summary */
2509 ipa_icf_write_summary, /* write_summary */
2510 ipa_icf_read_summary, /* read_summary */
2511 NULL, /*
2512 write_optimization_summary */
2513 NULL, /*
2514 read_optimization_summary */
2515 NULL, /* stmt_fixup */
2516 0, /* function_transform_todo_flags_start */
2517 NULL, /* function_transform */
2518 NULL) /* variable_transform */
2521 /* opt_pass methods: */
2522 virtual bool gate (function *)
2524 return in_lto_p || flag_ipa_icf_variables || flag_ipa_icf_functions;
2527 virtual unsigned int execute (function *)
2529 return ipa_icf_driver();
2531 }; // class pass_ipa_icf
2533 } // ipa_icf namespace
2535 ipa_opt_pass_d *
2536 make_pass_ipa_icf (gcc::context *ctxt)
2538 return new ipa_icf::pass_ipa_icf (ctxt);