OpenMP: Update documentation of metadirective implementation status.
[gcc.git] / gcc / ipa-icf.cc
blob3fccc620a82f43a8e3fb7180c3a3a1f42d5482a9
1 /* Interprocedural Identical Code Folding pass
2 Copyright (C) 2014-2025 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 "backend.h"
58 #include "target.h"
59 #include "rtl.h"
60 #include "tree.h"
61 #include "gimple.h"
62 #include "alloc-pool.h"
63 #include "tree-pass.h"
64 #include "ssa.h"
65 #include "cgraph.h"
66 #include "coverage.h"
67 #include "gimple-pretty-print.h"
68 #include "data-streamer.h"
69 #include "tree-streamer.h"
70 #include "fold-const.h"
71 #include "calls.h"
72 #include "varasm.h"
73 #include "gimple-iterator.h"
74 #include "tree-cfg.h"
75 #include "symbol-summary.h"
76 #include "sreal.h"
77 #include "ipa-cp.h"
78 #include "ipa-prop.h"
79 #include "ipa-fnsummary.h"
80 #include "except.h"
81 #include "attribs.h"
82 #include "print-tree.h"
83 #include "ipa-utils.h"
84 #include "tree-ssa-alias-compare.h"
85 #include "ipa-icf-gimple.h"
86 #include "fibonacci_heap.h"
87 #include "ipa-icf.h"
88 #include "stor-layout.h"
89 #include "dbgcnt.h"
90 #include "tree-vector-builder.h"
91 #include "symtab-thunks.h"
92 #include "alias.h"
93 #include "asan.h"
95 using namespace ipa_icf_gimple;
97 namespace ipa_icf {
99 /* Initialization and computation of symtab node hash, there data
100 are propagated later on. */
102 static sem_item_optimizer *optimizer = NULL;
104 /* Constructor. */
106 symbol_compare_collection::symbol_compare_collection (symtab_node *node)
108 m_references.create (0);
109 m_interposables.create (0);
111 ipa_ref *ref;
113 if (is_a <varpool_node *> (node) && DECL_VIRTUAL_P (node->decl))
114 return;
116 for (unsigned i = 0; node->iterate_reference (i, ref); i++)
118 if (ref->address_matters_p ())
119 m_references.safe_push (ref->referred);
121 if (ref->referred->get_availability () <= AVAIL_INTERPOSABLE)
123 if (ref->address_matters_p ())
124 m_references.safe_push (ref->referred);
125 else
126 m_interposables.safe_push (ref->referred);
130 if (is_a <cgraph_node *> (node))
132 cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
134 for (cgraph_edge *e = cnode->callees; e; e = e->next_callee)
135 if (e->callee->get_availability () <= AVAIL_INTERPOSABLE)
136 m_interposables.safe_push (e->callee);
140 /* Constructor for key value pair, where _ITEM is key and _INDEX is a target. */
142 sem_usage_pair::sem_usage_pair (sem_item *_item, unsigned int _index)
143 : item (_item), index (_index)
147 sem_item::sem_item (sem_item_type _type, bitmap_obstack *stack)
148 : type (_type), referenced_by_count (0), m_hash (-1), m_hash_set (false)
150 setup (stack);
153 sem_item::sem_item (sem_item_type _type, symtab_node *_node,
154 bitmap_obstack *stack)
155 : type (_type), node (_node), referenced_by_count (0), m_hash (-1),
156 m_hash_set (false)
158 decl = node->decl;
159 setup (stack);
162 /* Add reference to a semantic TARGET. */
164 void
165 sem_item::add_reference (ref_map *refs,
166 sem_item *target)
168 unsigned index = reference_count++;
169 bool existed;
171 sem_usage_pair *pair = new sem_usage_pair (target, index);
172 vec<sem_item *> &v = refs->get_or_insert (pair, &existed);
173 if (existed)
174 delete pair;
176 v.safe_push (this);
177 bitmap_set_bit (target->usage_index_bitmap, index);
178 refs_set.add (target->node);
179 ++target->referenced_by_count;
182 /* Initialize internal data structures. Bitmap STACK is used for
183 bitmap memory allocation process. */
185 void
186 sem_item::setup (bitmap_obstack *stack)
188 gcc_checking_assert (node);
190 reference_count = 0;
191 tree_refs.create (0);
192 usage_index_bitmap = BITMAP_ALLOC (stack);
195 sem_item::~sem_item ()
197 tree_refs.release ();
199 BITMAP_FREE (usage_index_bitmap);
202 /* Dump function for debugging purpose. */
204 DEBUG_FUNCTION void
205 sem_item::dump (void)
207 if (dump_file)
209 fprintf (dump_file, "[%s] %s (tree:%p)\n", type == FUNC ? "func" : "var",
210 node->dump_name (), (void *) node->decl);
211 fprintf (dump_file, " hash: %u\n", get_hash ());
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 gcc_checking_assert (TARGET_SUPPORTS_ALIASES);
224 return true;
225 #endif
228 void sem_item::set_hash (hashval_t hash)
230 m_hash = hash;
231 m_hash_set = true;
234 hash_map<const_tree, hashval_t> sem_item::m_type_hash_cache;
236 /* Semantic function constructor that uses STACK as bitmap memory stack. */
238 sem_function::sem_function (bitmap_obstack *stack)
239 : sem_item (FUNC, stack), memory_access_types (), m_alias_sets_hash (0),
240 m_checker (NULL), m_compared_func (NULL)
242 bb_sizes.create (0);
243 bb_sorted.create (0);
246 sem_function::sem_function (cgraph_node *node, bitmap_obstack *stack)
247 : sem_item (FUNC, node, stack), memory_access_types (),
248 m_alias_sets_hash (0), m_checker (NULL), m_compared_func (NULL)
250 bb_sizes.create (0);
251 bb_sorted.create (0);
254 sem_function::~sem_function ()
256 for (unsigned i = 0; i < bb_sorted.length (); i++)
257 delete (bb_sorted[i]);
259 bb_sizes.release ();
260 bb_sorted.release ();
263 /* Calculates hash value based on a BASIC_BLOCK. */
265 hashval_t
266 sem_function::get_bb_hash (const sem_bb *basic_block)
268 inchash::hash hstate;
270 hstate.add_int (basic_block->nondbg_stmt_count);
271 hstate.add_int (basic_block->edge_count);
273 return hstate.end ();
276 /* References independent hash function. */
278 hashval_t
279 sem_function::get_hash (void)
281 if (!m_hash_set)
283 inchash::hash hstate;
284 hstate.add_int (177454); /* Random number for function type. */
286 hstate.add_int (arg_count);
287 hstate.add_int (cfg_checksum);
288 hstate.add_int (gcode_hash);
290 for (unsigned i = 0; i < bb_sorted.length (); i++)
291 hstate.merge_hash (get_bb_hash (bb_sorted[i]));
293 for (unsigned i = 0; i < bb_sizes.length (); i++)
294 hstate.add_int (bb_sizes[i]);
296 /* Add common features of declaration itself. */
297 if (DECL_FUNCTION_SPECIFIC_TARGET (decl))
298 hstate.add_hwi
299 (cl_target_option_hash
300 (TREE_TARGET_OPTION (DECL_FUNCTION_SPECIFIC_TARGET (decl))));
301 if (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl))
302 hstate.add_hwi
303 (cl_optimization_hash
304 (TREE_OPTIMIZATION (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl))));
305 hstate.add_flag (DECL_CXX_CONSTRUCTOR_P (decl));
306 hstate.add_flag (DECL_CXX_DESTRUCTOR_P (decl));
307 hstate.add_flag (DECL_STATIC_CHAIN (decl));
309 set_hash (hstate.end ());
312 return m_hash;
315 /* Compare properties of symbols N1 and N2 that does not affect semantics of
316 symbol itself but affects semantics of its references from USED_BY (which
317 may be NULL if it is unknown). If comparison is false, symbols
318 can still be merged but any symbols referring them can't.
320 If ADDRESS is true, do extra checking needed for IPA_REF_ADDR.
322 TODO: We can also split attributes to those that determine codegen of
323 a function body/variable constructor itself and those that are used when
324 referring to it. */
326 bool
327 sem_item::compare_referenced_symbol_properties (symtab_node *used_by,
328 symtab_node *n1,
329 symtab_node *n2,
330 bool address)
332 if (is_a <cgraph_node *> (n1))
334 /* Inline properties matters: we do now want to merge uses of inline
335 function to uses of normal function because inline hint would be lost.
336 We however can merge inline function to noinline because the alias
337 will keep its DECL_DECLARED_INLINE flag.
339 Also ignore inline flag when optimizing for size or when function
340 is known to not be inlinable.
342 TODO: the optimize_size checks can also be assumed to be true if
343 unit has no !optimize_size functions. */
345 if ((!used_by || address || !is_a <cgraph_node *> (used_by)
346 || !opt_for_fn (used_by->decl, optimize_size))
347 && !opt_for_fn (n1->decl, optimize_size)
348 && n1->get_availability () > AVAIL_INTERPOSABLE
349 && (!DECL_UNINLINABLE (n1->decl) || !DECL_UNINLINABLE (n2->decl)))
351 if (DECL_DISREGARD_INLINE_LIMITS (n1->decl)
352 != DECL_DISREGARD_INLINE_LIMITS (n2->decl))
353 return return_false_with_msg
354 ("DECL_DISREGARD_INLINE_LIMITS are different");
356 if (DECL_DECLARED_INLINE_P (n1->decl)
357 != DECL_DECLARED_INLINE_P (n2->decl))
358 return return_false_with_msg ("inline attributes are different");
361 if (DECL_IS_OPERATOR_NEW_P (n1->decl)
362 != DECL_IS_OPERATOR_NEW_P (n2->decl))
363 return return_false_with_msg ("operator new flags are different");
365 if (DECL_IS_REPLACEABLE_OPERATOR (n1->decl)
366 != DECL_IS_REPLACEABLE_OPERATOR (n2->decl))
367 return return_false_with_msg ("replaceable operator flags are different");
370 /* Merging two definitions with a reference to equivalent vtables, but
371 belonging to a different type may result in ipa-polymorphic-call analysis
372 giving a wrong answer about the dynamic type of instance. */
373 if (is_a <varpool_node *> (n1))
375 if ((DECL_VIRTUAL_P (n1->decl) || DECL_VIRTUAL_P (n2->decl))
376 && (DECL_VIRTUAL_P (n1->decl) != DECL_VIRTUAL_P (n2->decl)
377 || !types_must_be_same_for_odr (DECL_CONTEXT (n1->decl),
378 DECL_CONTEXT (n2->decl)))
379 && (!used_by || !is_a <cgraph_node *> (used_by) || address
380 || opt_for_fn (used_by->decl, flag_devirtualize)))
381 return return_false_with_msg
382 ("references to virtual tables cannot be merged");
384 if (address && DECL_ALIGN (n1->decl) != DECL_ALIGN (n2->decl))
385 return return_false_with_msg ("alignment mismatch");
387 /* For functions we compare attributes in equals_wpa, because we do
388 not know what attributes may cause codegen differences, but for
389 variables just compare attributes for references - the codegen
390 for constructors is affected only by those attributes that we lower
391 to explicit representation (such as DECL_ALIGN or DECL_SECTION). */
392 if (!attribute_list_equal (DECL_ATTRIBUTES (n1->decl),
393 DECL_ATTRIBUTES (n2->decl)))
394 return return_false_with_msg ("different var decl attributes");
395 if (comp_type_attributes (TREE_TYPE (n1->decl),
396 TREE_TYPE (n2->decl)) != 1)
397 return return_false_with_msg ("different var type attributes");
400 /* When matching virtual tables, be sure to also match information
401 relevant for polymorphic call analysis. */
402 if (used_by && is_a <varpool_node *> (used_by)
403 && DECL_VIRTUAL_P (used_by->decl))
405 if (DECL_VIRTUAL_P (n1->decl) != DECL_VIRTUAL_P (n2->decl))
406 return return_false_with_msg ("virtual flag mismatch");
407 if (DECL_VIRTUAL_P (n1->decl) && is_a <cgraph_node *> (n1)
408 && (DECL_FINAL_P (n1->decl) != DECL_FINAL_P (n2->decl)))
409 return return_false_with_msg ("final flag mismatch");
411 return true;
414 /* Hash properties that are compared by compare_referenced_symbol_properties. */
416 void
417 sem_item::hash_referenced_symbol_properties (symtab_node *ref,
418 inchash::hash &hstate,
419 bool address)
421 if (is_a <cgraph_node *> (ref))
423 if ((type != FUNC || address || !opt_for_fn (decl, optimize_size))
424 && !opt_for_fn (ref->decl, optimize_size)
425 && !DECL_UNINLINABLE (ref->decl))
427 hstate.add_flag (DECL_DISREGARD_INLINE_LIMITS (ref->decl));
428 hstate.add_flag (DECL_DECLARED_INLINE_P (ref->decl));
430 hstate.add_flag (DECL_IS_OPERATOR_NEW_P (ref->decl));
432 else if (is_a <varpool_node *> (ref))
434 hstate.add_flag (DECL_VIRTUAL_P (ref->decl));
435 if (address)
436 hstate.add_int (DECL_ALIGN (ref->decl));
441 /* For a given symbol table nodes N1 and N2, we check that FUNCTION_DECLs
442 point to a same function. Comparison can be skipped if IGNORED_NODES
443 contains these nodes. ADDRESS indicate if address is taken. */
445 bool
446 sem_item::compare_symbol_references (
447 hash_map <symtab_node *, sem_item *> &ignored_nodes,
448 symtab_node *n1, symtab_node *n2, bool address)
450 enum availability avail1, avail2;
452 if (n1 == n2)
453 return true;
455 /* Never match variable and function. */
456 if (is_a <varpool_node *> (n1) != is_a <varpool_node *> (n2))
457 return false;
459 if (!compare_referenced_symbol_properties (node, n1, n2, address))
460 return false;
461 if (address && n1->equal_address_to (n2) == 1)
462 return true;
463 if (!address && n1->semantically_equivalent_p (n2))
464 return true;
466 n1 = n1->ultimate_alias_target (&avail1);
467 n2 = n2->ultimate_alias_target (&avail2);
469 if (avail1 > AVAIL_INTERPOSABLE && ignored_nodes.get (n1)
470 && avail2 > AVAIL_INTERPOSABLE && ignored_nodes.get (n2))
471 return true;
473 return return_false_with_msg ("different references");
476 /* If cgraph edges E1 and E2 are indirect calls, verify that
477 ECF flags are the same. */
479 bool sem_function::compare_edge_flags (cgraph_edge *e1, cgraph_edge *e2)
481 if (e1->indirect_info && e2->indirect_info)
483 int e1_flags = e1->indirect_info->ecf_flags;
484 int e2_flags = e2->indirect_info->ecf_flags;
486 if (e1_flags != e2_flags)
487 return return_false_with_msg ("ICF flags are different");
489 else if (e1->indirect_info || e2->indirect_info)
490 return false;
492 return true;
495 /* Return true if parameter I may be used. */
497 bool
498 sem_function::param_used_p (unsigned int i)
500 if (ipa_node_params_sum == NULL)
501 return true;
503 ipa_node_params *parms_info = ipa_node_params_sum->get (get_node ());
505 if (!parms_info || vec_safe_length (parms_info->descriptors) <= i)
506 return true;
508 return ipa_is_param_used (parms_info, i);
511 /* Perform additional check needed to match types function parameters that are
512 used. Unlike for normal decls it matters if type is TYPE_RESTRICT and we
513 make an assumption that REFERENCE_TYPE parameters are always non-NULL. */
515 bool
516 sem_function::compatible_parm_types_p (tree parm1, tree parm2)
518 /* Be sure that parameters are TBAA compatible. */
519 if (!func_checker::compatible_types_p (parm1, parm2))
520 return return_false_with_msg ("parameter type is not compatible");
522 if (POINTER_TYPE_P (parm1)
523 && (TYPE_RESTRICT (parm1) != TYPE_RESTRICT (parm2)))
524 return return_false_with_msg ("argument restrict flag mismatch");
526 /* nonnull_arg_p implies non-zero range to REFERENCE types. */
527 if (POINTER_TYPE_P (parm1)
528 && TREE_CODE (parm1) != TREE_CODE (parm2)
529 && opt_for_fn (decl, flag_delete_null_pointer_checks))
530 return return_false_with_msg ("pointer wrt reference mismatch");
532 return true;
535 /* Fast equality function based on knowledge known in WPA. */
537 bool
538 sem_function::equals_wpa (sem_item *item,
539 hash_map <symtab_node *, sem_item *> &ignored_nodes)
541 gcc_assert (item->type == FUNC);
542 cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
543 cgraph_node *cnode2 = dyn_cast <cgraph_node *> (item->node);
545 m_compared_func = static_cast<sem_function *> (item);
547 if (cnode->thunk != cnode2->thunk)
548 return return_false_with_msg ("thunk mismatch");
549 if (cnode->former_thunk_p () != cnode2->former_thunk_p ())
550 return return_false_with_msg ("former_thunk_p mismatch");
552 if ((cnode->thunk || cnode->former_thunk_p ())
553 && thunk_info::get (cnode) != thunk_info::get (cnode2))
554 return return_false_with_msg ("thunk_info mismatch");
556 /* Compare special function DECL attributes. */
557 if (DECL_FUNCTION_PERSONALITY (decl)
558 != DECL_FUNCTION_PERSONALITY (item->decl))
559 return return_false_with_msg ("function personalities are different");
561 if (DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl)
562 != DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (item->decl))
563 return return_false_with_msg ("instrument function entry exit "
564 "attributes are different");
566 if (DECL_NO_LIMIT_STACK (decl) != DECL_NO_LIMIT_STACK (item->decl))
567 return return_false_with_msg ("no stack limit attributes are different");
569 if (DECL_CXX_CONSTRUCTOR_P (decl) != DECL_CXX_CONSTRUCTOR_P (item->decl))
570 return return_false_with_msg ("DECL_CXX_CONSTRUCTOR mismatch");
572 if (DECL_CXX_DESTRUCTOR_P (decl) != DECL_CXX_DESTRUCTOR_P (item->decl))
573 return return_false_with_msg ("DECL_CXX_DESTRUCTOR mismatch");
575 /* TODO: pure/const flags mostly matters only for references, except for
576 the fact that codegen takes LOOPING flag as a hint that loops are
577 finite. We may arrange the code to always pick leader that has least
578 specified flags and then this can go into comparing symbol properties. */
579 if (flags_from_decl_or_type (decl) != flags_from_decl_or_type (item->decl))
580 return return_false_with_msg ("decl_or_type flags are different");
582 /* Do not match polymorphic constructors of different types. They calls
583 type memory location for ipa-polymorphic-call and we do not want
584 it to get confused by wrong type. */
585 if (DECL_CXX_CONSTRUCTOR_P (decl)
586 && opt_for_fn (decl, flag_devirtualize)
587 && TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
589 if (TREE_CODE (TREE_TYPE (item->decl)) != METHOD_TYPE)
590 return return_false_with_msg ("DECL_CXX_CONSTRUCTOR type mismatch");
591 else if (!func_checker::compatible_polymorphic_types_p
592 (TYPE_METHOD_BASETYPE (TREE_TYPE (decl)),
593 TYPE_METHOD_BASETYPE (TREE_TYPE (item->decl)), false))
594 return return_false_with_msg ("ctor polymorphic type mismatch");
597 /* Checking function TARGET and OPTIMIZATION flags. */
598 cl_target_option *tar1 = target_opts_for_fn (decl);
599 cl_target_option *tar2 = target_opts_for_fn (item->decl);
601 if (tar1 != tar2 && !cl_target_option_eq (tar1, tar2))
603 if (dump_file && (dump_flags & TDF_DETAILS))
605 fprintf (dump_file, "target flags difference");
606 cl_target_option_print_diff (dump_file, 2, tar1, tar2);
609 return return_false_with_msg ("Target flags are different");
612 cl_optimization *opt1 = opts_for_fn (decl);
613 cl_optimization *opt2 = opts_for_fn (item->decl);
615 if (opt1 != opt2 && !cl_optimization_option_eq (opt1, opt2))
617 if (dump_file && (dump_flags & TDF_DETAILS))
619 fprintf (dump_file, "optimization flags difference");
620 cl_optimization_print_diff (dump_file, 2, opt1, opt2);
623 return return_false_with_msg ("optimization flags are different");
626 /* Result type checking. */
627 if (!func_checker::compatible_types_p
628 (TREE_TYPE (TREE_TYPE (decl)),
629 TREE_TYPE (TREE_TYPE (m_compared_func->decl))))
630 return return_false_with_msg ("result types are different");
632 /* Checking types of arguments. */
633 tree list1 = TYPE_ARG_TYPES (TREE_TYPE (decl)),
634 list2 = TYPE_ARG_TYPES (TREE_TYPE (m_compared_func->decl));
635 for (unsigned i = 0; list1 && list2;
636 list1 = TREE_CHAIN (list1), list2 = TREE_CHAIN (list2), i++)
638 tree parm1 = TREE_VALUE (list1);
639 tree parm2 = TREE_VALUE (list2);
641 /* This guard is here for function pointer with attributes (pr59927.c). */
642 if (!parm1 || !parm2)
643 return return_false_with_msg ("NULL argument type");
645 /* Verify that types are compatible to ensure that both functions
646 have same calling conventions. */
647 if (!types_compatible_p (parm1, parm2))
648 return return_false_with_msg ("parameter types are not compatible");
650 if (!param_used_p (i))
651 continue;
653 /* Perform additional checks for used parameters. */
654 if (!compatible_parm_types_p (parm1, parm2))
655 return false;
658 if (list1 || list2)
659 return return_false_with_msg ("mismatched number of parameters");
661 if (DECL_STATIC_CHAIN (decl) != DECL_STATIC_CHAIN (item->decl))
662 return return_false_with_msg ("static chain mismatch");
664 if (node->num_references () != item->node->num_references ())
665 return return_false_with_msg ("different number of references");
667 /* Checking function attributes.
668 This is quadratic in number of attributes */
669 if (comp_type_attributes (TREE_TYPE (decl),
670 TREE_TYPE (item->decl)) != 1)
671 return return_false_with_msg ("different type attributes");
672 if (!attribute_list_equal (DECL_ATTRIBUTES (decl),
673 DECL_ATTRIBUTES (item->decl)))
674 return return_false_with_msg ("different decl attributes");
676 /* The type of THIS pointer type memory location for
677 ipa-polymorphic-call-analysis. */
678 if (opt_for_fn (decl, flag_devirtualize)
679 && (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
680 || TREE_CODE (TREE_TYPE (item->decl)) == METHOD_TYPE)
681 && param_used_p (0)
682 && compare_polymorphic_p ())
684 if (TREE_CODE (TREE_TYPE (decl)) != TREE_CODE (TREE_TYPE (item->decl)))
685 return return_false_with_msg ("METHOD_TYPE and FUNCTION_TYPE mismatch");
686 if (!func_checker::compatible_polymorphic_types_p
687 (TYPE_METHOD_BASETYPE (TREE_TYPE (decl)),
688 TYPE_METHOD_BASETYPE (TREE_TYPE (item->decl)), false))
689 return return_false_with_msg ("THIS pointer ODR type mismatch");
692 ipa_ref *ref = NULL, *ref2 = NULL;
693 for (unsigned i = 0; node->iterate_reference (i, ref); i++)
695 item->node->iterate_reference (i, ref2);
697 if (ref->use != ref2->use)
698 return return_false_with_msg ("reference use mismatch");
700 if (!compare_symbol_references (ignored_nodes, ref->referred,
701 ref2->referred,
702 ref->address_matters_p ()))
703 return false;
706 cgraph_edge *e1 = dyn_cast <cgraph_node *> (node)->callees;
707 cgraph_edge *e2 = dyn_cast <cgraph_node *> (item->node)->callees;
709 while (e1 && e2)
711 if (!compare_symbol_references (ignored_nodes, e1->callee,
712 e2->callee, false))
713 return false;
714 if (!compare_edge_flags (e1, e2))
715 return false;
717 e1 = e1->next_callee;
718 e2 = e2->next_callee;
721 if (e1 || e2)
722 return return_false_with_msg ("different number of calls");
724 e1 = dyn_cast <cgraph_node *> (node)->indirect_calls;
725 e2 = dyn_cast <cgraph_node *> (item->node)->indirect_calls;
727 while (e1 && e2)
729 if (!compare_edge_flags (e1, e2))
730 return false;
732 e1 = e1->next_callee;
733 e2 = e2->next_callee;
736 if (e1 || e2)
737 return return_false_with_msg ("different number of indirect calls");
739 return true;
742 /* Update hash by address sensitive references. We iterate over all
743 sensitive references (address_matters_p) and we hash ultimate alias
744 target of these nodes, which can improve a semantic item hash.
746 Also hash in referenced symbols properties. This can be done at any time
747 (as the properties should not change), but it is convenient to do it here
748 while we walk the references anyway. */
750 void
751 sem_item::update_hash_by_addr_refs (hash_map <symtab_node *,
752 sem_item *> &m_symtab_node_map)
754 ipa_ref* ref;
755 inchash::hash hstate (get_hash ());
757 for (unsigned i = 0; node->iterate_reference (i, ref); i++)
759 hstate.add_int (ref->use);
760 hash_referenced_symbol_properties (ref->referred, hstate,
761 ref->use == IPA_REF_ADDR);
762 if (ref->address_matters_p () || !m_symtab_node_map.get (ref->referred))
763 hstate.add_int (ref->referred->ultimate_alias_target ()->order);
766 if (is_a <cgraph_node *> (node))
768 for (cgraph_edge *e = dyn_cast <cgraph_node *> (node)->callers; e;
769 e = e->next_caller)
771 sem_item **result = m_symtab_node_map.get (e->callee);
772 hash_referenced_symbol_properties (e->callee, hstate, false);
773 if (!result)
774 hstate.add_int (e->callee->ultimate_alias_target ()->order);
778 set_hash (hstate.end ());
781 /* Update hash by computed local hash values taken from different
782 semantic items.
783 TODO: stronger SCC based hashing would be desirable here. */
785 void
786 sem_item::update_hash_by_local_refs (hash_map <symtab_node *,
787 sem_item *> &m_symtab_node_map)
789 ipa_ref* ref;
790 inchash::hash state (get_hash ());
792 for (unsigned j = 0; node->iterate_reference (j, ref); j++)
794 sem_item **result = m_symtab_node_map.get (ref->referring);
795 if (result)
796 state.merge_hash ((*result)->get_hash ());
799 if (type == FUNC)
801 for (cgraph_edge *e = dyn_cast <cgraph_node *> (node)->callees; e;
802 e = e->next_callee)
804 sem_item **result = m_symtab_node_map.get (e->caller);
805 if (result)
806 state.merge_hash ((*result)->get_hash ());
810 global_hash = state.end ();
813 /* Returns true if the item equals to ITEM given as argument. */
815 bool
816 sem_function::equals (sem_item *item,
817 hash_map <symtab_node *, sem_item *> &)
819 gcc_assert (item->type == FUNC);
820 bool eq = equals_private (item);
822 if (m_checker != NULL)
824 delete m_checker;
825 m_checker = NULL;
828 if (dump_file && (dump_flags & TDF_DETAILS))
829 fprintf (dump_file,
830 "Equals called for: %s:%s with result: %s\n\n",
831 node->dump_name (),
832 item->node->dump_name (),
833 eq ? "true" : "false");
835 return eq;
838 /* Processes function equality comparison. */
840 bool
841 sem_function::equals_private (sem_item *item)
843 if (item->type != FUNC)
844 return false;
846 basic_block bb1, bb2;
847 edge e1, e2;
848 edge_iterator ei1, ei2;
849 bool result = true;
850 tree arg1, arg2;
852 m_compared_func = static_cast<sem_function *> (item);
854 gcc_assert (decl != item->decl);
856 if (bb_sorted.length () != m_compared_func->bb_sorted.length ()
857 || edge_count != m_compared_func->edge_count
858 || cfg_checksum != m_compared_func->cfg_checksum)
859 return return_false ();
861 m_checker = new func_checker (decl, m_compared_func->decl,
862 false,
863 opt_for_fn (m_compared_func->decl,
864 flag_strict_aliasing),
865 &refs_set,
866 &m_compared_func->refs_set);
867 arg1 = DECL_ARGUMENTS (decl);
868 arg2 = DECL_ARGUMENTS (m_compared_func->decl);
869 for (unsigned i = 0;
870 arg1 && arg2; arg1 = DECL_CHAIN (arg1), arg2 = DECL_CHAIN (arg2), i++)
872 if (!types_compatible_p (TREE_TYPE (arg1), TREE_TYPE (arg2)))
873 return return_false_with_msg ("argument types are not compatible");
874 if (!param_used_p (i))
875 continue;
876 /* Perform additional checks for used parameters. */
877 if (!compatible_parm_types_p (TREE_TYPE (arg1), TREE_TYPE (arg2)))
878 return false;
879 if (!m_checker->compare_decl (arg1, arg2))
880 return return_false ();
882 if (arg1 || arg2)
883 return return_false_with_msg ("mismatched number of arguments");
885 if (DECL_STATIC_CHAIN (decl) != DECL_STATIC_CHAIN (m_compared_func->decl))
886 return return_false_with_msg ("static chain mismatch");
888 if (!dyn_cast <cgraph_node *> (node)->has_gimple_body_p ())
889 return true;
891 /* Fill-up label dictionary. */
892 for (unsigned i = 0; i < bb_sorted.length (); ++i)
894 m_checker->parse_labels (bb_sorted[i]);
895 m_checker->parse_labels (m_compared_func->bb_sorted[i]);
898 /* Checking all basic blocks. */
899 for (unsigned i = 0; i < bb_sorted.length (); ++i)
900 if(!m_checker->compare_bb (bb_sorted[i], m_compared_func->bb_sorted[i]))
901 return return_false ();
903 auto_vec <int> bb_dict;
905 /* Basic block edges check. */
906 for (unsigned i = 0; i < bb_sorted.length (); ++i)
908 bb1 = bb_sorted[i]->bb;
909 bb2 = m_compared_func->bb_sorted[i]->bb;
911 ei2 = ei_start (bb2->preds);
913 for (ei1 = ei_start (bb1->preds); ei_cond (ei1, &e1); ei_next (&ei1))
915 ei_cond (ei2, &e2);
917 if (e1->flags != e2->flags)
918 return return_false_with_msg ("flags comparison returns false");
920 if (!bb_dict_test (&bb_dict, e1->src->index, e2->src->index))
921 return return_false_with_msg ("edge comparison returns false");
923 if (!bb_dict_test (&bb_dict, e1->dest->index, e2->dest->index))
924 return return_false_with_msg ("BB comparison returns false");
926 if (!m_checker->compare_edge (e1, e2))
927 return return_false_with_msg ("edge comparison returns false");
929 ei_next (&ei2);
933 /* Basic block PHI nodes comparison. */
934 for (unsigned i = 0; i < bb_sorted.length (); i++)
935 if (!compare_phi_node (bb_sorted[i]->bb, m_compared_func->bb_sorted[i]->bb))
936 return return_false_with_msg ("PHI node comparison returns false");
938 return result;
941 /* Set LOCAL_P of NODE to true if DATA is non-NULL.
942 Helper for call_for_symbol_thunks_and_aliases. */
944 static bool
945 set_local (cgraph_node *node, void *data)
947 node->local = data != NULL;
948 return false;
951 /* TREE_ADDRESSABLE of NODE to true.
952 Helper for call_for_symbol_thunks_and_aliases. */
954 static bool
955 set_addressable (varpool_node *node, void *)
957 TREE_ADDRESSABLE (node->decl) = 1;
958 return false;
961 /* Clear DECL_RTL of NODE.
962 Helper for call_for_symbol_thunks_and_aliases. */
964 static bool
965 clear_decl_rtl (symtab_node *node, void *)
967 SET_DECL_RTL (node->decl, NULL);
968 return false;
971 /* Redirect all callers of N and its aliases to TO. Remove aliases if
972 possible. Return number of redirections made. */
974 static int
975 redirect_all_callers (cgraph_node *n, cgraph_node *to)
977 int nredirected = 0;
978 ipa_ref *ref;
979 cgraph_edge *e = n->callers;
981 while (e)
983 /* Redirecting thunks to interposable symbols or symbols in other sections
984 may not be supported by target output code. Play safe for now and
985 punt on redirection. */
986 if (!e->caller->thunk)
988 struct cgraph_edge *nexte = e->next_caller;
989 e->redirect_callee (to);
990 e = nexte;
991 nredirected++;
993 else
994 e = e->next_callee;
996 for (unsigned i = 0; n->iterate_direct_aliases (i, ref);)
998 bool removed = false;
999 cgraph_node *n_alias = dyn_cast <cgraph_node *> (ref->referring);
1001 if ((DECL_COMDAT_GROUP (n->decl)
1002 && (DECL_COMDAT_GROUP (n->decl)
1003 == DECL_COMDAT_GROUP (n_alias->decl)))
1004 || (n_alias->get_availability () > AVAIL_INTERPOSABLE
1005 && n->get_availability () > AVAIL_INTERPOSABLE))
1007 nredirected += redirect_all_callers (n_alias, to);
1008 if (n_alias->can_remove_if_no_direct_calls_p ()
1009 && !n_alias->call_for_symbol_and_aliases (cgraph_node::has_thunk_p,
1010 NULL, true)
1011 && !n_alias->has_aliases_p ())
1012 n_alias->remove ();
1014 if (!removed)
1015 i++;
1017 return nredirected;
1020 /* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can
1021 be applied. */
1023 bool
1024 sem_function::merge (sem_item *alias_item)
1026 gcc_assert (alias_item->type == FUNC);
1028 sem_function *alias_func = static_cast<sem_function *> (alias_item);
1030 cgraph_node *original = get_node ();
1031 cgraph_node *local_original = NULL;
1032 cgraph_node *alias = alias_func->get_node ();
1034 bool create_wrapper = false;
1035 bool create_alias = false;
1036 bool redirect_callers = false;
1037 bool remove = false;
1039 bool original_discardable = false;
1040 bool original_discarded = false;
1042 bool original_address_matters = original->address_matters_p ();
1043 bool alias_address_matters = alias->address_matters_p ();
1045 AUTO_DUMP_SCOPE ("merge",
1046 dump_user_location_t::from_function_decl (decl));
1048 if (DECL_EXTERNAL (alias->decl))
1050 if (dump_enabled_p ())
1051 dump_printf (MSG_MISSED_OPTIMIZATION,
1052 "Not unifying; alias is external.\n");
1053 return false;
1056 if (DECL_NO_INLINE_WARNING_P (original->decl)
1057 != DECL_NO_INLINE_WARNING_P (alias->decl))
1059 if (dump_enabled_p ())
1060 dump_printf (MSG_MISSED_OPTIMIZATION,
1061 "Not unifying; DECL_NO_INLINE_WARNING mismatch.\n");
1062 return false;
1065 /* Do not attempt to mix functions from different user sections;
1066 we do not know what user intends with those. */
1067 if (((DECL_SECTION_NAME (original->decl) && !original->implicit_section)
1068 || (DECL_SECTION_NAME (alias->decl) && !alias->implicit_section))
1069 && DECL_SECTION_NAME (original->decl) != DECL_SECTION_NAME (alias->decl))
1071 if (dump_enabled_p ())
1072 dump_printf (MSG_MISSED_OPTIMIZATION,
1073 "Not unifying; "
1074 "original and alias are in different sections.\n");
1075 return false;
1078 if (!original->in_same_comdat_group_p (alias)
1079 || original->comdat_local_p ())
1081 if (dump_enabled_p ())
1082 dump_printf (MSG_MISSED_OPTIMIZATION,
1083 "Not unifying; alias nor wrapper cannot be created; "
1084 "across comdat group boundary\n");
1085 return false;
1088 /* See if original is in a section that can be discarded if the main
1089 symbol is not used. */
1091 if (original->can_be_discarded_p ())
1092 original_discardable = true;
1093 /* Also consider case where we have resolution info and we know that
1094 original's definition is not going to be used. In this case we cannot
1095 create alias to original. */
1096 if (node->resolution != LDPR_UNKNOWN
1097 && !decl_binds_to_current_def_p (node->decl))
1098 original_discardable = original_discarded = true;
1100 /* Creating a symtab alias is the optimal way to merge.
1101 It however cannot be used in the following cases:
1103 1) if ORIGINAL and ALIAS may be possibly compared for address equality.
1104 2) if ORIGINAL is in a section that may be discarded by linker or if
1105 it is an external functions where we cannot create an alias
1106 (ORIGINAL_DISCARDABLE)
1107 3) if target do not support symbol aliases.
1108 4) original and alias lie in different comdat groups.
1110 If we cannot produce alias, we will turn ALIAS into WRAPPER of ORIGINAL
1111 and/or redirect all callers from ALIAS to ORIGINAL. */
1112 if ((original_address_matters && alias_address_matters)
1113 || (original_discardable
1114 && (!DECL_COMDAT_GROUP (alias->decl)
1115 || (DECL_COMDAT_GROUP (alias->decl)
1116 != DECL_COMDAT_GROUP (original->decl))))
1117 || original_discarded
1118 || !sem_item::target_supports_symbol_aliases_p ()
1119 || DECL_COMDAT_GROUP (alias->decl) != DECL_COMDAT_GROUP (original->decl))
1121 /* First see if we can produce wrapper. */
1123 /* Symbol properties that matter for references must be preserved.
1124 TODO: We can produce wrapper, but we need to produce alias of ORIGINAL
1125 with proper properties. */
1126 if (!sem_item::compare_referenced_symbol_properties (NULL, original, alias,
1127 alias->address_taken))
1129 if (dump_enabled_p ())
1130 dump_printf (MSG_MISSED_OPTIMIZATION,
1131 "Wrapper cannot be created because referenced symbol "
1132 "properties mismatch\n");
1134 /* Do not turn function in one comdat group into wrapper to another
1135 comdat group. Other compiler producing the body of the
1136 another comdat group may make opposite decision and with unfortunate
1137 linker choices this may close a loop. */
1138 else if (DECL_COMDAT_GROUP (original->decl)
1139 && DECL_COMDAT_GROUP (alias->decl)
1140 && (DECL_COMDAT_GROUP (alias->decl)
1141 != DECL_COMDAT_GROUP (original->decl)))
1143 if (dump_enabled_p ())
1144 dump_printf (MSG_MISSED_OPTIMIZATION,
1145 "Wrapper cannot be created because of COMDAT\n");
1147 else if (DECL_STATIC_CHAIN (alias->decl)
1148 || DECL_STATIC_CHAIN (original->decl))
1150 if (dump_enabled_p ())
1151 dump_printf (MSG_MISSED_OPTIMIZATION,
1152 "Cannot create wrapper of nested function.\n");
1154 /* TODO: We can also deal with variadic functions never calling
1155 VA_START. */
1156 else if (stdarg_p (TREE_TYPE (alias->decl)))
1158 if (dump_enabled_p ())
1159 dump_printf (MSG_MISSED_OPTIMIZATION,
1160 "cannot create wrapper of stdarg function.\n");
1162 else if (ipa_fn_summaries
1163 && ipa_size_summaries->get (alias) != NULL
1164 && ipa_size_summaries->get (alias)->self_size <= 2)
1166 if (dump_enabled_p ())
1167 dump_printf (MSG_MISSED_OPTIMIZATION, "Wrapper creation is not "
1168 "profitable (function is too small).\n");
1170 /* If user paid attention to mark function noinline, assume it is
1171 somewhat special and do not try to turn it into a wrapper that
1172 cannot be undone by inliner. */
1173 else if (lookup_attribute ("noinline", DECL_ATTRIBUTES (alias->decl)))
1175 if (dump_enabled_p ())
1176 dump_printf (MSG_MISSED_OPTIMIZATION,
1177 "Wrappers are not created for noinline.\n");
1179 else
1180 create_wrapper = true;
1182 /* We can redirect local calls in the case both alias and original
1183 are not interposable. */
1184 redirect_callers
1185 = alias->get_availability () > AVAIL_INTERPOSABLE
1186 && original->get_availability () > AVAIL_INTERPOSABLE;
1187 /* TODO: We can redirect, but we need to produce alias of ORIGINAL
1188 with proper properties. */
1189 if (!sem_item::compare_referenced_symbol_properties (NULL, original, alias,
1190 alias->address_taken))
1191 redirect_callers = false;
1193 if (!redirect_callers && !create_wrapper)
1195 if (dump_enabled_p ())
1196 dump_printf (MSG_MISSED_OPTIMIZATION,
1197 "Not unifying; cannot redirect callers nor "
1198 "produce wrapper\n");
1199 return false;
1202 /* Work out the symbol the wrapper should call.
1203 If ORIGINAL is interposable, we need to call a local alias.
1204 Also produce local alias (if possible) as an optimization.
1206 Local aliases cannot be created inside comdat groups because that
1207 prevents inlining. */
1208 if (!original_discardable && !original->get_comdat_group ())
1210 local_original
1211 = dyn_cast <cgraph_node *> (original->noninterposable_alias ());
1212 if (!local_original
1213 && original->get_availability () > AVAIL_INTERPOSABLE)
1214 local_original = original;
1216 /* If we cannot use local alias, fallback to the original
1217 when possible. */
1218 else if (original->get_availability () > AVAIL_INTERPOSABLE)
1219 local_original = original;
1221 /* If original is COMDAT local, we cannot really redirect calls outside
1222 of its comdat group to it. */
1223 if (original->comdat_local_p ())
1224 redirect_callers = false;
1225 if (!local_original)
1227 if (dump_enabled_p ())
1228 dump_printf (MSG_MISSED_OPTIMIZATION,
1229 "Not unifying; cannot produce local alias.\n");
1230 return false;
1233 if (!redirect_callers && !create_wrapper)
1235 if (dump_enabled_p ())
1236 dump_printf (MSG_MISSED_OPTIMIZATION,
1237 "Not unifying; "
1238 "cannot redirect callers nor produce a wrapper\n");
1239 return false;
1241 if (!create_wrapper
1242 && !alias->call_for_symbol_and_aliases (cgraph_node::has_thunk_p,
1243 NULL, true)
1244 && !alias->can_remove_if_no_direct_calls_p ())
1246 if (dump_enabled_p ())
1247 dump_printf (MSG_MISSED_OPTIMIZATION,
1248 "Not unifying; cannot make wrapper and "
1249 "function has other uses than direct calls\n");
1250 return false;
1253 else
1254 create_alias = true;
1256 if (redirect_callers)
1258 int nredirected = redirect_all_callers (alias, local_original);
1260 if (nredirected)
1262 alias->icf_merged = true;
1263 local_original->icf_merged = true;
1265 if (dump_enabled_p ())
1266 dump_printf (MSG_NOTE,
1267 "%i local calls have been "
1268 "redirected.\n", nredirected);
1271 /* If all callers was redirected, do not produce wrapper. */
1272 if (alias->can_remove_if_no_direct_calls_p ()
1273 && !DECL_VIRTUAL_P (alias->decl)
1274 && !alias->has_aliases_p ())
1276 create_wrapper = false;
1277 remove = true;
1279 gcc_assert (!create_alias);
1281 else if (create_alias)
1283 alias->icf_merged = true;
1285 /* Remove the function's body. */
1286 ipa_merge_profiles (original, alias);
1287 symtab->call_cgraph_removal_hooks (alias);
1288 alias->release_body (true);
1289 alias->reset ();
1290 /* Notice global symbol possibly produced RTL. */
1291 ((symtab_node *)alias)->call_for_symbol_and_aliases (clear_decl_rtl,
1292 NULL, true);
1294 /* Create the alias. */
1295 cgraph_node::create_alias (alias_func->decl, decl);
1296 alias->resolve_alias (original);
1298 original->call_for_symbol_thunks_and_aliases
1299 (set_local, (void *)(size_t) original->local_p (), true);
1301 if (dump_enabled_p ())
1302 dump_printf (MSG_OPTIMIZED_LOCATIONS,
1303 "Unified; Function alias has been created.\n");
1305 if (create_wrapper)
1307 gcc_assert (!create_alias);
1308 alias->icf_merged = true;
1309 symtab->call_cgraph_removal_hooks (alias);
1310 local_original->icf_merged = true;
1312 /* FIXME update local_original counts. */
1313 ipa_merge_profiles (original, alias, true);
1314 alias->create_wrapper (local_original);
1315 symtab->call_cgraph_insertion_hooks (alias);
1317 if (dump_enabled_p ())
1318 dump_printf (MSG_OPTIMIZED_LOCATIONS,
1319 "Unified; Wrapper has been created.\n");
1322 /* It's possible that redirection can hit thunks that block
1323 redirection opportunities. */
1324 gcc_assert (alias->icf_merged || remove || redirect_callers);
1325 original->icf_merged = true;
1327 /* We use merged flag to track cases where COMDAT function is known to be
1328 compatible its callers. If we merged in non-COMDAT, we need to give up
1329 on this optimization. */
1330 if (original->merged_comdat && !alias->merged_comdat)
1332 if (dump_enabled_p ())
1333 dump_printf (MSG_NOTE, "Dropping merged_comdat flag.\n");
1334 if (local_original)
1335 local_original->merged_comdat = false;
1336 original->merged_comdat = false;
1339 if (remove)
1341 ipa_merge_profiles (original, alias);
1342 alias->release_body ();
1343 alias->reset ();
1344 alias->body_removed = true;
1345 alias->icf_merged = true;
1346 if (dump_enabled_p ())
1347 dump_printf (MSG_OPTIMIZED_LOCATIONS,
1348 "Unified; Function body was removed.\n");
1351 return true;
1354 /* Semantic item initialization function. */
1356 void
1357 sem_function::init (ipa_icf_gimple::func_checker *checker)
1359 m_checker = checker;
1360 if (in_lto_p)
1361 get_node ()->get_untransformed_body ();
1363 tree fndecl = node->decl;
1364 function *func = DECL_STRUCT_FUNCTION (fndecl);
1366 gcc_assert (func);
1367 gcc_assert (SSANAMES (func));
1369 ssa_names_size = SSANAMES (func)->length ();
1370 node = node;
1372 decl = fndecl;
1373 region_tree = func->eh->region_tree;
1375 /* iterating all function arguments. */
1376 arg_count = count_formal_params (fndecl);
1378 edge_count = n_edges_for_fn (func);
1379 cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
1380 if (!cnode->thunk)
1382 cfg_checksum = coverage_compute_cfg_checksum (func);
1384 inchash::hash hstate;
1386 basic_block bb;
1387 FOR_EACH_BB_FN (bb, func)
1389 unsigned nondbg_stmt_count = 0;
1391 edge e;
1392 for (edge_iterator ei = ei_start (bb->preds); ei_cond (ei, &e);
1393 ei_next (&ei))
1394 cfg_checksum = iterative_hash_host_wide_int (e->flags,
1395 cfg_checksum);
1397 /* TODO: We should be able to match PHIs with different order of
1398 parameters. This needs to be also updated in
1399 sem_function::compare_phi_node. */
1400 gphi_iterator si;
1401 for (si = gsi_start_nonvirtual_phis (bb); !gsi_end_p (si);
1402 gsi_next_nonvirtual_phi (&si))
1404 hstate.add_int (GIMPLE_PHI);
1405 gphi *phi = si.phi ();
1406 m_checker->hash_operand (gimple_phi_result (phi), hstate, 0,
1407 func_checker::OP_NORMAL);
1408 hstate.add_int (gimple_phi_num_args (phi));
1409 for (unsigned int i = 0; i < gimple_phi_num_args (phi); i++)
1410 m_checker->hash_operand (gimple_phi_arg_def (phi, i),
1411 hstate, 0, func_checker::OP_NORMAL);
1414 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
1415 gsi_next (&gsi))
1417 gimple *stmt = gsi_stmt (gsi);
1419 if (gimple_code (stmt) != GIMPLE_DEBUG
1420 && gimple_code (stmt) != GIMPLE_PREDICT)
1422 hash_stmt (stmt, hstate);
1423 nondbg_stmt_count++;
1427 hstate.commit_flag ();
1428 gcode_hash = hstate.end ();
1429 bb_sizes.safe_push (nondbg_stmt_count);
1431 /* Inserting basic block to hash table. */
1432 sem_bb *semantic_bb = new sem_bb (bb, nondbg_stmt_count,
1433 EDGE_COUNT (bb->preds)
1434 + EDGE_COUNT (bb->succs));
1436 bb_sorted.safe_push (semantic_bb);
1439 else
1441 cfg_checksum = 0;
1442 gcode_hash = thunk_info::get (cnode)->hash ();
1445 m_checker = NULL;
1448 /* Improve accumulated hash for HSTATE based on a gimple statement STMT. */
1450 void
1451 sem_function::hash_stmt (gimple *stmt, inchash::hash &hstate)
1453 enum gimple_code code = gimple_code (stmt);
1455 hstate.add_int (code);
1457 switch (code)
1459 case GIMPLE_SWITCH:
1460 m_checker->hash_operand (gimple_switch_index (as_a <gswitch *> (stmt)),
1461 hstate, 0, func_checker::OP_NORMAL);
1462 break;
1463 case GIMPLE_ASSIGN:
1464 hstate.add_int (gimple_assign_rhs_code (stmt));
1465 /* fall through */
1466 case GIMPLE_CALL:
1467 case GIMPLE_ASM:
1468 case GIMPLE_COND:
1469 case GIMPLE_GOTO:
1470 case GIMPLE_RETURN:
1472 func_checker::operand_access_type_map map (5);
1473 func_checker::classify_operands (stmt, &map);
1475 /* All these statements are equivalent if their operands are. */
1476 for (unsigned i = 0; i < gimple_num_ops (stmt); ++i)
1478 func_checker::operand_access_type
1479 access_type = func_checker::get_operand_access_type
1480 (&map, gimple_op (stmt, i));
1481 m_checker->hash_operand (gimple_op (stmt, i), hstate, 0,
1482 access_type);
1483 /* For memory accesses when hasing for LTO stremaing record
1484 base and ref alias ptr types so we can compare them at WPA
1485 time without having to read actual function body. */
1486 if (access_type == func_checker::OP_MEMORY
1487 && lto_streaming_expected_p ()
1488 && flag_strict_aliasing)
1490 ao_ref ref;
1492 ao_ref_init (&ref, gimple_op (stmt, i));
1493 tree t = ao_ref_alias_ptr_type (&ref);
1494 if (!variably_modified_type_p (t, NULL_TREE))
1495 memory_access_types.safe_push (t);
1496 t = ao_ref_base_alias_ptr_type (&ref);
1497 if (!variably_modified_type_p (t, NULL_TREE))
1498 memory_access_types.safe_push (t);
1501 /* Consider nocf_check attribute in hash as it affects code
1502 generation. */
1503 if (code == GIMPLE_CALL
1504 && flag_cf_protection & CF_BRANCH)
1505 hstate.add_flag (gimple_call_nocf_check_p (as_a <gcall *> (stmt)));
1507 break;
1508 default:
1509 break;
1514 /* Return true if polymorphic comparison must be processed. */
1516 bool
1517 sem_function::compare_polymorphic_p (void)
1519 struct cgraph_edge *e;
1521 if (!opt_for_fn (get_node ()->decl, flag_devirtualize))
1522 return false;
1523 if (get_node ()->indirect_calls != NULL)
1524 return true;
1525 /* TODO: We can do simple propagation determining what calls may lead to
1526 a polymorphic call. */
1527 for (e = get_node ()->callees; e; e = e->next_callee)
1528 if (e->callee->definition
1529 && opt_for_fn (e->callee->decl, flag_devirtualize))
1530 return true;
1531 return false;
1534 /* For a given call graph NODE, the function constructs new
1535 semantic function item. */
1537 sem_function *
1538 sem_function::parse (cgraph_node *node, bitmap_obstack *stack,
1539 func_checker *checker)
1541 tree fndecl = node->decl;
1542 function *func = DECL_STRUCT_FUNCTION (fndecl);
1544 if (!func || (!node->has_gimple_body_p () && !node->thunk))
1545 return NULL;
1547 if (lookup_attribute_by_prefix ("omp ", DECL_ATTRIBUTES (node->decl)) != NULL)
1548 return NULL;
1550 if (lookup_attribute_by_prefix ("oacc ",
1551 DECL_ATTRIBUTES (node->decl)) != NULL)
1552 return NULL;
1554 /* PR ipa/70306. */
1555 if (DECL_STATIC_CONSTRUCTOR (node->decl)
1556 || DECL_STATIC_DESTRUCTOR (node->decl))
1557 return NULL;
1559 sem_function *f = new sem_function (node, stack);
1560 f->init (checker);
1562 return f;
1565 /* For given basic blocks BB1 and BB2 (from functions FUNC1 and FUNC),
1566 return true if phi nodes are semantically equivalent in these blocks . */
1568 bool
1569 sem_function::compare_phi_node (basic_block bb1, basic_block bb2)
1571 gphi_iterator si1, si2;
1572 gphi *phi1, *phi2;
1573 unsigned size1, size2, i;
1574 tree t1, t2;
1575 edge e1, e2;
1577 gcc_assert (bb1 != NULL);
1578 gcc_assert (bb2 != NULL);
1580 si2 = gsi_start_nonvirtual_phis (bb2);
1581 for (si1 = gsi_start_nonvirtual_phis (bb1); !gsi_end_p (si1);
1582 gsi_next_nonvirtual_phi (&si1))
1584 if (gsi_end_p (si1) && gsi_end_p (si2))
1585 break;
1587 if (gsi_end_p (si1) || gsi_end_p (si2))
1588 return return_false();
1590 phi1 = si1.phi ();
1591 phi2 = si2.phi ();
1593 tree phi_result1 = gimple_phi_result (phi1);
1594 tree phi_result2 = gimple_phi_result (phi2);
1596 if (!m_checker->compare_operand (phi_result1, phi_result2,
1597 func_checker::OP_NORMAL))
1598 return return_false_with_msg ("PHI results are different");
1600 size1 = gimple_phi_num_args (phi1);
1601 size2 = gimple_phi_num_args (phi2);
1603 if (size1 != size2)
1604 return return_false ();
1606 /* TODO: We should be able to match PHIs with different order of
1607 parameters. This needs to be also updated in sem_function::init. */
1608 for (i = 0; i < size1; ++i)
1610 t1 = gimple_phi_arg (phi1, i)->def;
1611 t2 = gimple_phi_arg (phi2, i)->def;
1613 if (!m_checker->compare_operand (t1, t2, func_checker::OP_NORMAL))
1614 return return_false ();
1616 e1 = gimple_phi_arg_edge (phi1, i);
1617 e2 = gimple_phi_arg_edge (phi2, i);
1619 if (!m_checker->compare_edge (e1, e2))
1620 return return_false ();
1623 gsi_next_nonvirtual_phi (&si2);
1626 return true;
1629 /* Basic blocks dictionary BB_DICT returns true if SOURCE index BB
1630 corresponds to TARGET. */
1632 bool
1633 sem_function::bb_dict_test (vec<int> *bb_dict, int source, int target)
1635 source++;
1636 target++;
1638 if (bb_dict->length () <= (unsigned)source)
1639 bb_dict->safe_grow_cleared (source + 1, true);
1641 if ((*bb_dict)[source] == 0)
1643 (*bb_dict)[source] = target;
1644 return true;
1646 else
1647 return (*bb_dict)[source] == target;
1650 sem_variable::sem_variable (bitmap_obstack *stack): sem_item (VAR, stack)
1654 sem_variable::sem_variable (varpool_node *node, bitmap_obstack *stack)
1655 : sem_item (VAR, node, stack)
1657 gcc_checking_assert (node);
1658 gcc_checking_assert (get_node ());
1661 /* Fast equality function based on knowledge known in WPA. */
1663 bool
1664 sem_variable::equals_wpa (sem_item *item,
1665 hash_map <symtab_node *, sem_item *> &ignored_nodes)
1667 gcc_assert (item->type == VAR);
1669 if (node->num_references () != item->node->num_references ())
1670 return return_false_with_msg ("different number of references");
1672 if (DECL_TLS_MODEL (decl) || DECL_TLS_MODEL (item->decl))
1673 return return_false_with_msg ("TLS model");
1675 /* DECL_ALIGN is safe to merge, because we will always chose the largest
1676 alignment out of all aliases. */
1678 if (DECL_VIRTUAL_P (decl) != DECL_VIRTUAL_P (item->decl))
1679 return return_false_with_msg ("Virtual flag mismatch");
1681 if (DECL_SIZE (decl) != DECL_SIZE (item->decl)
1682 && ((!DECL_SIZE (decl) || !DECL_SIZE (item->decl))
1683 || !operand_equal_p (DECL_SIZE (decl),
1684 DECL_SIZE (item->decl), OEP_ONLY_CONST)))
1685 return return_false_with_msg ("size mismatch");
1687 /* Do not attempt to mix data from different user sections;
1688 we do not know what user intends with those. */
1689 if (((DECL_SECTION_NAME (decl) && !node->implicit_section)
1690 || (DECL_SECTION_NAME (item->decl) && !item->node->implicit_section))
1691 && DECL_SECTION_NAME (decl) != DECL_SECTION_NAME (item->decl))
1692 return return_false_with_msg ("user section mismatch");
1694 if (DECL_IN_TEXT_SECTION (decl) != DECL_IN_TEXT_SECTION (item->decl))
1695 return return_false_with_msg ("text section");
1697 if (TYPE_ADDR_SPACE (TREE_TYPE (decl))
1698 != TYPE_ADDR_SPACE (TREE_TYPE (item->decl)))
1699 return return_false_with_msg ("address-space");
1701 ipa_ref *ref = NULL, *ref2 = NULL;
1702 for (unsigned i = 0; node->iterate_reference (i, ref); i++)
1704 item->node->iterate_reference (i, ref2);
1706 if (ref->use != ref2->use)
1707 return return_false_with_msg ("reference use mismatch");
1709 if (!compare_symbol_references (ignored_nodes,
1710 ref->referred, ref2->referred,
1711 ref->address_matters_p ()))
1712 return false;
1715 return true;
1718 /* Returns true if the item equals to ITEM given as argument. */
1720 bool
1721 sem_variable::equals (sem_item *item,
1722 hash_map <symtab_node *, sem_item *> &)
1724 gcc_assert (item->type == VAR);
1725 bool ret;
1727 if (DECL_INITIAL (decl) == error_mark_node && in_lto_p)
1728 dyn_cast <varpool_node *>(node)->get_constructor ();
1729 if (DECL_INITIAL (item->decl) == error_mark_node && in_lto_p)
1730 dyn_cast <varpool_node *>(item->node)->get_constructor ();
1732 /* As seen in PR ipa/65303 we have to compare variables types. */
1733 if (!func_checker::compatible_types_p (TREE_TYPE (decl),
1734 TREE_TYPE (item->decl)))
1735 return return_false_with_msg ("variables types are different");
1737 ret = sem_variable::equals (DECL_INITIAL (decl),
1738 DECL_INITIAL (item->node->decl));
1739 if (dump_file && (dump_flags & TDF_DETAILS))
1740 fprintf (dump_file,
1741 "Equals called for vars: %s:%s with result: %s\n\n",
1742 node->dump_name (), item->node->dump_name (),
1743 ret ? "true" : "false");
1745 return ret;
1748 /* Compares trees T1 and T2 for semantic equality. */
1750 bool
1751 sem_variable::equals (tree t1, tree t2)
1753 if (!t1 || !t2)
1754 return return_with_debug (t1 == t2);
1755 if (t1 == t2)
1756 return true;
1757 tree_code tc1 = TREE_CODE (t1);
1758 tree_code tc2 = TREE_CODE (t2);
1760 if (tc1 != tc2)
1761 return return_false_with_msg ("TREE_CODE mismatch");
1763 switch (tc1)
1765 case CONSTRUCTOR:
1767 vec<constructor_elt, va_gc> *v1, *v2;
1768 unsigned HOST_WIDE_INT idx;
1770 enum tree_code typecode = TREE_CODE (TREE_TYPE (t1));
1771 if (typecode != TREE_CODE (TREE_TYPE (t2)))
1772 return return_false_with_msg ("constructor type mismatch");
1774 if (typecode == ARRAY_TYPE)
1776 HOST_WIDE_INT size_1 = int_size_in_bytes (TREE_TYPE (t1));
1777 /* For arrays, check that the sizes all match. */
1778 if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2))
1779 || size_1 == -1
1780 || size_1 != int_size_in_bytes (TREE_TYPE (t2)))
1781 return return_false_with_msg ("constructor array size mismatch");
1783 else if (!func_checker::compatible_types_p (TREE_TYPE (t1),
1784 TREE_TYPE (t2)))
1785 return return_false_with_msg ("constructor type incompatible");
1787 v1 = CONSTRUCTOR_ELTS (t1);
1788 v2 = CONSTRUCTOR_ELTS (t2);
1789 if (vec_safe_length (v1) != vec_safe_length (v2))
1790 return return_false_with_msg ("constructor number of elts mismatch");
1792 for (idx = 0; idx < vec_safe_length (v1); ++idx)
1794 constructor_elt *c1 = &(*v1)[idx];
1795 constructor_elt *c2 = &(*v2)[idx];
1797 /* Check that each value is the same... */
1798 if (!sem_variable::equals (c1->value, c2->value))
1799 return false;
1800 /* ... and that they apply to the same fields! */
1801 if (!sem_variable::equals (c1->index, c2->index))
1802 return false;
1804 return true;
1806 case MEM_REF:
1808 tree x1 = TREE_OPERAND (t1, 0);
1809 tree x2 = TREE_OPERAND (t2, 0);
1810 tree y1 = TREE_OPERAND (t1, 1);
1811 tree y2 = TREE_OPERAND (t2, 1);
1813 if (!func_checker::compatible_types_p (TREE_TYPE (x1), TREE_TYPE (x2)))
1814 return return_false ();
1816 /* Type of the offset on MEM_REF does not matter. */
1817 return return_with_debug (sem_variable::equals (x1, x2)
1818 && known_eq (wi::to_poly_offset (y1),
1819 wi::to_poly_offset (y2)));
1821 case ADDR_EXPR:
1822 case FDESC_EXPR:
1824 tree op1 = TREE_OPERAND (t1, 0);
1825 tree op2 = TREE_OPERAND (t2, 0);
1826 return sem_variable::equals (op1, op2);
1828 /* References to other vars/decls are compared using ipa-ref. */
1829 case FUNCTION_DECL:
1830 case VAR_DECL:
1831 if (decl_in_symtab_p (t1) && decl_in_symtab_p (t2))
1832 return true;
1833 return return_false_with_msg ("Declaration mismatch");
1834 case CONST_DECL:
1835 /* TODO: We can check CONST_DECL by its DECL_INITIAL, but for that we
1836 need to process its VAR/FUNCTION references without relying on ipa-ref
1837 compare. */
1838 case FIELD_DECL:
1839 case LABEL_DECL:
1840 return return_false_with_msg ("Declaration mismatch");
1841 case INTEGER_CST:
1842 /* Integer constants are the same only if the same width of type. */
1843 if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2)))
1844 return return_false_with_msg ("INTEGER_CST precision mismatch");
1845 if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2)))
1846 return return_false_with_msg ("INTEGER_CST mode mismatch");
1847 return return_with_debug (tree_int_cst_equal (t1, t2));
1848 case STRING_CST:
1849 if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2)))
1850 return return_false_with_msg ("STRING_CST mode mismatch");
1851 if (TREE_STRING_LENGTH (t1) != TREE_STRING_LENGTH (t2))
1852 return return_false_with_msg ("STRING_CST length mismatch");
1853 if (memcmp (TREE_STRING_POINTER (t1), TREE_STRING_POINTER (t2),
1854 TREE_STRING_LENGTH (t1)))
1855 return return_false_with_msg ("STRING_CST mismatch");
1856 return true;
1857 case FIXED_CST:
1858 /* Fixed constants are the same only if the same width of type. */
1859 if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2)))
1860 return return_false_with_msg ("FIXED_CST precision mismatch");
1862 return return_with_debug (FIXED_VALUES_IDENTICAL (TREE_FIXED_CST (t1),
1863 TREE_FIXED_CST (t2)));
1864 case COMPLEX_CST:
1865 return (sem_variable::equals (TREE_REALPART (t1), TREE_REALPART (t2))
1866 && sem_variable::equals (TREE_IMAGPART (t1), TREE_IMAGPART (t2)));
1867 case REAL_CST:
1868 /* Real constants are the same only if the same width of type. */
1869 if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2)))
1870 return return_false_with_msg ("REAL_CST precision mismatch");
1871 return return_with_debug (real_identical (&TREE_REAL_CST (t1),
1872 &TREE_REAL_CST (t2)));
1873 case VECTOR_CST:
1875 if (maybe_ne (VECTOR_CST_NELTS (t1), VECTOR_CST_NELTS (t2)))
1876 return return_false_with_msg ("VECTOR_CST nelts mismatch");
1878 unsigned int count
1879 = tree_vector_builder::binary_encoded_nelts (t1, t2);
1880 for (unsigned int i = 0; i < count; ++i)
1881 if (!sem_variable::equals (VECTOR_CST_ENCODED_ELT (t1, i),
1882 VECTOR_CST_ENCODED_ELT (t2, i)))
1883 return false;
1885 return true;
1887 case ARRAY_REF:
1888 case ARRAY_RANGE_REF:
1890 tree x1 = TREE_OPERAND (t1, 0);
1891 tree x2 = TREE_OPERAND (t2, 0);
1892 tree y1 = TREE_OPERAND (t1, 1);
1893 tree y2 = TREE_OPERAND (t2, 1);
1895 if (!sem_variable::equals (x1, x2) || !sem_variable::equals (y1, y2))
1896 return false;
1897 if (!sem_variable::equals (array_ref_low_bound (t1),
1898 array_ref_low_bound (t2)))
1899 return false;
1900 if (!sem_variable::equals (array_ref_element_size (t1),
1901 array_ref_element_size (t2)))
1902 return false;
1903 return true;
1906 case COMPONENT_REF:
1907 case POINTER_PLUS_EXPR:
1908 case PLUS_EXPR:
1909 case MINUS_EXPR:
1910 case RANGE_EXPR:
1912 tree x1 = TREE_OPERAND (t1, 0);
1913 tree x2 = TREE_OPERAND (t2, 0);
1914 tree y1 = TREE_OPERAND (t1, 1);
1915 tree y2 = TREE_OPERAND (t2, 1);
1917 return sem_variable::equals (x1, x2) && sem_variable::equals (y1, y2);
1920 CASE_CONVERT:
1921 case VIEW_CONVERT_EXPR:
1922 if (!func_checker::compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2)))
1923 return return_false ();
1924 return sem_variable::equals (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
1925 case ERROR_MARK:
1926 return return_false_with_msg ("ERROR_MARK");
1927 default:
1928 return return_false_with_msg ("Unknown TREE code reached");
1932 /* Parser function that visits a varpool NODE. */
1934 sem_variable *
1935 sem_variable::parse (varpool_node *node, bitmap_obstack *stack,
1936 func_checker *checker)
1938 if (TREE_THIS_VOLATILE (node->decl) || DECL_HARD_REGISTER (node->decl)
1939 || node->alias)
1940 return NULL;
1942 sem_variable *v = new sem_variable (node, stack);
1943 v->init (checker);
1945 return v;
1948 /* Semantic variable initialization function. */
1950 void
1951 sem_variable::init (ipa_icf_gimple::func_checker *checker)
1953 decl = get_node ()->decl;
1955 /* All WPA streamed in symbols should have their hashes computed at compile
1956 time. At this point, the constructor may not be in memory at all.
1957 DECL_INITIAL (decl) would be error_mark_node in that case. */
1958 if (!m_hash_set)
1960 gcc_assert (!node->lto_file_data);
1961 inchash::hash hstate;
1962 hstate.add_int (456346417);
1963 checker->hash_operand (DECL_INITIAL (decl), hstate, 0);
1964 set_hash (hstate.end ());
1968 /* References independent hash function. */
1970 hashval_t
1971 sem_variable::get_hash (void)
1973 gcc_checking_assert (m_hash_set);
1974 return m_hash;
1977 /* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can
1978 be applied. */
1980 bool
1981 sem_variable::merge (sem_item *alias_item)
1983 gcc_assert (alias_item->type == VAR);
1985 AUTO_DUMP_SCOPE ("merge",
1986 dump_user_location_t::from_function_decl (decl));
1987 if (!sem_item::target_supports_symbol_aliases_p ())
1989 if (dump_enabled_p ())
1990 dump_printf (MSG_MISSED_OPTIMIZATION, "Not unifying; "
1991 "Symbol aliases are not supported by target\n");
1992 return false;
1995 if (DECL_EXTERNAL (alias_item->decl))
1997 if (dump_enabled_p ())
1998 dump_printf (MSG_MISSED_OPTIMIZATION,
1999 "Not unifying; alias is external.\n");
2000 return false;
2003 sem_variable *alias_var = static_cast<sem_variable *> (alias_item);
2005 varpool_node *original = get_node ();
2006 varpool_node *alias = alias_var->get_node ();
2007 bool original_discardable = false;
2009 bool alias_address_matters = alias->address_matters_p ();
2011 /* See if original is in a section that can be discarded if the main
2012 symbol is not used.
2013 Also consider case where we have resolution info and we know that
2014 original's definition is not going to be used. In this case we cannot
2015 create alias to original. */
2016 if (original->can_be_discarded_p ()
2017 || (node->resolution != LDPR_UNKNOWN
2018 && !decl_binds_to_current_def_p (node->decl)))
2019 original_discardable = true;
2021 gcc_assert (!TREE_ASM_WRITTEN (alias->decl));
2023 /* Constant pool machinery is not quite ready for aliases.
2024 TODO: varasm code contains logic for merging DECL_IN_CONSTANT_POOL.
2025 For LTO merging does not happen that is an important missing feature.
2026 We can enable merging with LTO if the DECL_IN_CONSTANT_POOL
2027 flag is dropped and non-local symbol name is assigned. */
2028 if (DECL_IN_CONSTANT_POOL (alias->decl)
2029 || DECL_IN_CONSTANT_POOL (original->decl))
2031 if (dump_enabled_p ())
2032 dump_printf (MSG_MISSED_OPTIMIZATION,
2033 "Not unifying; constant pool variables.\n");
2034 return false;
2037 /* Do not attempt to mix functions from different user sections;
2038 we do not know what user intends with those. */
2039 if (((DECL_SECTION_NAME (original->decl) && !original->implicit_section)
2040 || (DECL_SECTION_NAME (alias->decl) && !alias->implicit_section))
2041 && DECL_SECTION_NAME (original->decl) != DECL_SECTION_NAME (alias->decl))
2043 if (dump_enabled_p ())
2044 dump_printf (MSG_MISSED_OPTIMIZATION,
2045 "Not unifying; "
2046 "original and alias are in different sections.\n");
2047 return false;
2050 /* We cannot merge if address comparison matters. */
2051 if (alias_address_matters && flag_merge_constants < 2)
2053 if (dump_enabled_p ())
2054 dump_printf (MSG_MISSED_OPTIMIZATION,
2055 "Not unifying; address of original may be compared.\n");
2056 return false;
2059 if (DECL_ALIGN (original->decl) != DECL_ALIGN (alias->decl)
2060 && (sanitize_flags_p (SANITIZE_ADDRESS, original->decl)
2061 || sanitize_flags_p (SANITIZE_ADDRESS, alias->decl)))
2063 if (dump_enabled_p ())
2064 dump_printf (MSG_MISSED_OPTIMIZATION,
2065 "Not unifying; "
2066 "ASAN requires equal alignments for original and alias\n");
2068 return false;
2071 if (DECL_ALIGN (original->decl) < DECL_ALIGN (alias->decl))
2073 if (dump_enabled_p ())
2074 dump_printf (MSG_MISSED_OPTIMIZATION,
2075 "Not unifying; "
2076 "original and alias have incompatible alignments\n");
2078 return false;
2081 if (DECL_COMDAT_GROUP (original->decl) != DECL_COMDAT_GROUP (alias->decl))
2083 if (dump_enabled_p ())
2084 dump_printf (MSG_MISSED_OPTIMIZATION,
2085 "Not unifying; alias cannot be created; "
2086 "across comdat group boundary\n");
2088 return false;
2091 if (original_discardable)
2093 if (dump_enabled_p ())
2094 dump_printf (MSG_MISSED_OPTIMIZATION,
2095 "Not unifying; alias cannot be created; "
2096 "target is discardable\n");
2098 return false;
2100 else
2102 gcc_assert (!original->alias);
2103 gcc_assert (!alias->alias);
2105 alias->analyzed = false;
2107 DECL_INITIAL (alias->decl) = NULL;
2108 ((symtab_node *)alias)->call_for_symbol_and_aliases (clear_decl_rtl,
2109 NULL, true);
2110 alias->remove_all_references ();
2111 if (TREE_ADDRESSABLE (alias->decl))
2112 original->call_for_symbol_and_aliases (set_addressable, NULL, true);
2114 varpool_node::create_alias (alias_var->decl, decl);
2115 alias->resolve_alias (original);
2117 if (dump_enabled_p ())
2118 dump_printf (MSG_OPTIMIZED_LOCATIONS,
2119 "Unified; Variable alias has been created.\n");
2121 return true;
2125 /* Dump symbol to FILE. */
2127 void
2128 sem_variable::dump_to_file (FILE *file)
2130 gcc_assert (file);
2132 print_node (file, "", decl, 0);
2133 fprintf (file, "\n\n");
2136 unsigned int sem_item_optimizer::class_id = 0;
2138 sem_item_optimizer::sem_item_optimizer ()
2139 : worklist (0), m_classes (0), m_classes_count (0), m_cgraph_node_hooks (NULL),
2140 m_varpool_node_hooks (NULL), m_merged_variables (), m_references ()
2142 m_items.create (0);
2143 bitmap_obstack_initialize (&m_bmstack);
2146 sem_item_optimizer::~sem_item_optimizer ()
2148 for (unsigned int i = 0; i < m_items.length (); i++)
2149 delete m_items[i];
2152 for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
2153 it != m_classes.end (); ++it)
2155 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
2156 delete (*it)->classes[i];
2158 (*it)->classes.release ();
2159 free (*it);
2162 m_items.release ();
2164 bitmap_obstack_release (&m_bmstack);
2165 m_merged_variables.release ();
2168 /* Write IPA ICF summary for symbols. */
2170 void
2171 sem_item_optimizer::write_summary (void)
2173 unsigned int count = 0;
2175 output_block *ob = create_output_block (LTO_section_ipa_icf);
2176 lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
2177 ob->symbol = NULL;
2179 /* Calculate number of symbols to be serialized. */
2180 for (lto_symtab_encoder_iterator lsei = lsei_start_in_partition (encoder);
2181 !lsei_end_p (lsei);
2182 lsei_next_in_partition (&lsei))
2184 symtab_node *node = lsei_node (lsei);
2186 if (m_symtab_node_map.get (node))
2187 count++;
2190 streamer_write_uhwi (ob, count);
2192 /* Process all of the symbols. */
2193 for (lto_symtab_encoder_iterator lsei = lsei_start_in_partition (encoder);
2194 !lsei_end_p (lsei);
2195 lsei_next_in_partition (&lsei))
2197 symtab_node *node = lsei_node (lsei);
2199 sem_item **item = m_symtab_node_map.get (node);
2201 if (item && *item)
2203 int node_ref = lto_symtab_encoder_encode (encoder, node);
2204 streamer_write_uhwi_stream (ob->main_stream, node_ref);
2206 streamer_write_uhwi (ob, (*item)->get_hash ());
2208 if ((*item)->type == FUNC)
2210 sem_function *fn = static_cast<sem_function *> (*item);
2211 streamer_write_uhwi (ob, fn->memory_access_types.length ());
2212 for (unsigned i = 0; i < fn->memory_access_types.length (); i++)
2213 stream_write_tree (ob, fn->memory_access_types[i], true);
2218 streamer_write_char_stream (ob->main_stream, 0);
2219 produce_asm (ob);
2220 destroy_output_block (ob);
2223 /* Reads a section from LTO stream file FILE_DATA. Input block for DATA
2224 contains LEN bytes. */
2226 void
2227 sem_item_optimizer::read_section (lto_file_decl_data *file_data,
2228 const char *data, size_t len)
2230 const lto_function_header *header
2231 = (const lto_function_header *) data;
2232 const int cfg_offset = sizeof (lto_function_header);
2233 const int main_offset = cfg_offset + header->cfg_size;
2234 const int string_offset = main_offset + header->main_size;
2235 data_in *data_in;
2236 unsigned int i;
2237 unsigned int count;
2239 lto_input_block ib_main ((const char *) data + main_offset, 0,
2240 header->main_size, file_data);
2242 data_in
2243 = lto_data_in_create (file_data, (const char *) data + string_offset,
2244 header->string_size, vNULL);
2246 count = streamer_read_uhwi (&ib_main);
2248 for (i = 0; i < count; i++)
2250 unsigned int index;
2251 symtab_node *node;
2252 lto_symtab_encoder_t encoder;
2254 index = streamer_read_uhwi (&ib_main);
2255 encoder = file_data->symtab_node_encoder;
2256 node = lto_symtab_encoder_deref (encoder, index);
2258 hashval_t hash = streamer_read_uhwi (&ib_main);
2259 gcc_assert (node->definition);
2261 if (is_a<cgraph_node *> (node))
2263 cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
2265 sem_function *fn = new sem_function (cnode, &m_bmstack);
2266 unsigned count = streamer_read_uhwi (&ib_main);
2267 inchash::hash hstate (0);
2268 if (flag_incremental_link == INCREMENTAL_LINK_LTO)
2269 fn->memory_access_types.reserve_exact (count);
2270 for (unsigned i = 0; i < count; i++)
2272 tree type = stream_read_tree (&ib_main, data_in);
2273 hstate.add_int (get_deref_alias_set (type));
2274 if (flag_incremental_link == INCREMENTAL_LINK_LTO)
2275 fn->memory_access_types.quick_push (type);
2277 fn->m_alias_sets_hash = hstate.end ();
2278 fn->set_hash (hash);
2279 m_items.safe_push (fn);
2281 else
2283 varpool_node *vnode = dyn_cast <varpool_node *> (node);
2285 sem_variable *var = new sem_variable (vnode, &m_bmstack);
2286 var->set_hash (hash);
2287 m_items.safe_push (var);
2291 lto_free_section_data (file_data, LTO_section_ipa_icf, NULL, data,
2292 len);
2293 lto_data_in_delete (data_in);
2296 /* Read IPA ICF summary for symbols. */
2298 void
2299 sem_item_optimizer::read_summary (void)
2301 lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
2302 lto_file_decl_data *file_data;
2303 unsigned int j = 0;
2305 while ((file_data = file_data_vec[j++]))
2307 size_t len;
2308 const char *data
2309 = lto_get_summary_section_data (file_data, LTO_section_ipa_icf, &len);
2310 if (data)
2311 read_section (file_data, data, len);
2315 /* Register callgraph and varpool hooks. */
2317 void
2318 sem_item_optimizer::register_hooks (void)
2320 if (!m_cgraph_node_hooks)
2321 m_cgraph_node_hooks = symtab->add_cgraph_removal_hook
2322 (&sem_item_optimizer::cgraph_removal_hook, this);
2324 if (!m_varpool_node_hooks)
2325 m_varpool_node_hooks = symtab->add_varpool_removal_hook
2326 (&sem_item_optimizer::varpool_removal_hook, this);
2329 /* Unregister callgraph and varpool hooks. */
2331 void
2332 sem_item_optimizer::unregister_hooks (void)
2334 if (m_cgraph_node_hooks)
2335 symtab->remove_cgraph_removal_hook (m_cgraph_node_hooks);
2337 if (m_varpool_node_hooks)
2338 symtab->remove_varpool_removal_hook (m_varpool_node_hooks);
2341 /* Adds a CLS to hashtable associated by hash value. */
2343 void
2344 sem_item_optimizer::add_class (congruence_class *cls)
2346 gcc_assert (cls->members.length ());
2348 congruence_class_group *group
2349 = get_group_by_hash (cls->members[0]->get_hash (),
2350 cls->members[0]->type);
2351 group->classes.safe_push (cls);
2354 /* Gets a congruence class group based on given HASH value and TYPE. */
2356 congruence_class_group *
2357 sem_item_optimizer::get_group_by_hash (hashval_t hash, sem_item_type type)
2359 congruence_class_group *item = XNEW (congruence_class_group);
2360 item->hash = hash;
2361 item->type = type;
2363 congruence_class_group **slot = m_classes.find_slot (item, INSERT);
2365 if (*slot)
2366 free (item);
2367 else
2369 item->classes.create (1);
2370 *slot = item;
2373 return *slot;
2376 /* Callgraph removal hook called for a NODE with a custom DATA. */
2378 void
2379 sem_item_optimizer::cgraph_removal_hook (cgraph_node *node, void *data)
2381 sem_item_optimizer *optimizer = (sem_item_optimizer *) data;
2382 optimizer->remove_symtab_node (node);
2385 /* Varpool removal hook called for a NODE with a custom DATA. */
2387 void
2388 sem_item_optimizer::varpool_removal_hook (varpool_node *node, void *data)
2390 sem_item_optimizer *optimizer = (sem_item_optimizer *) data;
2391 optimizer->remove_symtab_node (node);
2394 /* Remove symtab NODE triggered by symtab removal hooks. */
2396 void
2397 sem_item_optimizer::remove_symtab_node (symtab_node *node)
2399 gcc_assert (m_classes.is_empty ());
2401 m_removed_items_set.add (node);
2404 void
2405 sem_item_optimizer::remove_item (sem_item *item)
2407 if (m_symtab_node_map.get (item->node))
2408 m_symtab_node_map.remove (item->node);
2409 delete item;
2412 /* Removes all callgraph and varpool nodes that are marked by symtab
2413 as deleted. */
2415 void
2416 sem_item_optimizer::filter_removed_items (void)
2418 auto_vec <sem_item *> filtered;
2420 for (unsigned int i = 0; i < m_items.length(); i++)
2422 sem_item *item = m_items[i];
2424 if (m_removed_items_set.contains (item->node))
2426 remove_item (item);
2427 continue;
2430 if (item->type == FUNC)
2432 cgraph_node *cnode = static_cast <sem_function *>(item)->get_node ();
2434 if (in_lto_p && (cnode->alias || cnode->body_removed))
2435 remove_item (item);
2436 else
2437 filtered.safe_push (item);
2439 else /* VAR. */
2441 if (!flag_ipa_icf_variables)
2442 remove_item (item);
2443 else
2445 /* Filter out non-readonly variables. */
2446 tree decl = item->decl;
2447 varpool_node *vnode = static_cast <sem_variable *>(item)->get_node ();
2448 if (!TREE_READONLY (decl) || vnode->body_removed)
2449 remove_item (item);
2450 else
2451 filtered.safe_push (item);
2456 /* Clean-up of released semantic items. */
2458 m_items.release ();
2459 for (unsigned int i = 0; i < filtered.length(); i++)
2460 m_items.safe_push (filtered[i]);
2463 /* Optimizer entry point which returns true in case it processes
2464 a merge operation. True is returned if there's a merge operation
2465 processed. */
2467 bool
2468 sem_item_optimizer::execute (void)
2470 filter_removed_items ();
2471 unregister_hooks ();
2473 build_graph ();
2474 update_hash_by_addr_refs ();
2475 update_hash_by_memory_access_type ();
2476 build_hash_based_classes ();
2478 if (dump_file)
2479 fprintf (dump_file, "Dump after hash based groups\n");
2480 dump_cong_classes ();
2482 subdivide_classes_by_equality (true);
2484 if (dump_file)
2485 fprintf (dump_file, "Dump after WPA based types groups\n");
2487 dump_cong_classes ();
2489 process_cong_reduction ();
2490 checking_verify_classes ();
2492 if (dump_file)
2493 fprintf (dump_file, "Dump after callgraph-based congruence reduction\n");
2495 dump_cong_classes ();
2497 unsigned int loaded_symbols = parse_nonsingleton_classes ();
2498 subdivide_classes_by_equality ();
2500 if (dump_file)
2501 fprintf (dump_file, "Dump after full equality comparison of groups\n");
2503 dump_cong_classes ();
2505 unsigned int prev_class_count = m_classes_count;
2507 process_cong_reduction ();
2508 dump_cong_classes ();
2509 checking_verify_classes ();
2510 bool merged_p = merge_classes (prev_class_count, loaded_symbols);
2512 if (dump_file && (dump_flags & TDF_DETAILS))
2513 symtab->dump (dump_file);
2515 return merged_p;
2518 /* Function responsible for visiting all potential functions and
2519 read-only variables that can be merged. */
2521 void
2522 sem_item_optimizer::parse_funcs_and_vars (void)
2524 cgraph_node *cnode;
2526 /* Create dummy func_checker for hashing purpose. */
2527 func_checker checker;
2529 if (flag_ipa_icf_functions)
2530 FOR_EACH_DEFINED_FUNCTION (cnode)
2532 sem_function *f = sem_function::parse (cnode, &m_bmstack, &checker);
2533 if (f)
2535 m_items.safe_push (f);
2536 m_symtab_node_map.put (cnode, f);
2540 varpool_node *vnode;
2542 if (flag_ipa_icf_variables)
2543 FOR_EACH_DEFINED_VARIABLE (vnode)
2545 sem_variable *v = sem_variable::parse (vnode, &m_bmstack, &checker);
2547 if (v)
2549 m_items.safe_push (v);
2550 m_symtab_node_map.put (vnode, v);
2555 /* Makes pairing between a congruence class CLS and semantic ITEM. */
2557 void
2558 sem_item_optimizer::add_item_to_class (congruence_class *cls, sem_item *item)
2560 item->index_in_class = cls->members.length ();
2561 cls->members.safe_push (item);
2562 cls->referenced_by_count += item->referenced_by_count;
2563 item->cls = cls;
2566 /* For each semantic item, append hash values of references. */
2568 void
2569 sem_item_optimizer::update_hash_by_addr_refs ()
2571 /* First, append to hash sensitive references and class type if it need to
2572 be matched for ODR. */
2573 for (unsigned i = 0; i < m_items.length (); i++)
2575 m_items[i]->update_hash_by_addr_refs (m_symtab_node_map);
2576 if (m_items[i]->type == FUNC)
2578 if (TREE_CODE (TREE_TYPE (m_items[i]->decl)) == METHOD_TYPE
2579 && contains_polymorphic_type_p
2580 (TYPE_METHOD_BASETYPE (TREE_TYPE (m_items[i]->decl)))
2581 && (DECL_CXX_CONSTRUCTOR_P (m_items[i]->decl)
2582 || (static_cast<sem_function *> (m_items[i])->param_used_p (0)
2583 && static_cast<sem_function *> (m_items[i])
2584 ->compare_polymorphic_p ())))
2586 tree class_type
2587 = TYPE_METHOD_BASETYPE (TREE_TYPE (m_items[i]->decl));
2588 inchash::hash hstate (m_items[i]->get_hash ());
2590 /* Hash ODR types by mangled name if it is defined.
2591 If not we know that type is anonymous of free_lang_data
2592 was not run and in that case type main variants are
2593 unique. */
2594 if (TYPE_NAME (class_type)
2595 && DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (class_type))
2596 && !type_in_anonymous_namespace_p
2597 (class_type))
2598 hstate.add_hwi
2599 (IDENTIFIER_HASH_VALUE
2600 (DECL_ASSEMBLER_NAME (TYPE_NAME (class_type))));
2601 else
2603 gcc_checking_assert
2604 (!in_lto_p
2605 || type_in_anonymous_namespace_p (class_type));
2606 hstate.add_hwi (TYPE_UID (TYPE_MAIN_VARIANT (class_type)));
2609 m_items[i]->set_hash (hstate.end ());
2614 /* Once all symbols have enhanced hash value, we can append
2615 hash values of symbols that are seen by IPA ICF and are
2616 references by a semantic item. Newly computed values
2617 are saved to global_hash member variable. */
2618 for (unsigned i = 0; i < m_items.length (); i++)
2619 m_items[i]->update_hash_by_local_refs (m_symtab_node_map);
2621 /* Global hash value replace current hash values. */
2622 for (unsigned i = 0; i < m_items.length (); i++)
2623 m_items[i]->set_hash (m_items[i]->global_hash);
2626 void
2627 sem_item_optimizer::update_hash_by_memory_access_type ()
2629 for (unsigned i = 0; i < m_items.length (); i++)
2631 if (m_items[i]->type == FUNC)
2633 sem_function *fn = static_cast<sem_function *> (m_items[i]);
2634 inchash::hash hstate (fn->get_hash ());
2635 hstate.add_int (fn->m_alias_sets_hash);
2636 fn->set_hash (hstate.end ());
2641 /* Congruence classes are built by hash value. */
2643 void
2644 sem_item_optimizer::build_hash_based_classes (void)
2646 for (unsigned i = 0; i < m_items.length (); i++)
2648 sem_item *item = m_items[i];
2650 congruence_class_group *group
2651 = get_group_by_hash (item->get_hash (), item->type);
2653 if (!group->classes.length ())
2655 m_classes_count++;
2656 group->classes.safe_push (new congruence_class (class_id++));
2659 add_item_to_class (group->classes[0], item);
2663 /* Build references according to call graph. */
2665 void
2666 sem_item_optimizer::build_graph (void)
2668 for (unsigned i = 0; i < m_items.length (); i++)
2670 sem_item *item = m_items[i];
2671 m_symtab_node_map.put (item->node, item);
2673 /* Initialize hash values if we are not in LTO mode. */
2674 if (!in_lto_p)
2675 item->get_hash ();
2678 for (unsigned i = 0; i < m_items.length (); i++)
2680 sem_item *item = m_items[i];
2682 if (item->type == FUNC)
2684 cgraph_node *cnode = dyn_cast <cgraph_node *> (item->node);
2686 cgraph_edge *e = cnode->callees;
2687 while (e)
2689 sem_item **slot = m_symtab_node_map.get
2690 (e->callee->ultimate_alias_target ());
2691 if (slot)
2692 item->add_reference (&m_references, *slot);
2694 e = e->next_callee;
2698 ipa_ref *ref = NULL;
2699 for (unsigned i = 0; item->node->iterate_reference (i, ref); i++)
2701 sem_item **slot = m_symtab_node_map.get
2702 (ref->referred->ultimate_alias_target ());
2703 if (slot)
2704 item->add_reference (&m_references, *slot);
2709 /* Semantic items in classes having more than one element and initialized.
2710 In case of WPA, we load function body. */
2712 unsigned int
2713 sem_item_optimizer::parse_nonsingleton_classes (void)
2715 unsigned int counter = 0;
2717 /* Create dummy func_checker for hashing purpose. */
2718 func_checker checker;
2720 for (unsigned i = 0; i < m_items.length (); i++)
2721 if (m_items[i]->cls->members.length () > 1)
2723 m_items[i]->init (&checker);
2724 ++counter;
2727 if (dump_file)
2729 float f = m_items.length () ? 100.0f * counter / m_items.length () : 0.0f;
2730 fprintf (dump_file, "Init called for %u items (%.2f%%).\n", counter, f);
2733 return counter;
2736 /* Equality function for semantic items is used to subdivide existing
2737 classes. If IN_WPA, fast equality function is invoked. */
2739 void
2740 sem_item_optimizer::subdivide_classes_by_equality (bool in_wpa)
2742 for (hash_table <congruence_class_hash>::iterator it = m_classes.begin ();
2743 it != m_classes.end (); ++it)
2745 unsigned int class_count = (*it)->classes.length ();
2747 for (unsigned i = 0; i < class_count; i++)
2749 congruence_class *c = (*it)->classes[i];
2751 if (c->members.length() > 1)
2753 auto_vec <sem_item *> new_vector;
2755 sem_item *first = c->members[0];
2756 new_vector.safe_push (first);
2758 unsigned class_split_first = (*it)->classes.length ();
2760 for (unsigned j = 1; j < c->members.length (); j++)
2762 sem_item *item = c->members[j];
2764 bool equals
2765 = in_wpa ? first->equals_wpa (item, m_symtab_node_map)
2766 : first->equals (item, m_symtab_node_map);
2768 if (equals)
2769 new_vector.safe_push (item);
2770 else
2772 bool integrated = false;
2774 for (unsigned k = class_split_first;
2775 k < (*it)->classes.length (); k++)
2777 sem_item *x = (*it)->classes[k]->members[0];
2778 bool equals
2779 = in_wpa ? x->equals_wpa (item, m_symtab_node_map)
2780 : x->equals (item, m_symtab_node_map);
2782 if (equals)
2784 integrated = true;
2785 add_item_to_class ((*it)->classes[k], item);
2787 break;
2791 if (!integrated)
2793 congruence_class *c
2794 = new congruence_class (class_id++);
2795 m_classes_count++;
2796 add_item_to_class (c, item);
2798 (*it)->classes.safe_push (c);
2803 // We replace newly created new_vector for the class we've just
2804 // splitted.
2805 c->members.release ();
2806 c->members.create (new_vector.length ());
2808 for (unsigned int j = 0; j < new_vector.length (); j++)
2809 add_item_to_class (c, new_vector[j]);
2814 checking_verify_classes ();
2817 /* Subdivide classes by address references that members of the class
2818 reference. Example can be a pair of functions that have an address
2819 taken from a function. If these addresses are different the class
2820 is split. */
2822 unsigned
2823 sem_item_optimizer::subdivide_classes_by_sensitive_refs ()
2825 typedef hash_map <symbol_compare_hash, vec <sem_item *> > subdivide_hash_map;
2827 unsigned newly_created_classes = 0;
2829 for (hash_table <congruence_class_hash>::iterator it = m_classes.begin ();
2830 it != m_classes.end (); ++it)
2832 unsigned int class_count = (*it)->classes.length ();
2833 auto_vec<congruence_class *> new_classes;
2835 for (unsigned i = 0; i < class_count; i++)
2837 congruence_class *c = (*it)->classes[i];
2839 if (c->members.length() > 1)
2841 subdivide_hash_map split_map;
2843 for (unsigned j = 0; j < c->members.length (); j++)
2845 sem_item *source_node = c->members[j];
2847 symbol_compare_collection *collection
2848 = new symbol_compare_collection (source_node->node);
2850 bool existed;
2851 vec <sem_item *> *slot
2852 = &split_map.get_or_insert (collection, &existed);
2853 gcc_checking_assert (slot);
2855 slot->safe_push (source_node);
2857 if (existed)
2858 delete collection;
2861 /* If the map contains more than one key, we have to split
2862 the map appropriately. */
2863 if (split_map.elements () != 1)
2865 bool first_class = true;
2867 for (subdivide_hash_map::iterator it2 = split_map.begin ();
2868 it2 != split_map.end (); ++it2)
2870 congruence_class *new_cls;
2871 new_cls = new congruence_class (class_id++);
2873 for (unsigned k = 0; k < (*it2).second.length (); k++)
2874 add_item_to_class (new_cls, (*it2).second[k]);
2876 worklist_push (new_cls);
2877 newly_created_classes++;
2879 if (first_class)
2881 (*it)->classes[i] = new_cls;
2882 first_class = false;
2884 else
2886 new_classes.safe_push (new_cls);
2887 m_classes_count++;
2892 /* Release memory. */
2893 for (subdivide_hash_map::iterator it2 = split_map.begin ();
2894 it2 != split_map.end (); ++it2)
2896 delete (*it2).first;
2897 (*it2).second.release ();
2902 for (unsigned i = 0; i < new_classes.length (); i++)
2903 (*it)->classes.safe_push (new_classes[i]);
2906 return newly_created_classes;
2909 /* Verify congruence classes, if checking is enabled. */
2911 void
2912 sem_item_optimizer::checking_verify_classes (void)
2914 if (flag_checking)
2915 verify_classes ();
2918 /* Verify congruence classes. */
2920 void
2921 sem_item_optimizer::verify_classes (void)
2923 for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
2924 it != m_classes.end (); ++it)
2926 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
2928 congruence_class *cls = (*it)->classes[i];
2930 gcc_assert (cls);
2931 gcc_assert (cls->members.length () > 0);
2933 for (unsigned int j = 0; j < cls->members.length (); j++)
2935 sem_item *item = cls->members[j];
2937 gcc_assert (item);
2938 gcc_assert (item->cls == cls);
2944 /* Disposes split map traverse function. CLS_PTR is pointer to congruence
2945 class, BSLOT is bitmap slot we want to release. DATA is mandatory,
2946 but unused argument. */
2948 bool
2949 sem_item_optimizer::release_split_map (congruence_class * const &,
2950 bitmap const &b, traverse_split_pair *)
2952 bitmap bmp = b;
2954 BITMAP_FREE (bmp);
2956 return true;
2959 /* Process split operation for a class given as pointer CLS_PTR,
2960 where bitmap B splits congruence class members. DATA is used
2961 as argument of split pair. */
2963 bool
2964 sem_item_optimizer::traverse_congruence_split (congruence_class * const &cls,
2965 bitmap const &b,
2966 traverse_split_pair *pair)
2968 sem_item_optimizer *optimizer = pair->optimizer;
2969 const congruence_class *splitter_cls = pair->cls;
2971 /* If counted bits are greater than zero and less than the number of members
2972 a group will be splitted. */
2973 unsigned popcount = bitmap_count_bits (b);
2975 if (popcount > 0 && popcount < cls->members.length ())
2977 auto_vec <congruence_class *, 2> newclasses;
2978 newclasses.quick_push (new congruence_class (class_id++));
2979 newclasses.quick_push (new congruence_class (class_id++));
2981 for (unsigned int i = 0; i < cls->members.length (); i++)
2983 int target = bitmap_bit_p (b, i);
2984 congruence_class *tc = newclasses[target];
2986 add_item_to_class (tc, cls->members[i]);
2989 if (flag_checking)
2991 for (unsigned int i = 0; i < 2; i++)
2992 gcc_assert (newclasses[i]->members.length ());
2995 if (splitter_cls == cls)
2996 optimizer->splitter_class_removed = true;
2998 /* Remove old class from worklist if presented. */
2999 bool in_worklist = cls->in_worklist;
3001 if (in_worklist)
3002 cls->in_worklist = false;
3004 congruence_class_group g;
3005 g.hash = cls->members[0]->get_hash ();
3006 g.type = cls->members[0]->type;
3008 congruence_class_group *slot = optimizer->m_classes.find (&g);
3010 for (unsigned int i = 0; i < slot->classes.length (); i++)
3011 if (slot->classes[i] == cls)
3013 slot->classes.ordered_remove (i);
3014 break;
3017 /* New class will be inserted and integrated to work list. */
3018 for (unsigned int i = 0; i < 2; i++)
3019 optimizer->add_class (newclasses[i]);
3021 /* Two classes replace one, so that increment just by one. */
3022 optimizer->m_classes_count++;
3024 /* If OLD class was presented in the worklist, we remove the class
3025 and replace it will both newly created classes. */
3026 if (in_worklist)
3027 for (unsigned int i = 0; i < 2; i++)
3028 optimizer->worklist_push (newclasses[i]);
3029 else /* Just smaller class is inserted. */
3031 unsigned int smaller_index
3032 = (newclasses[0]->members.length ()
3033 < newclasses[1]->members.length ()
3034 ? 0 : 1);
3035 optimizer->worklist_push (newclasses[smaller_index]);
3038 if (dump_file && (dump_flags & TDF_DETAILS))
3040 fprintf (dump_file, " congruence class splitted:\n");
3041 cls->dump (dump_file, 4);
3043 fprintf (dump_file, " newly created groups:\n");
3044 for (unsigned int i = 0; i < 2; i++)
3045 newclasses[i]->dump (dump_file, 4);
3048 /* Release class if not presented in work list. */
3049 if (!in_worklist)
3050 delete cls;
3052 return true;
3055 return false;
3058 /* Compare function for sorting pairs in do_congruence_step_f. */
3061 sem_item_optimizer::sort_congruence_split (const void *a_, const void *b_)
3063 const std::pair<congruence_class *, bitmap> *a
3064 = (const std::pair<congruence_class *, bitmap> *)a_;
3065 const std::pair<congruence_class *, bitmap> *b
3066 = (const std::pair<congruence_class *, bitmap> *)b_;
3067 if (a->first->id < b->first->id)
3068 return -1;
3069 else if (a->first->id > b->first->id)
3070 return 1;
3071 return 0;
3074 /* Tests if a class CLS used as INDEXth splits any congruence classes.
3075 Bitmap stack BMSTACK is used for bitmap allocation. */
3077 bool
3078 sem_item_optimizer::do_congruence_step_for_index (congruence_class *cls,
3079 unsigned int index)
3081 hash_map <congruence_class *, bitmap> split_map;
3083 for (unsigned int i = 0; i < cls->members.length (); i++)
3085 sem_item *item = cls->members[i];
3086 sem_usage_pair needle (item, index);
3087 vec<sem_item *> *callers = m_references.get (&needle);
3088 if (callers == NULL)
3089 continue;
3091 for (unsigned int j = 0; j < callers->length (); j++)
3093 sem_item *caller = (*callers)[j];
3094 if (caller->cls->members.length () < 2)
3095 continue;
3096 bitmap *slot = split_map.get (caller->cls);
3097 bitmap b;
3099 if(!slot)
3101 b = BITMAP_ALLOC (&m_bmstack);
3102 split_map.put (caller->cls, b);
3104 else
3105 b = *slot;
3107 gcc_checking_assert (caller->cls);
3108 gcc_checking_assert (caller->index_in_class
3109 < caller->cls->members.length ());
3111 bitmap_set_bit (b, caller->index_in_class);
3115 auto_vec<std::pair<congruence_class *, bitmap> > to_split;
3116 to_split.reserve_exact (split_map.elements ());
3117 for (hash_map <congruence_class *, bitmap>::iterator i = split_map.begin ();
3118 i != split_map.end (); ++i)
3119 to_split.safe_push (*i);
3120 to_split.qsort (sort_congruence_split);
3122 traverse_split_pair pair;
3123 pair.optimizer = this;
3124 pair.cls = cls;
3126 splitter_class_removed = false;
3127 bool r = false;
3128 for (unsigned i = 0; i < to_split.length (); ++i)
3129 r |= traverse_congruence_split (to_split[i].first, to_split[i].second,
3130 &pair);
3132 /* Bitmap clean-up. */
3133 split_map.traverse <traverse_split_pair *,
3134 sem_item_optimizer::release_split_map> (NULL);
3136 return r;
3139 /* Every usage of a congruence class CLS is a candidate that can split the
3140 collection of classes. Bitmap stack BMSTACK is used for bitmap
3141 allocation. */
3143 void
3144 sem_item_optimizer::do_congruence_step (congruence_class *cls)
3146 bitmap_iterator bi;
3147 unsigned int i;
3149 bitmap usage = BITMAP_ALLOC (&m_bmstack);
3151 for (unsigned int i = 0; i < cls->members.length (); i++)
3152 bitmap_ior_into (usage, cls->members[i]->usage_index_bitmap);
3154 EXECUTE_IF_SET_IN_BITMAP (usage, 0, i, bi)
3156 if (dump_file && (dump_flags & TDF_DETAILS))
3157 fprintf (dump_file, " processing congruence step for class: %u "
3158 "(%u items, %u references), index: %u\n", cls->id,
3159 cls->referenced_by_count, cls->members.length (), i);
3160 do_congruence_step_for_index (cls, i);
3162 if (splitter_class_removed)
3163 break;
3166 BITMAP_FREE (usage);
3169 /* Adds a newly created congruence class CLS to worklist. */
3171 void
3172 sem_item_optimizer::worklist_push (congruence_class *cls)
3174 /* Return if the class CLS is already presented in work list. */
3175 if (cls->in_worklist)
3176 return;
3178 cls->in_worklist = true;
3179 worklist.insert (cls->referenced_by_count, cls);
3182 /* Pops a class from worklist. */
3184 congruence_class *
3185 sem_item_optimizer::worklist_pop (void)
3187 congruence_class *cls;
3189 while (!worklist.empty ())
3191 cls = worklist.extract_min ();
3192 if (cls->in_worklist)
3194 cls->in_worklist = false;
3196 return cls;
3198 else
3200 /* Work list item was already intended to be removed.
3201 The only reason for doing it is to split a class.
3202 Thus, the class CLS is deleted. */
3203 delete cls;
3207 return NULL;
3210 /* Iterative congruence reduction function. */
3212 void
3213 sem_item_optimizer::process_cong_reduction (void)
3215 for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
3216 it != m_classes.end (); ++it)
3217 for (unsigned i = 0; i < (*it)->classes.length (); i++)
3218 if ((*it)->classes[i]->is_class_used ())
3219 worklist_push ((*it)->classes[i]);
3221 if (dump_file)
3222 fprintf (dump_file, "Worklist has been filled with: "
3223 HOST_SIZE_T_PRINT_UNSIGNED "\n",
3224 (fmt_size_t) worklist.nodes ());
3226 if (dump_file && (dump_flags & TDF_DETAILS))
3227 fprintf (dump_file, "Congruence class reduction\n");
3229 congruence_class *cls;
3231 /* Process complete congruence reduction. */
3232 while ((cls = worklist_pop ()) != NULL)
3233 do_congruence_step (cls);
3235 /* Subdivide newly created classes according to references. */
3236 unsigned new_classes = subdivide_classes_by_sensitive_refs ();
3238 if (dump_file)
3239 fprintf (dump_file, "Address reference subdivision created: %u "
3240 "new classes.\n", new_classes);
3243 /* Debug function prints all informations about congruence classes. */
3245 void
3246 sem_item_optimizer::dump_cong_classes (void)
3248 if (!dump_file)
3249 return;
3251 /* Histogram calculation. */
3252 unsigned int max_index = 0;
3253 unsigned int single_element_classes = 0;
3254 unsigned int* histogram = XCNEWVEC (unsigned int, m_items.length () + 1);
3256 for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
3257 it != m_classes.end (); ++it)
3258 for (unsigned i = 0; i < (*it)->classes.length (); i++)
3260 unsigned int c = (*it)->classes[i]->members.length ();
3261 histogram[c]++;
3263 if (c > max_index)
3264 max_index = c;
3266 if (c == 1)
3267 ++single_element_classes;
3270 fprintf (dump_file,
3271 "Congruence classes: " HOST_SIZE_T_PRINT_UNSIGNED " with total: "
3272 "%u items (in a non-singular class: %u)\n",
3273 (fmt_size_t) m_classes.elements (),
3274 m_items.length (), m_items.length () - single_element_classes);
3275 fprintf (dump_file,
3276 "Class size histogram [number of members]: number of classes\n");
3277 for (unsigned int i = 0; i <= max_index; i++)
3278 if (histogram[i])
3279 fprintf (dump_file, "%6u: %6u\n", i, histogram[i]);
3281 if (dump_flags & TDF_DETAILS)
3282 for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
3283 it != m_classes.end (); ++it)
3285 fprintf (dump_file, " group: with %u classes:\n",
3286 (*it)->classes.length ());
3288 for (unsigned i = 0; i < (*it)->classes.length (); i++)
3290 (*it)->classes[i]->dump (dump_file, 4);
3292 if (i < (*it)->classes.length () - 1)
3293 fprintf (dump_file, " ");
3297 free (histogram);
3300 /* Sort pair of sem_items A and B by DECL_UID. */
3302 static int
3303 sort_sem_items_by_decl_uid (const void *a, const void *b)
3305 const sem_item *i1 = *(const sem_item * const *)a;
3306 const sem_item *i2 = *(const sem_item * const *)b;
3308 int uid1 = DECL_UID (i1->decl);
3309 int uid2 = DECL_UID (i2->decl);
3310 return uid1 - uid2;
3313 /* Sort pair of congruence_classes A and B by DECL_UID of the first member. */
3315 static int
3316 sort_congruence_classes_by_decl_uid (const void *a, const void *b)
3318 const congruence_class *c1 = *(const congruence_class * const *)a;
3319 const congruence_class *c2 = *(const congruence_class * const *)b;
3321 int uid1 = DECL_UID (c1->members[0]->decl);
3322 int uid2 = DECL_UID (c2->members[0]->decl);
3323 return uid1 - uid2;
3326 /* Sort pair of congruence_class_groups A and B by
3327 DECL_UID of the first member of a first group. */
3329 static int
3330 sort_congruence_class_groups_by_decl_uid (const void *a, const void *b)
3332 const std::pair<congruence_class_group *, int> *g1
3333 = (const std::pair<congruence_class_group *, int> *) a;
3334 const std::pair<congruence_class_group *, int> *g2
3335 = (const std::pair<congruence_class_group *, int> *) b;
3336 return g1->second - g2->second;
3339 /* After reduction is done, we can declare all items in a group
3340 to be equal. PREV_CLASS_COUNT is start number of classes
3341 before reduction. True is returned if there's a merge operation
3342 processed. LOADED_SYMBOLS is number of symbols that were loaded
3343 in WPA. */
3345 bool
3346 sem_item_optimizer::merge_classes (unsigned int prev_class_count,
3347 unsigned int loaded_symbols)
3349 unsigned int item_count = m_items.length ();
3350 unsigned int class_count = m_classes_count;
3351 unsigned int equal_items = item_count - class_count;
3353 unsigned int non_singular_classes_count = 0;
3354 unsigned int non_singular_classes_sum = 0;
3356 bool merged_p = false;
3358 /* PR lto/78211
3359 Sort functions in congruence classes by DECL_UID and do the same
3360 for the classes to not to break -fcompare-debug. */
3362 for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
3363 it != m_classes.end (); ++it)
3365 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
3367 congruence_class *c = (*it)->classes[i];
3368 c->members.qsort (sort_sem_items_by_decl_uid);
3371 (*it)->classes.qsort (sort_congruence_classes_by_decl_uid);
3374 for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
3375 it != m_classes.end (); ++it)
3376 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
3378 congruence_class *c = (*it)->classes[i];
3379 if (c->members.length () > 1)
3381 non_singular_classes_count++;
3382 non_singular_classes_sum += c->members.length ();
3386 auto_vec<std::pair<congruence_class_group *, int> > classes (
3387 m_classes.elements ());
3388 for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
3389 it != m_classes.end (); ++it)
3391 int uid = DECL_UID ((*it)->classes[0]->members[0]->decl);
3392 classes.quick_push (std::pair<congruence_class_group *, int> (*it, uid));
3395 classes.qsort (sort_congruence_class_groups_by_decl_uid);
3397 if (dump_file)
3399 fprintf (dump_file, "\nItem count: %u\n", item_count);
3400 fprintf (dump_file, "Congruent classes before: %u, after: %u\n",
3401 prev_class_count, class_count);
3402 fprintf (dump_file, "Average class size before: %.2f, after: %.2f\n",
3403 prev_class_count ? 1.0f * item_count / prev_class_count : 0.0f,
3404 class_count ? 1.0f * item_count / class_count : 0.0f);
3405 fprintf (dump_file, "Average non-singular class size: %.2f, count: %u\n",
3406 non_singular_classes_count ? 1.0f * non_singular_classes_sum /
3407 non_singular_classes_count : 0.0f,
3408 non_singular_classes_count);
3409 fprintf (dump_file, "Equal symbols: %u\n", equal_items);
3410 unsigned total = equal_items + non_singular_classes_count;
3411 fprintf (dump_file, "Totally needed symbols: %u"
3412 ", fraction of loaded symbols: %.2f%%\n\n", total,
3413 loaded_symbols ? 100.0f * total / loaded_symbols : 0.0f);
3416 unsigned int l;
3417 std::pair<congruence_class_group *, int> *it;
3418 FOR_EACH_VEC_ELT (classes, l, it)
3419 for (unsigned int i = 0; i < it->first->classes.length (); i++)
3421 congruence_class *c = it->first->classes[i];
3423 if (c->members.length () == 1)
3424 continue;
3426 sem_item *source = c->members[0];
3427 bool this_merged_p = false;
3429 if (DECL_NAME (source->decl)
3430 && MAIN_NAME_P (DECL_NAME (source->decl)))
3431 /* If merge via wrappers, picking main as the target can be
3432 problematic. */
3433 source = c->members[1];
3435 for (unsigned int j = 0; j < c->members.length (); j++)
3437 sem_item *alias = c->members[j];
3439 if (alias == source)
3440 continue;
3442 dump_user_location_t loc
3443 = dump_user_location_t::from_function_decl (source->decl);
3444 if (dump_enabled_p ())
3446 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
3447 "Semantic equality hit:%s->%s\n",
3448 source->node->dump_name (),
3449 alias->node->dump_name ());
3450 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
3451 "Assembler symbol names:%s->%s\n",
3452 source->node->dump_asm_name (),
3453 alias->node->dump_asm_name ());
3456 if (lookup_attribute ("no_icf", DECL_ATTRIBUTES (alias->decl))
3457 || lookup_attribute ("no_icf", DECL_ATTRIBUTES (source->decl)))
3459 if (dump_enabled_p ())
3460 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
3461 "Merge operation is skipped due to no_icf "
3462 "attribute.\n");
3463 continue;
3466 if (dump_file && (dump_flags & TDF_DETAILS))
3468 source->dump_to_file (dump_file);
3469 alias->dump_to_file (dump_file);
3472 if (dbg_cnt (merged_ipa_icf))
3474 bool merged = source->merge (alias);
3475 this_merged_p |= merged;
3477 if (merged && alias->type == VAR)
3479 symtab_pair p = symtab_pair (source->node, alias->node);
3480 m_merged_variables.safe_push (p);
3485 merged_p |= this_merged_p;
3486 if (this_merged_p
3487 && source->type == FUNC
3488 && (!flag_wpa || flag_checking))
3490 unsigned i;
3491 tree name;
3492 FOR_EACH_SSA_NAME (i, name, DECL_STRUCT_FUNCTION (source->decl))
3494 /* We need to either merge or reset SSA_NAME_*_INFO.
3495 For merging we don't preserve the mapping between
3496 original and alias SSA_NAMEs from successful equals
3497 calls. */
3498 if (POINTER_TYPE_P (TREE_TYPE (name)))
3500 if (SSA_NAME_PTR_INFO (name))
3502 gcc_checking_assert (!flag_wpa);
3503 SSA_NAME_PTR_INFO (name) = NULL;
3506 else if (SSA_NAME_RANGE_INFO (name))
3508 gcc_checking_assert (!flag_wpa);
3509 SSA_NAME_RANGE_INFO (name) = NULL;
3515 if (!m_merged_variables.is_empty ())
3516 fixup_points_to_sets ();
3518 return merged_p;
3521 /* Fixup points to set PT. */
3523 void
3524 sem_item_optimizer::fixup_pt_set (struct pt_solution *pt)
3526 if (pt->vars == NULL)
3527 return;
3529 unsigned i;
3530 symtab_pair *item;
3531 FOR_EACH_VEC_ELT (m_merged_variables, i, item)
3532 if (bitmap_bit_p (pt->vars, DECL_UID (item->second->decl)))
3533 bitmap_set_bit (pt->vars, DECL_UID (item->first->decl));
3536 /* Set all points-to UIDs of aliases pointing to node N as UID. */
3538 static void
3539 set_alias_uids (symtab_node *n, int uid)
3541 ipa_ref *ref;
3542 FOR_EACH_ALIAS (n, ref)
3544 if (dump_file)
3545 fprintf (dump_file, " Setting points-to UID of [%s] as %d\n",
3546 ref->referring->dump_asm_name (), uid);
3548 SET_DECL_PT_UID (ref->referring->decl, uid);
3549 set_alias_uids (ref->referring, uid);
3553 /* Fixup points to analysis info. */
3555 void
3556 sem_item_optimizer::fixup_points_to_sets (void)
3558 /* TODO: remove in GCC 9 and trigger PTA re-creation after IPA passes. */
3559 cgraph_node *cnode;
3561 FOR_EACH_DEFINED_FUNCTION (cnode)
3563 tree name;
3564 unsigned i;
3565 function *fn = DECL_STRUCT_FUNCTION (cnode->decl);
3566 if (!gimple_in_ssa_p (fn))
3567 continue;
3569 FOR_EACH_SSA_NAME (i, name, fn)
3570 if (POINTER_TYPE_P (TREE_TYPE (name))
3571 && SSA_NAME_PTR_INFO (name))
3572 fixup_pt_set (&SSA_NAME_PTR_INFO (name)->pt);
3573 fixup_pt_set (&fn->gimple_df->escaped);
3574 fixup_pt_set (&fn->gimple_df->escaped_return);
3576 /* The above gets us to 99% I guess, at least catching the
3577 address compares. Below also gets us aliasing correct
3578 but as said we're giving leeway to the situation with
3579 readonly vars anyway, so ... */
3580 basic_block bb;
3581 FOR_EACH_BB_FN (bb, fn)
3582 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
3583 gsi_next (&gsi))
3585 gcall *call = dyn_cast<gcall *> (gsi_stmt (gsi));
3586 if (call)
3588 fixup_pt_set (gimple_call_use_set (call));
3589 fixup_pt_set (gimple_call_clobber_set (call));
3594 unsigned i;
3595 symtab_pair *item;
3596 FOR_EACH_VEC_ELT (m_merged_variables, i, item)
3597 set_alias_uids (item->first, DECL_UID (item->first->decl));
3600 /* Dump function prints all class members to a FILE with an INDENT. */
3602 void
3603 congruence_class::dump (FILE *file, unsigned int indent) const
3605 FPRINTF_SPACES (file, indent, "class with id: %u, hash: %u, items: %u\n",
3606 id, members[0]->get_hash (), members.length ());
3608 FPUTS_SPACES (file, indent + 2, "");
3609 for (unsigned i = 0; i < members.length (); i++)
3610 fprintf (file, "%s ", members[i]->node->dump_asm_name ());
3612 fprintf (file, "\n");
3615 /* Returns true if there's a member that is used from another group. */
3617 bool
3618 congruence_class::is_class_used (void)
3620 for (unsigned int i = 0; i < members.length (); i++)
3621 if (members[i]->referenced_by_count)
3622 return true;
3624 return false;
3627 /* Generate pass summary for IPA ICF pass. */
3629 static void
3630 ipa_icf_generate_summary (void)
3632 if (!optimizer)
3633 optimizer = new sem_item_optimizer ();
3635 optimizer->register_hooks ();
3636 optimizer->parse_funcs_and_vars ();
3639 /* Write pass summary for IPA ICF pass. */
3641 static void
3642 ipa_icf_write_summary (void)
3644 gcc_assert (optimizer);
3646 optimizer->write_summary ();
3649 /* Read pass summary for IPA ICF pass. */
3651 static void
3652 ipa_icf_read_summary (void)
3654 if (!optimizer)
3655 optimizer = new sem_item_optimizer ();
3657 optimizer->read_summary ();
3658 optimizer->register_hooks ();
3661 /* Semantic equality execution function. */
3663 static unsigned int
3664 ipa_icf_driver (void)
3666 gcc_assert (optimizer);
3668 bool merged_p = optimizer->execute ();
3670 delete optimizer;
3671 optimizer = NULL;
3673 return merged_p ? TODO_remove_functions : 0;
3676 const pass_data pass_data_ipa_icf =
3678 IPA_PASS, /* type */
3679 "icf", /* name */
3680 OPTGROUP_IPA, /* optinfo_flags */
3681 TV_IPA_ICF, /* tv_id */
3682 0, /* properties_required */
3683 0, /* properties_provided */
3684 0, /* properties_destroyed */
3685 0, /* todo_flags_start */
3686 0, /* todo_flags_finish */
3689 class pass_ipa_icf : public ipa_opt_pass_d
3691 public:
3692 pass_ipa_icf (gcc::context *ctxt)
3693 : ipa_opt_pass_d (pass_data_ipa_icf, ctxt,
3694 ipa_icf_generate_summary, /* generate_summary */
3695 ipa_icf_write_summary, /* write_summary */
3696 ipa_icf_read_summary, /* read_summary */
3697 NULL, /*
3698 write_optimization_summary */
3699 NULL, /*
3700 read_optimization_summary */
3701 NULL, /* stmt_fixup */
3702 0, /* function_transform_todo_flags_start */
3703 NULL, /* function_transform */
3704 NULL) /* variable_transform */
3707 /* opt_pass methods: */
3708 bool gate (function *) final override
3710 return in_lto_p || flag_ipa_icf_variables || flag_ipa_icf_functions;
3713 unsigned int execute (function *) final override
3715 return ipa_icf_driver();
3717 }; // class pass_ipa_icf
3719 } // ipa_icf namespace
3721 ipa_opt_pass_d *
3722 make_pass_ipa_icf (gcc::context *ctxt)
3724 return new ipa_icf::pass_ipa_icf (ctxt);
3727 /* Reset all state within ipa-icf.cc so that we can rerun the compiler
3728 within the same process. For use by toplev::finalize. */
3730 void
3731 ipa_icf_cc_finalize (void)
3733 ipa_icf::optimizer = NULL;