Fix compilation failure with C++98 compilers
[official-gcc.git] / gcc / ipa-icf.c
blob3c54f8d4b6d42112eea434311e7fecca5a320d3e
1 /* Interprocedural Identical Code Folding pass
2 Copyright (C) 2014-2018 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 #define INCLUDE_LIST
56 #include "system.h"
57 #include "coretypes.h"
58 #include "backend.h"
59 #include "target.h"
60 #include "rtl.h"
61 #include "tree.h"
62 #include "gimple.h"
63 #include "alloc-pool.h"
64 #include "tree-pass.h"
65 #include "ssa.h"
66 #include "cgraph.h"
67 #include "coverage.h"
68 #include "gimple-pretty-print.h"
69 #include "data-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 "ipa-prop.h"
77 #include "ipa-fnsummary.h"
78 #include "except.h"
79 #include "attribs.h"
80 #include "print-tree.h"
81 #include "ipa-utils.h"
82 #include "ipa-icf-gimple.h"
83 #include "ipa-icf.h"
84 #include "stor-layout.h"
85 #include "dbgcnt.h"
86 #include "tree-vector-builder.h"
88 using namespace ipa_icf_gimple;
90 namespace ipa_icf {
92 /* Initialization and computation of symtab node hash, there data
93 are propagated later on. */
95 static sem_item_optimizer *optimizer = NULL;
97 /* Constructor. */
99 symbol_compare_collection::symbol_compare_collection (symtab_node *node)
101 m_references.create (0);
102 m_interposables.create (0);
104 ipa_ref *ref;
106 if (is_a <varpool_node *> (node) && DECL_VIRTUAL_P (node->decl))
107 return;
109 for (unsigned i = 0; node->iterate_reference (i, ref); i++)
111 if (ref->address_matters_p ())
112 m_references.safe_push (ref->referred);
114 if (ref->referred->get_availability () <= AVAIL_INTERPOSABLE)
116 if (ref->address_matters_p ())
117 m_references.safe_push (ref->referred);
118 else
119 m_interposables.safe_push (ref->referred);
123 if (is_a <cgraph_node *> (node))
125 cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
127 for (cgraph_edge *e = cnode->callees; e; e = e->next_callee)
128 if (e->callee->get_availability () <= AVAIL_INTERPOSABLE)
129 m_interposables.safe_push (e->callee);
133 /* Constructor for key value pair, where _ITEM is key and _INDEX is a target. */
135 sem_usage_pair::sem_usage_pair (sem_item *_item, unsigned int _index)
136 : item (_item), index (_index)
140 sem_item::sem_item (sem_item_type _type, bitmap_obstack *stack)
141 : type (_type), m_hash (-1), m_hash_set (false)
143 setup (stack);
146 sem_item::sem_item (sem_item_type _type, symtab_node *_node,
147 bitmap_obstack *stack)
148 : type (_type), node (_node), m_hash (-1), m_hash_set (false)
150 decl = node->decl;
151 setup (stack);
154 /* Add reference to a semantic TARGET. */
156 void
157 sem_item::add_reference (sem_item *target)
159 refs.safe_push (target);
160 unsigned index = refs.length ();
161 target->usages.safe_push (new sem_usage_pair(this, index));
162 bitmap_set_bit (target->usage_index_bitmap, index);
163 refs_set.add (target->node);
166 /* Initialize internal data structures. Bitmap STACK is used for
167 bitmap memory allocation process. */
169 void
170 sem_item::setup (bitmap_obstack *stack)
172 gcc_checking_assert (node);
174 refs.create (0);
175 tree_refs.create (0);
176 usages.create (0);
177 usage_index_bitmap = BITMAP_ALLOC (stack);
180 sem_item::~sem_item ()
182 for (unsigned i = 0; i < usages.length (); i++)
183 delete usages[i];
185 refs.release ();
186 tree_refs.release ();
187 usages.release ();
189 BITMAP_FREE (usage_index_bitmap);
192 /* Dump function for debugging purpose. */
194 DEBUG_FUNCTION void
195 sem_item::dump (void)
197 if (dump_file)
199 fprintf (dump_file, "[%s] %s (tree:%p)\n", type == FUNC ? "func" : "var",
200 node->dump_name (), (void *) node->decl);
201 fprintf (dump_file, " hash: %u\n", get_hash ());
202 fprintf (dump_file, " references: ");
204 for (unsigned i = 0; i < refs.length (); i++)
205 fprintf (dump_file, "%s%s ", refs[i]->node->name (),
206 i < refs.length() - 1 ? "," : "");
208 fprintf (dump_file, "\n");
212 /* Return true if target supports alias symbols. */
214 bool
215 sem_item::target_supports_symbol_aliases_p (void)
217 #if !defined (ASM_OUTPUT_DEF) || (!defined(ASM_OUTPUT_WEAK_ALIAS) && !defined (ASM_WEAKEN_DECL))
218 return false;
219 #else
220 return true;
221 #endif
224 void sem_item::set_hash (hashval_t hash)
226 m_hash = hash;
227 m_hash_set = true;
230 hash_map<const_tree, hashval_t> sem_item::m_type_hash_cache;
232 /* Semantic function constructor that uses STACK as bitmap memory stack. */
234 sem_function::sem_function (bitmap_obstack *stack)
235 : sem_item (FUNC, stack), m_checker (NULL), m_compared_func (NULL)
237 bb_sizes.create (0);
238 bb_sorted.create (0);
241 sem_function::sem_function (cgraph_node *node, bitmap_obstack *stack)
242 : sem_item (FUNC, node, stack), m_checker (NULL), m_compared_func (NULL)
244 bb_sizes.create (0);
245 bb_sorted.create (0);
248 sem_function::~sem_function ()
250 for (unsigned i = 0; i < bb_sorted.length (); i++)
251 delete (bb_sorted[i]);
253 bb_sizes.release ();
254 bb_sorted.release ();
257 /* Calculates hash value based on a BASIC_BLOCK. */
259 hashval_t
260 sem_function::get_bb_hash (const sem_bb *basic_block)
262 inchash::hash hstate;
264 hstate.add_int (basic_block->nondbg_stmt_count);
265 hstate.add_int (basic_block->edge_count);
267 return hstate.end ();
270 /* References independent hash function. */
272 hashval_t
273 sem_function::get_hash (void)
275 if (!m_hash_set)
277 inchash::hash hstate;
278 hstate.add_int (177454); /* Random number for function type. */
280 hstate.add_int (arg_count);
281 hstate.add_int (cfg_checksum);
282 hstate.add_int (gcode_hash);
284 for (unsigned i = 0; i < bb_sorted.length (); i++)
285 hstate.merge_hash (get_bb_hash (bb_sorted[i]));
287 for (unsigned i = 0; i < bb_sizes.length (); i++)
288 hstate.add_int (bb_sizes[i]);
290 /* Add common features of declaration itself. */
291 if (DECL_FUNCTION_SPECIFIC_TARGET (decl))
292 hstate.add_hwi
293 (cl_target_option_hash
294 (TREE_TARGET_OPTION (DECL_FUNCTION_SPECIFIC_TARGET (decl))));
295 if (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl))
296 hstate.add_hwi
297 (cl_optimization_hash
298 (TREE_OPTIMIZATION (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl))));
299 hstate.add_flag (DECL_CXX_CONSTRUCTOR_P (decl));
300 hstate.add_flag (DECL_CXX_DESTRUCTOR_P (decl));
302 set_hash (hstate.end ());
305 return m_hash;
308 /* Return ture if A1 and A2 represent equivalent function attribute lists.
309 Based on comp_type_attributes. */
311 bool
312 sem_item::compare_attributes (const_tree a1, const_tree a2)
314 const_tree a;
315 if (a1 == a2)
316 return true;
317 for (a = a1; a != NULL_TREE; a = TREE_CHAIN (a))
319 const struct attribute_spec *as;
320 const_tree attr;
322 as = lookup_attribute_spec (get_attribute_name (a));
323 /* TODO: We can introduce as->affects_decl_identity
324 and as->affects_decl_reference_identity if attribute mismatch
325 gets a common reason to give up on merging. It may not be worth
326 the effort.
327 For example returns_nonnull affects only references, while
328 optimize attribute can be ignored because it is already lowered
329 into flags representation and compared separately. */
330 if (!as)
331 continue;
333 attr = lookup_attribute (as->name, CONST_CAST_TREE (a2));
334 if (!attr || !attribute_value_equal (a, attr))
335 break;
337 if (!a)
339 for (a = a2; a != NULL_TREE; a = TREE_CHAIN (a))
341 const struct attribute_spec *as;
343 as = lookup_attribute_spec (get_attribute_name (a));
344 if (!as)
345 continue;
347 if (!lookup_attribute (as->name, CONST_CAST_TREE (a1)))
348 break;
349 /* We don't need to compare trees again, as we did this
350 already in first loop. */
352 if (!a)
353 return true;
355 /* TODO: As in comp_type_attributes we may want to introduce target hook. */
356 return false;
359 /* Compare properties of symbols N1 and N2 that does not affect semantics of
360 symbol itself but affects semantics of its references from USED_BY (which
361 may be NULL if it is unknown). If comparsion is false, symbols
362 can still be merged but any symbols referring them can't.
364 If ADDRESS is true, do extra checking needed for IPA_REF_ADDR.
366 TODO: We can also split attributes to those that determine codegen of
367 a function body/variable constructor itself and those that are used when
368 referring to it. */
370 bool
371 sem_item::compare_referenced_symbol_properties (symtab_node *used_by,
372 symtab_node *n1,
373 symtab_node *n2,
374 bool address)
376 if (is_a <cgraph_node *> (n1))
378 /* Inline properties matters: we do now want to merge uses of inline
379 function to uses of normal function because inline hint would be lost.
380 We however can merge inline function to noinline because the alias
381 will keep its DECL_DECLARED_INLINE flag.
383 Also ignore inline flag when optimizing for size or when function
384 is known to not be inlinable.
386 TODO: the optimize_size checks can also be assumed to be true if
387 unit has no !optimize_size functions. */
389 if ((!used_by || address || !is_a <cgraph_node *> (used_by)
390 || !opt_for_fn (used_by->decl, optimize_size))
391 && !opt_for_fn (n1->decl, optimize_size)
392 && n1->get_availability () > AVAIL_INTERPOSABLE
393 && (!DECL_UNINLINABLE (n1->decl) || !DECL_UNINLINABLE (n2->decl)))
395 if (DECL_DISREGARD_INLINE_LIMITS (n1->decl)
396 != DECL_DISREGARD_INLINE_LIMITS (n2->decl))
397 return return_false_with_msg
398 ("DECL_DISREGARD_INLINE_LIMITS are different");
400 if (DECL_DECLARED_INLINE_P (n1->decl)
401 != DECL_DECLARED_INLINE_P (n2->decl))
402 return return_false_with_msg ("inline attributes are different");
405 if (DECL_IS_OPERATOR_NEW (n1->decl)
406 != DECL_IS_OPERATOR_NEW (n2->decl))
407 return return_false_with_msg ("operator new flags are different");
410 /* Merging two definitions with a reference to equivalent vtables, but
411 belonging to a different type may result in ipa-polymorphic-call analysis
412 giving a wrong answer about the dynamic type of instance. */
413 if (is_a <varpool_node *> (n1))
415 if ((DECL_VIRTUAL_P (n1->decl) || DECL_VIRTUAL_P (n2->decl))
416 && (DECL_VIRTUAL_P (n1->decl) != DECL_VIRTUAL_P (n2->decl)
417 || !types_must_be_same_for_odr (DECL_CONTEXT (n1->decl),
418 DECL_CONTEXT (n2->decl)))
419 && (!used_by || !is_a <cgraph_node *> (used_by) || address
420 || opt_for_fn (used_by->decl, flag_devirtualize)))
421 return return_false_with_msg
422 ("references to virtual tables can not be merged");
424 if (address && DECL_ALIGN (n1->decl) != DECL_ALIGN (n2->decl))
425 return return_false_with_msg ("alignment mismatch");
427 /* For functions we compare attributes in equals_wpa, because we do
428 not know what attributes may cause codegen differences, but for
429 variables just compare attributes for references - the codegen
430 for constructors is affected only by those attributes that we lower
431 to explicit representation (such as DECL_ALIGN or DECL_SECTION). */
432 if (!compare_attributes (DECL_ATTRIBUTES (n1->decl),
433 DECL_ATTRIBUTES (n2->decl)))
434 return return_false_with_msg ("different var decl attributes");
435 if (comp_type_attributes (TREE_TYPE (n1->decl),
436 TREE_TYPE (n2->decl)) != 1)
437 return return_false_with_msg ("different var type attributes");
440 /* When matching virtual tables, be sure to also match information
441 relevant for polymorphic call analysis. */
442 if (used_by && is_a <varpool_node *> (used_by)
443 && DECL_VIRTUAL_P (used_by->decl))
445 if (DECL_VIRTUAL_P (n1->decl) != DECL_VIRTUAL_P (n2->decl))
446 return return_false_with_msg ("virtual flag mismatch");
447 if (DECL_VIRTUAL_P (n1->decl) && is_a <cgraph_node *> (n1)
448 && (DECL_FINAL_P (n1->decl) != DECL_FINAL_P (n2->decl)))
449 return return_false_with_msg ("final flag mismatch");
451 return true;
454 /* Hash properties that are compared by compare_referenced_symbol_properties. */
456 void
457 sem_item::hash_referenced_symbol_properties (symtab_node *ref,
458 inchash::hash &hstate,
459 bool address)
461 if (is_a <cgraph_node *> (ref))
463 if ((type != FUNC || address || !opt_for_fn (decl, optimize_size))
464 && !opt_for_fn (ref->decl, optimize_size)
465 && !DECL_UNINLINABLE (ref->decl))
467 hstate.add_flag (DECL_DISREGARD_INLINE_LIMITS (ref->decl));
468 hstate.add_flag (DECL_DECLARED_INLINE_P (ref->decl));
470 hstate.add_flag (DECL_IS_OPERATOR_NEW (ref->decl));
472 else if (is_a <varpool_node *> (ref))
474 hstate.add_flag (DECL_VIRTUAL_P (ref->decl));
475 if (address)
476 hstate.add_int (DECL_ALIGN (ref->decl));
481 /* For a given symbol table nodes N1 and N2, we check that FUNCTION_DECLs
482 point to a same function. Comparison can be skipped if IGNORED_NODES
483 contains these nodes. ADDRESS indicate if address is taken. */
485 bool
486 sem_item::compare_symbol_references (
487 hash_map <symtab_node *, sem_item *> &ignored_nodes,
488 symtab_node *n1, symtab_node *n2, bool address)
490 enum availability avail1, avail2;
492 if (n1 == n2)
493 return true;
495 /* Never match variable and function. */
496 if (is_a <varpool_node *> (n1) != is_a <varpool_node *> (n2))
497 return false;
499 if (!compare_referenced_symbol_properties (node, n1, n2, address))
500 return false;
501 if (address && n1->equal_address_to (n2) == 1)
502 return true;
503 if (!address && n1->semantically_equivalent_p (n2))
504 return true;
506 n1 = n1->ultimate_alias_target (&avail1);
507 n2 = n2->ultimate_alias_target (&avail2);
509 if (avail1 > AVAIL_INTERPOSABLE && ignored_nodes.get (n1)
510 && avail2 > AVAIL_INTERPOSABLE && ignored_nodes.get (n2))
511 return true;
513 return return_false_with_msg ("different references");
516 /* If cgraph edges E1 and E2 are indirect calls, verify that
517 ECF flags are the same. */
519 bool sem_function::compare_edge_flags (cgraph_edge *e1, cgraph_edge *e2)
521 if (e1->indirect_info && e2->indirect_info)
523 int e1_flags = e1->indirect_info->ecf_flags;
524 int e2_flags = e2->indirect_info->ecf_flags;
526 if (e1_flags != e2_flags)
527 return return_false_with_msg ("ICF flags are different");
529 else if (e1->indirect_info || e2->indirect_info)
530 return false;
532 return true;
535 /* Return true if parameter I may be used. */
537 bool
538 sem_function::param_used_p (unsigned int i)
540 if (ipa_node_params_sum == NULL)
541 return true;
543 struct ipa_node_params *parms_info = IPA_NODE_REF (get_node ());
545 if (vec_safe_length (parms_info->descriptors) <= i)
546 return true;
548 return ipa_is_param_used (IPA_NODE_REF (get_node ()), i);
551 /* Perform additional check needed to match types function parameters that are
552 used. Unlike for normal decls it matters if type is TYPE_RESTRICT and we
553 make an assumption that REFERENCE_TYPE parameters are always non-NULL. */
555 bool
556 sem_function::compatible_parm_types_p (tree parm1, tree parm2)
558 /* Be sure that parameters are TBAA compatible. */
559 if (!func_checker::compatible_types_p (parm1, parm2))
560 return return_false_with_msg ("parameter type is not compatible");
562 if (POINTER_TYPE_P (parm1)
563 && (TYPE_RESTRICT (parm1) != TYPE_RESTRICT (parm2)))
564 return return_false_with_msg ("argument restrict flag mismatch");
566 /* nonnull_arg_p implies non-zero range to REFERENCE types. */
567 if (POINTER_TYPE_P (parm1)
568 && TREE_CODE (parm1) != TREE_CODE (parm2)
569 && opt_for_fn (decl, flag_delete_null_pointer_checks))
570 return return_false_with_msg ("pointer wrt reference mismatch");
572 return true;
575 /* Fast equality function based on knowledge known in WPA. */
577 bool
578 sem_function::equals_wpa (sem_item *item,
579 hash_map <symtab_node *, sem_item *> &ignored_nodes)
581 gcc_assert (item->type == FUNC);
582 cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
583 cgraph_node *cnode2 = dyn_cast <cgraph_node *> (item->node);
585 m_compared_func = static_cast<sem_function *> (item);
587 if (cnode->thunk.thunk_p != cnode2->thunk.thunk_p)
588 return return_false_with_msg ("thunk_p mismatch");
590 if (cnode->thunk.thunk_p)
592 if (cnode->thunk.fixed_offset != cnode2->thunk.fixed_offset)
593 return return_false_with_msg ("thunk fixed_offset mismatch");
594 if (cnode->thunk.virtual_value != cnode2->thunk.virtual_value)
595 return return_false_with_msg ("thunk virtual_value mismatch");
596 if (cnode->thunk.indirect_offset != cnode2->thunk.indirect_offset)
597 return return_false_with_msg ("thunk indirect_offset mismatch");
598 if (cnode->thunk.this_adjusting != cnode2->thunk.this_adjusting)
599 return return_false_with_msg ("thunk this_adjusting mismatch");
600 if (cnode->thunk.virtual_offset_p != cnode2->thunk.virtual_offset_p)
601 return return_false_with_msg ("thunk virtual_offset_p mismatch");
602 if (cnode->thunk.add_pointer_bounds_args
603 != cnode2->thunk.add_pointer_bounds_args)
604 return return_false_with_msg ("thunk add_pointer_bounds_args mismatch");
607 /* Compare special function DECL attributes. */
608 if (DECL_FUNCTION_PERSONALITY (decl)
609 != DECL_FUNCTION_PERSONALITY (item->decl))
610 return return_false_with_msg ("function personalities are different");
612 if (DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl)
613 != DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (item->decl))
614 return return_false_with_msg ("intrument function entry exit "
615 "attributes are different");
617 if (DECL_NO_LIMIT_STACK (decl) != DECL_NO_LIMIT_STACK (item->decl))
618 return return_false_with_msg ("no stack limit attributes are different");
620 if (DECL_CXX_CONSTRUCTOR_P (decl) != DECL_CXX_CONSTRUCTOR_P (item->decl))
621 return return_false_with_msg ("DECL_CXX_CONSTRUCTOR mismatch");
623 if (DECL_CXX_DESTRUCTOR_P (decl) != DECL_CXX_DESTRUCTOR_P (item->decl))
624 return return_false_with_msg ("DECL_CXX_DESTRUCTOR mismatch");
626 /* TODO: pure/const flags mostly matters only for references, except for
627 the fact that codegen takes LOOPING flag as a hint that loops are
628 finite. We may arrange the code to always pick leader that has least
629 specified flags and then this can go into comparing symbol properties. */
630 if (flags_from_decl_or_type (decl) != flags_from_decl_or_type (item->decl))
631 return return_false_with_msg ("decl_or_type flags are different");
633 /* Do not match polymorphic constructors of different types. They calls
634 type memory location for ipa-polymorphic-call and we do not want
635 it to get confused by wrong type. */
636 if (DECL_CXX_CONSTRUCTOR_P (decl)
637 && TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
639 if (TREE_CODE (TREE_TYPE (item->decl)) != METHOD_TYPE)
640 return return_false_with_msg ("DECL_CXX_CONSTURCTOR type mismatch");
641 else if (!func_checker::compatible_polymorphic_types_p
642 (TYPE_METHOD_BASETYPE (TREE_TYPE (decl)),
643 TYPE_METHOD_BASETYPE (TREE_TYPE (item->decl)), false))
644 return return_false_with_msg ("ctor polymorphic type mismatch");
647 /* Checking function TARGET and OPTIMIZATION flags. */
648 cl_target_option *tar1 = target_opts_for_fn (decl);
649 cl_target_option *tar2 = target_opts_for_fn (item->decl);
651 if (tar1 != tar2 && !cl_target_option_eq (tar1, tar2))
653 if (dump_file && (dump_flags & TDF_DETAILS))
655 fprintf (dump_file, "target flags difference");
656 cl_target_option_print_diff (dump_file, 2, tar1, tar2);
659 return return_false_with_msg ("Target flags are different");
662 cl_optimization *opt1 = opts_for_fn (decl);
663 cl_optimization *opt2 = opts_for_fn (item->decl);
665 if (opt1 != opt2 && !cl_optimization_option_eq (opt1, opt2))
667 if (dump_file && (dump_flags & TDF_DETAILS))
669 fprintf (dump_file, "optimization flags difference");
670 cl_optimization_print_diff (dump_file, 2, opt1, opt2);
673 return return_false_with_msg ("optimization flags are different");
676 /* Result type checking. */
677 if (!func_checker::compatible_types_p
678 (TREE_TYPE (TREE_TYPE (decl)),
679 TREE_TYPE (TREE_TYPE (m_compared_func->decl))))
680 return return_false_with_msg ("result types are different");
682 /* Checking types of arguments. */
683 tree list1 = TYPE_ARG_TYPES (TREE_TYPE (decl)),
684 list2 = TYPE_ARG_TYPES (TREE_TYPE (m_compared_func->decl));
685 for (unsigned i = 0; list1 && list2;
686 list1 = TREE_CHAIN (list1), list2 = TREE_CHAIN (list2), i++)
688 tree parm1 = TREE_VALUE (list1);
689 tree parm2 = TREE_VALUE (list2);
691 /* This guard is here for function pointer with attributes (pr59927.c). */
692 if (!parm1 || !parm2)
693 return return_false_with_msg ("NULL argument type");
695 /* Verify that types are compatible to ensure that both functions
696 have same calling conventions. */
697 if (!types_compatible_p (parm1, parm2))
698 return return_false_with_msg ("parameter types are not compatible");
700 if (!param_used_p (i))
701 continue;
703 /* Perform additional checks for used parameters. */
704 if (!compatible_parm_types_p (parm1, parm2))
705 return false;
708 if (list1 || list2)
709 return return_false_with_msg ("Mismatched number of parameters");
711 if (node->num_references () != item->node->num_references ())
712 return return_false_with_msg ("different number of references");
714 /* Checking function attributes.
715 This is quadratic in number of attributes */
716 if (comp_type_attributes (TREE_TYPE (decl),
717 TREE_TYPE (item->decl)) != 1)
718 return return_false_with_msg ("different type attributes");
719 if (!compare_attributes (DECL_ATTRIBUTES (decl),
720 DECL_ATTRIBUTES (item->decl)))
721 return return_false_with_msg ("different decl attributes");
723 /* The type of THIS pointer type memory location for
724 ipa-polymorphic-call-analysis. */
725 if (opt_for_fn (decl, flag_devirtualize)
726 && (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
727 || TREE_CODE (TREE_TYPE (item->decl)) == METHOD_TYPE)
728 && param_used_p (0)
729 && compare_polymorphic_p ())
731 if (TREE_CODE (TREE_TYPE (decl)) != TREE_CODE (TREE_TYPE (item->decl)))
732 return return_false_with_msg ("METHOD_TYPE and FUNCTION_TYPE mismatch");
733 if (!func_checker::compatible_polymorphic_types_p
734 (TYPE_METHOD_BASETYPE (TREE_TYPE (decl)),
735 TYPE_METHOD_BASETYPE (TREE_TYPE (item->decl)), false))
736 return return_false_with_msg ("THIS pointer ODR type mismatch");
739 ipa_ref *ref = NULL, *ref2 = NULL;
740 for (unsigned i = 0; node->iterate_reference (i, ref); i++)
742 item->node->iterate_reference (i, ref2);
744 if (ref->use != ref2->use)
745 return return_false_with_msg ("reference use mismatch");
747 if (!compare_symbol_references (ignored_nodes, ref->referred,
748 ref2->referred,
749 ref->address_matters_p ()))
750 return false;
753 cgraph_edge *e1 = dyn_cast <cgraph_node *> (node)->callees;
754 cgraph_edge *e2 = dyn_cast <cgraph_node *> (item->node)->callees;
756 while (e1 && e2)
758 if (!compare_symbol_references (ignored_nodes, e1->callee,
759 e2->callee, false))
760 return false;
761 if (!compare_edge_flags (e1, e2))
762 return false;
764 e1 = e1->next_callee;
765 e2 = e2->next_callee;
768 if (e1 || e2)
769 return return_false_with_msg ("different number of calls");
771 e1 = dyn_cast <cgraph_node *> (node)->indirect_calls;
772 e2 = dyn_cast <cgraph_node *> (item->node)->indirect_calls;
774 while (e1 && e2)
776 if (!compare_edge_flags (e1, e2))
777 return false;
779 e1 = e1->next_callee;
780 e2 = e2->next_callee;
783 if (e1 || e2)
784 return return_false_with_msg ("different number of indirect calls");
786 return true;
789 /* Update hash by address sensitive references. We iterate over all
790 sensitive references (address_matters_p) and we hash ultime alias
791 target of these nodes, which can improve a semantic item hash.
793 Also hash in referenced symbols properties. This can be done at any time
794 (as the properties should not change), but it is convenient to do it here
795 while we walk the references anyway. */
797 void
798 sem_item::update_hash_by_addr_refs (hash_map <symtab_node *,
799 sem_item *> &m_symtab_node_map)
801 ipa_ref* ref;
802 inchash::hash hstate (get_hash ());
804 for (unsigned i = 0; node->iterate_reference (i, ref); i++)
806 hstate.add_int (ref->use);
807 hash_referenced_symbol_properties (ref->referred, hstate,
808 ref->use == IPA_REF_ADDR);
809 if (ref->address_matters_p () || !m_symtab_node_map.get (ref->referred))
810 hstate.add_int (ref->referred->ultimate_alias_target ()->order);
813 if (is_a <cgraph_node *> (node))
815 for (cgraph_edge *e = dyn_cast <cgraph_node *> (node)->callers; e;
816 e = e->next_caller)
818 sem_item **result = m_symtab_node_map.get (e->callee);
819 hash_referenced_symbol_properties (e->callee, hstate, false);
820 if (!result)
821 hstate.add_int (e->callee->ultimate_alias_target ()->order);
825 set_hash (hstate.end ());
828 /* Update hash by computed local hash values taken from different
829 semantic items.
830 TODO: stronger SCC based hashing would be desirable here. */
832 void
833 sem_item::update_hash_by_local_refs (hash_map <symtab_node *,
834 sem_item *> &m_symtab_node_map)
836 ipa_ref* ref;
837 inchash::hash state (get_hash ());
839 for (unsigned j = 0; node->iterate_reference (j, ref); j++)
841 sem_item **result = m_symtab_node_map.get (ref->referring);
842 if (result)
843 state.merge_hash ((*result)->get_hash ());
846 if (type == FUNC)
848 for (cgraph_edge *e = dyn_cast <cgraph_node *> (node)->callees; e;
849 e = e->next_callee)
851 sem_item **result = m_symtab_node_map.get (e->caller);
852 if (result)
853 state.merge_hash ((*result)->get_hash ());
857 global_hash = state.end ();
860 /* Returns true if the item equals to ITEM given as argument. */
862 bool
863 sem_function::equals (sem_item *item,
864 hash_map <symtab_node *, sem_item *> &)
866 gcc_assert (item->type == FUNC);
867 bool eq = equals_private (item);
869 if (m_checker != NULL)
871 delete m_checker;
872 m_checker = NULL;
875 if (dump_file && (dump_flags & TDF_DETAILS))
876 fprintf (dump_file,
877 "Equals called for: %s:%s with result: %s\n\n",
878 node->dump_name (),
879 item->node->dump_name (),
880 eq ? "true" : "false");
882 return eq;
885 /* Processes function equality comparison. */
887 bool
888 sem_function::equals_private (sem_item *item)
890 if (item->type != FUNC)
891 return false;
893 basic_block bb1, bb2;
894 edge e1, e2;
895 edge_iterator ei1, ei2;
896 bool result = true;
897 tree arg1, arg2;
899 m_compared_func = static_cast<sem_function *> (item);
901 gcc_assert (decl != item->decl);
903 if (bb_sorted.length () != m_compared_func->bb_sorted.length ()
904 || edge_count != m_compared_func->edge_count
905 || cfg_checksum != m_compared_func->cfg_checksum)
906 return return_false ();
908 m_checker = new func_checker (decl, m_compared_func->decl,
909 compare_polymorphic_p (),
910 false,
911 &refs_set,
912 &m_compared_func->refs_set);
913 arg1 = DECL_ARGUMENTS (decl);
914 arg2 = DECL_ARGUMENTS (m_compared_func->decl);
915 for (unsigned i = 0;
916 arg1 && arg2; arg1 = DECL_CHAIN (arg1), arg2 = DECL_CHAIN (arg2), i++)
918 if (!types_compatible_p (TREE_TYPE (arg1), TREE_TYPE (arg2)))
919 return return_false_with_msg ("argument types are not compatible");
920 if (!param_used_p (i))
921 continue;
922 /* Perform additional checks for used parameters. */
923 if (!compatible_parm_types_p (TREE_TYPE (arg1), TREE_TYPE (arg2)))
924 return false;
925 if (!m_checker->compare_decl (arg1, arg2))
926 return return_false ();
928 if (arg1 || arg2)
929 return return_false_with_msg ("Mismatched number of arguments");
931 if (!dyn_cast <cgraph_node *> (node)->has_gimple_body_p ())
932 return true;
934 /* Fill-up label dictionary. */
935 for (unsigned i = 0; i < bb_sorted.length (); ++i)
937 m_checker->parse_labels (bb_sorted[i]);
938 m_checker->parse_labels (m_compared_func->bb_sorted[i]);
941 /* Checking all basic blocks. */
942 for (unsigned i = 0; i < bb_sorted.length (); ++i)
943 if(!m_checker->compare_bb (bb_sorted[i], m_compared_func->bb_sorted[i]))
944 return return_false();
946 dump_message ("All BBs are equal\n");
948 auto_vec <int> bb_dict;
950 /* Basic block edges check. */
951 for (unsigned i = 0; i < bb_sorted.length (); ++i)
953 bb1 = bb_sorted[i]->bb;
954 bb2 = m_compared_func->bb_sorted[i]->bb;
956 ei2 = ei_start (bb2->preds);
958 for (ei1 = ei_start (bb1->preds); ei_cond (ei1, &e1); ei_next (&ei1))
960 ei_cond (ei2, &e2);
962 if (e1->flags != e2->flags)
963 return return_false_with_msg ("flags comparison returns false");
965 if (!bb_dict_test (&bb_dict, e1->src->index, e2->src->index))
966 return return_false_with_msg ("edge comparison returns false");
968 if (!bb_dict_test (&bb_dict, e1->dest->index, e2->dest->index))
969 return return_false_with_msg ("BB comparison returns false");
971 if (!m_checker->compare_edge (e1, e2))
972 return return_false_with_msg ("edge comparison returns false");
974 ei_next (&ei2);
978 /* Basic block PHI nodes comparison. */
979 for (unsigned i = 0; i < bb_sorted.length (); i++)
980 if (!compare_phi_node (bb_sorted[i]->bb, m_compared_func->bb_sorted[i]->bb))
981 return return_false_with_msg ("PHI node comparison returns false");
983 return result;
986 /* Set LOCAL_P of NODE to true if DATA is non-NULL.
987 Helper for call_for_symbol_thunks_and_aliases. */
989 static bool
990 set_local (cgraph_node *node, void *data)
992 node->local.local = data != NULL;
993 return false;
996 /* TREE_ADDRESSABLE of NODE to true.
997 Helper for call_for_symbol_thunks_and_aliases. */
999 static bool
1000 set_addressable (varpool_node *node, void *)
1002 TREE_ADDRESSABLE (node->decl) = 1;
1003 return false;
1006 /* Clear DECL_RTL of NODE.
1007 Helper for call_for_symbol_thunks_and_aliases. */
1009 static bool
1010 clear_decl_rtl (symtab_node *node, void *)
1012 SET_DECL_RTL (node->decl, NULL);
1013 return false;
1016 /* Redirect all callers of N and its aliases to TO. Remove aliases if
1017 possible. Return number of redirections made. */
1019 static int
1020 redirect_all_callers (cgraph_node *n, cgraph_node *to)
1022 int nredirected = 0;
1023 ipa_ref *ref;
1024 cgraph_edge *e = n->callers;
1026 while (e)
1028 /* Redirecting thunks to interposable symbols or symbols in other sections
1029 may not be supported by target output code. Play safe for now and
1030 punt on redirection. */
1031 if (!e->caller->thunk.thunk_p)
1033 struct cgraph_edge *nexte = e->next_caller;
1034 e->redirect_callee (to);
1035 e = nexte;
1036 nredirected++;
1038 else
1039 e = e->next_callee;
1041 for (unsigned i = 0; n->iterate_direct_aliases (i, ref);)
1043 bool removed = false;
1044 cgraph_node *n_alias = dyn_cast <cgraph_node *> (ref->referring);
1046 if ((DECL_COMDAT_GROUP (n->decl)
1047 && (DECL_COMDAT_GROUP (n->decl)
1048 == DECL_COMDAT_GROUP (n_alias->decl)))
1049 || (n_alias->get_availability () > AVAIL_INTERPOSABLE
1050 && n->get_availability () > AVAIL_INTERPOSABLE))
1052 nredirected += redirect_all_callers (n_alias, to);
1053 if (n_alias->can_remove_if_no_direct_calls_p ()
1054 && !n_alias->call_for_symbol_and_aliases (cgraph_node::has_thunk_p,
1055 NULL, true)
1056 && !n_alias->has_aliases_p ())
1057 n_alias->remove ();
1059 if (!removed)
1060 i++;
1062 return nredirected;
1065 /* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can
1066 be applied. */
1068 bool
1069 sem_function::merge (sem_item *alias_item)
1071 gcc_assert (alias_item->type == FUNC);
1073 sem_function *alias_func = static_cast<sem_function *> (alias_item);
1075 cgraph_node *original = get_node ();
1076 cgraph_node *local_original = NULL;
1077 cgraph_node *alias = alias_func->get_node ();
1079 bool create_wrapper = false;
1080 bool create_alias = false;
1081 bool redirect_callers = false;
1082 bool remove = false;
1084 bool original_discardable = false;
1085 bool original_discarded = false;
1087 bool original_address_matters = original->address_matters_p ();
1088 bool alias_address_matters = alias->address_matters_p ();
1090 if (DECL_EXTERNAL (alias->decl))
1092 if (dump_file)
1093 fprintf (dump_file, "Not unifying; alias is external.\n\n");
1094 return false;
1097 if (DECL_NO_INLINE_WARNING_P (original->decl)
1098 != DECL_NO_INLINE_WARNING_P (alias->decl))
1100 if (dump_file)
1101 fprintf (dump_file,
1102 "Not unifying; "
1103 "DECL_NO_INLINE_WARNING mismatch.\n\n");
1104 return false;
1107 /* Do not attempt to mix functions from different user sections;
1108 we do not know what user intends with those. */
1109 if (((DECL_SECTION_NAME (original->decl) && !original->implicit_section)
1110 || (DECL_SECTION_NAME (alias->decl) && !alias->implicit_section))
1111 && DECL_SECTION_NAME (original->decl) != DECL_SECTION_NAME (alias->decl))
1113 if (dump_file)
1114 fprintf (dump_file,
1115 "Not unifying; "
1116 "original and alias are in different sections.\n\n");
1117 return false;
1120 if (!original->in_same_comdat_group_p (alias)
1121 || original->comdat_local_p ())
1123 if (dump_file)
1124 fprintf (dump_file,
1125 "Not unifying; alias nor wrapper cannot be created; "
1126 "across comdat group boundary\n\n");
1128 return false;
1131 /* See if original is in a section that can be discarded if the main
1132 symbol is not used. */
1134 if (original->can_be_discarded_p ())
1135 original_discardable = true;
1136 /* Also consider case where we have resolution info and we know that
1137 original's definition is not going to be used. In this case we can not
1138 create alias to original. */
1139 if (node->resolution != LDPR_UNKNOWN
1140 && !decl_binds_to_current_def_p (node->decl))
1141 original_discardable = original_discarded = true;
1143 /* Creating a symtab alias is the optimal way to merge.
1144 It however can not be used in the following cases:
1146 1) if ORIGINAL and ALIAS may be possibly compared for address equality.
1147 2) if ORIGINAL is in a section that may be discarded by linker or if
1148 it is an external functions where we can not create an alias
1149 (ORIGINAL_DISCARDABLE)
1150 3) if target do not support symbol aliases.
1151 4) original and alias lie in different comdat groups.
1153 If we can not produce alias, we will turn ALIAS into WRAPPER of ORIGINAL
1154 and/or redirect all callers from ALIAS to ORIGINAL. */
1155 if ((original_address_matters && alias_address_matters)
1156 || (original_discardable
1157 && (!DECL_COMDAT_GROUP (alias->decl)
1158 || (DECL_COMDAT_GROUP (alias->decl)
1159 != DECL_COMDAT_GROUP (original->decl))))
1160 || original_discarded
1161 || !sem_item::target_supports_symbol_aliases_p ()
1162 || DECL_COMDAT_GROUP (alias->decl) != DECL_COMDAT_GROUP (original->decl))
1164 /* First see if we can produce wrapper. */
1166 /* Symbol properties that matter for references must be preserved.
1167 TODO: We can produce wrapper, but we need to produce alias of ORIGINAL
1168 with proper properties. */
1169 if (!sem_item::compare_referenced_symbol_properties (NULL, original, alias,
1170 alias->address_taken))
1172 if (dump_file)
1173 fprintf (dump_file,
1174 "Wrapper cannot be created because referenced symbol "
1175 "properties mismatch\n");
1177 /* Do not turn function in one comdat group into wrapper to another
1178 comdat group. Other compiler producing the body of the
1179 another comdat group may make opossite decision and with unfortunate
1180 linker choices this may close a loop. */
1181 else if (DECL_COMDAT_GROUP (original->decl)
1182 && DECL_COMDAT_GROUP (alias->decl)
1183 && (DECL_COMDAT_GROUP (alias->decl)
1184 != DECL_COMDAT_GROUP (original->decl)))
1186 if (dump_file)
1187 fprintf (dump_file,
1188 "Wrapper cannot be created because of COMDAT\n");
1190 else if (DECL_STATIC_CHAIN (alias->decl)
1191 || DECL_STATIC_CHAIN (original->decl))
1193 if (dump_file)
1194 fprintf (dump_file,
1195 "Cannot create wrapper of nested function.\n");
1197 /* TODO: We can also deal with variadic functions never calling
1198 VA_START. */
1199 else if (stdarg_p (TREE_TYPE (alias->decl)))
1201 if (dump_file)
1202 fprintf (dump_file,
1203 "can not create wrapper of stdarg function.\n");
1205 else if (ipa_fn_summaries
1206 && ipa_fn_summaries->get (alias) != NULL
1207 && ipa_fn_summaries->get (alias)->self_size <= 2)
1209 if (dump_file)
1210 fprintf (dump_file, "Wrapper creation is not "
1211 "profitable (function is too small).\n");
1213 /* If user paid attention to mark function noinline, assume it is
1214 somewhat special and do not try to turn it into a wrapper that can
1215 not be undone by inliner. */
1216 else if (lookup_attribute ("noinline", DECL_ATTRIBUTES (alias->decl)))
1218 if (dump_file)
1219 fprintf (dump_file, "Wrappers are not created for noinline.\n");
1221 else
1222 create_wrapper = true;
1224 /* We can redirect local calls in the case both alias and orignal
1225 are not interposable. */
1226 redirect_callers
1227 = alias->get_availability () > AVAIL_INTERPOSABLE
1228 && original->get_availability () > AVAIL_INTERPOSABLE;
1229 /* TODO: We can redirect, but we need to produce alias of ORIGINAL
1230 with proper properties. */
1231 if (!sem_item::compare_referenced_symbol_properties (NULL, original, alias,
1232 alias->address_taken))
1233 redirect_callers = false;
1235 if (!redirect_callers && !create_wrapper)
1237 if (dump_file)
1238 fprintf (dump_file, "Not unifying; can not redirect callers nor "
1239 "produce wrapper\n\n");
1240 return false;
1243 /* Work out the symbol the wrapper should call.
1244 If ORIGINAL is interposable, we need to call a local alias.
1245 Also produce local alias (if possible) as an optimization.
1247 Local aliases can not be created inside comdat groups because that
1248 prevents inlining. */
1249 if (!original_discardable && !original->get_comdat_group ())
1251 local_original
1252 = dyn_cast <cgraph_node *> (original->noninterposable_alias ());
1253 if (!local_original
1254 && original->get_availability () > AVAIL_INTERPOSABLE)
1255 local_original = original;
1257 /* If we can not use local alias, fallback to the original
1258 when possible. */
1259 else if (original->get_availability () > AVAIL_INTERPOSABLE)
1260 local_original = original;
1262 /* If original is COMDAT local, we can not really redirect calls outside
1263 of its comdat group to it. */
1264 if (original->comdat_local_p ())
1265 redirect_callers = false;
1266 if (!local_original)
1268 if (dump_file)
1269 fprintf (dump_file, "Not unifying; "
1270 "can not produce local alias.\n\n");
1271 return false;
1274 if (!redirect_callers && !create_wrapper)
1276 if (dump_file)
1277 fprintf (dump_file, "Not unifying; "
1278 "can not redirect callers nor produce a wrapper\n\n");
1279 return false;
1281 if (!create_wrapper
1282 && !alias->call_for_symbol_and_aliases (cgraph_node::has_thunk_p,
1283 NULL, true)
1284 && !alias->can_remove_if_no_direct_calls_p ())
1286 if (dump_file)
1287 fprintf (dump_file, "Not unifying; can not make wrapper and "
1288 "function has other uses than direct calls\n\n");
1289 return false;
1292 else
1293 create_alias = true;
1295 if (redirect_callers)
1297 int nredirected = redirect_all_callers (alias, local_original);
1299 if (nredirected)
1301 alias->icf_merged = true;
1302 local_original->icf_merged = true;
1304 if (dump_file && nredirected)
1305 fprintf (dump_file, "%i local calls have been "
1306 "redirected.\n", nredirected);
1309 /* If all callers was redirected, do not produce wrapper. */
1310 if (alias->can_remove_if_no_direct_calls_p ()
1311 && !DECL_VIRTUAL_P (alias->decl)
1312 && !alias->has_aliases_p ())
1314 create_wrapper = false;
1315 remove = true;
1317 gcc_assert (!create_alias);
1319 else if (create_alias)
1321 alias->icf_merged = true;
1323 /* Remove the function's body. */
1324 ipa_merge_profiles (original, alias);
1325 alias->release_body (true);
1326 alias->reset ();
1327 /* Notice global symbol possibly produced RTL. */
1328 ((symtab_node *)alias)->call_for_symbol_and_aliases (clear_decl_rtl,
1329 NULL, true);
1331 /* Create the alias. */
1332 cgraph_node::create_alias (alias_func->decl, decl);
1333 alias->resolve_alias (original);
1335 original->call_for_symbol_thunks_and_aliases
1336 (set_local, (void *)(size_t) original->local_p (), true);
1338 if (dump_file)
1339 fprintf (dump_file, "Unified; Function alias has been created.\n\n");
1341 if (create_wrapper)
1343 gcc_assert (!create_alias);
1344 alias->icf_merged = true;
1345 local_original->icf_merged = true;
1347 /* FIXME update local_original counts. */
1348 ipa_merge_profiles (original, alias, true);
1349 alias->create_wrapper (local_original);
1351 if (dump_file)
1352 fprintf (dump_file, "Unified; Wrapper has been created.\n\n");
1355 /* It's possible that redirection can hit thunks that block
1356 redirection opportunities. */
1357 gcc_assert (alias->icf_merged || remove || redirect_callers);
1358 original->icf_merged = true;
1360 /* We use merged flag to track cases where COMDAT function is known to be
1361 compatible its callers. If we merged in non-COMDAT, we need to give up
1362 on this optimization. */
1363 if (original->merged_comdat && !alias->merged_comdat)
1365 if (dump_file)
1366 fprintf (dump_file, "Dropping merged_comdat flag.\n\n");
1367 if (local_original)
1368 local_original->merged_comdat = false;
1369 original->merged_comdat = false;
1372 if (remove)
1374 ipa_merge_profiles (original, alias);
1375 alias->release_body ();
1376 alias->reset ();
1377 alias->body_removed = true;
1378 alias->icf_merged = true;
1379 if (dump_file)
1380 fprintf (dump_file, "Unified; Function body was removed.\n");
1383 return true;
1386 /* Semantic item initialization function. */
1388 void
1389 sem_function::init (void)
1391 if (in_lto_p)
1392 get_node ()->get_untransformed_body ();
1394 tree fndecl = node->decl;
1395 function *func = DECL_STRUCT_FUNCTION (fndecl);
1397 gcc_assert (func);
1398 gcc_assert (SSANAMES (func));
1400 ssa_names_size = SSANAMES (func)->length ();
1401 node = node;
1403 decl = fndecl;
1404 region_tree = func->eh->region_tree;
1406 /* iterating all function arguments. */
1407 arg_count = count_formal_params (fndecl);
1409 edge_count = n_edges_for_fn (func);
1410 cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
1411 if (!cnode->thunk.thunk_p)
1413 cfg_checksum = coverage_compute_cfg_checksum (func);
1415 inchash::hash hstate;
1417 basic_block bb;
1418 FOR_EACH_BB_FN (bb, func)
1420 unsigned nondbg_stmt_count = 0;
1422 edge e;
1423 for (edge_iterator ei = ei_start (bb->preds); ei_cond (ei, &e);
1424 ei_next (&ei))
1425 cfg_checksum = iterative_hash_host_wide_int (e->flags,
1426 cfg_checksum);
1428 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
1429 gsi_next (&gsi))
1431 gimple *stmt = gsi_stmt (gsi);
1433 if (gimple_code (stmt) != GIMPLE_DEBUG
1434 && gimple_code (stmt) != GIMPLE_PREDICT)
1436 hash_stmt (stmt, hstate);
1437 nondbg_stmt_count++;
1441 hstate.commit_flag ();
1442 gcode_hash = hstate.end ();
1443 bb_sizes.safe_push (nondbg_stmt_count);
1445 /* Inserting basic block to hash table. */
1446 sem_bb *semantic_bb = new sem_bb (bb, nondbg_stmt_count,
1447 EDGE_COUNT (bb->preds)
1448 + EDGE_COUNT (bb->succs));
1450 bb_sorted.safe_push (semantic_bb);
1453 else
1455 cfg_checksum = 0;
1456 inchash::hash hstate;
1457 hstate.add_hwi (cnode->thunk.fixed_offset);
1458 hstate.add_hwi (cnode->thunk.virtual_value);
1459 hstate.add_flag (cnode->thunk.this_adjusting);
1460 hstate.add_flag (cnode->thunk.virtual_offset_p);
1461 hstate.add_flag (cnode->thunk.add_pointer_bounds_args);
1462 gcode_hash = hstate.end ();
1466 /* Accumulate to HSTATE a hash of expression EXP.
1467 Identical to inchash::add_expr, but guaranteed to be stable across LTO
1468 and DECL equality classes. */
1470 void
1471 sem_item::add_expr (const_tree exp, inchash::hash &hstate)
1473 if (exp == NULL_TREE)
1475 hstate.merge_hash (0);
1476 return;
1479 /* Handled component can be matched in a cureful way proving equivalence
1480 even if they syntactically differ. Just skip them. */
1481 STRIP_NOPS (exp);
1482 while (handled_component_p (exp))
1483 exp = TREE_OPERAND (exp, 0);
1485 enum tree_code code = TREE_CODE (exp);
1486 hstate.add_int (code);
1488 switch (code)
1490 /* Use inchash::add_expr for everything that is LTO stable. */
1491 case VOID_CST:
1492 case INTEGER_CST:
1493 case REAL_CST:
1494 case FIXED_CST:
1495 case STRING_CST:
1496 case COMPLEX_CST:
1497 case VECTOR_CST:
1498 inchash::add_expr (exp, hstate);
1499 break;
1500 case CONSTRUCTOR:
1502 unsigned HOST_WIDE_INT idx;
1503 tree value;
1505 hstate.add_hwi (int_size_in_bytes (TREE_TYPE (exp)));
1507 FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, value)
1508 if (value)
1509 add_expr (value, hstate);
1510 break;
1512 case ADDR_EXPR:
1513 case FDESC_EXPR:
1514 add_expr (get_base_address (TREE_OPERAND (exp, 0)), hstate);
1515 break;
1516 case SSA_NAME:
1517 case VAR_DECL:
1518 case CONST_DECL:
1519 case PARM_DECL:
1520 hstate.add_hwi (int_size_in_bytes (TREE_TYPE (exp)));
1521 break;
1522 case MEM_REF:
1523 case POINTER_PLUS_EXPR:
1524 case MINUS_EXPR:
1525 case RANGE_EXPR:
1526 add_expr (TREE_OPERAND (exp, 0), hstate);
1527 add_expr (TREE_OPERAND (exp, 1), hstate);
1528 break;
1529 case PLUS_EXPR:
1531 inchash::hash one, two;
1532 add_expr (TREE_OPERAND (exp, 0), one);
1533 add_expr (TREE_OPERAND (exp, 1), two);
1534 hstate.add_commutative (one, two);
1536 break;
1537 CASE_CONVERT:
1538 hstate.add_hwi (int_size_in_bytes (TREE_TYPE (exp)));
1539 return add_expr (TREE_OPERAND (exp, 0), hstate);
1540 default:
1541 break;
1545 /* Accumulate to HSTATE a hash of type t.
1546 TYpes that may end up being compatible after LTO type merging needs to have
1547 the same hash. */
1549 void
1550 sem_item::add_type (const_tree type, inchash::hash &hstate)
1552 if (type == NULL_TREE)
1554 hstate.merge_hash (0);
1555 return;
1558 type = TYPE_MAIN_VARIANT (type);
1560 hstate.add_int (TYPE_MODE (type));
1562 if (TREE_CODE (type) == COMPLEX_TYPE)
1564 hstate.add_int (COMPLEX_TYPE);
1565 sem_item::add_type (TREE_TYPE (type), hstate);
1567 else if (INTEGRAL_TYPE_P (type))
1569 hstate.add_int (INTEGER_TYPE);
1570 hstate.add_flag (TYPE_UNSIGNED (type));
1571 hstate.add_int (TYPE_PRECISION (type));
1573 else if (VECTOR_TYPE_P (type))
1575 hstate.add_int (VECTOR_TYPE);
1576 hstate.add_int (TYPE_PRECISION (type));
1577 sem_item::add_type (TREE_TYPE (type), hstate);
1579 else if (TREE_CODE (type) == ARRAY_TYPE)
1581 hstate.add_int (ARRAY_TYPE);
1582 /* Do not hash size, so complete and incomplete types can match. */
1583 sem_item::add_type (TREE_TYPE (type), hstate);
1585 else if (RECORD_OR_UNION_TYPE_P (type))
1587 /* Incomplete types must be skipped here. */
1588 if (!COMPLETE_TYPE_P (type))
1590 hstate.add_int (RECORD_TYPE);
1591 return;
1594 hashval_t *val = m_type_hash_cache.get (type);
1596 if (!val)
1598 inchash::hash hstate2;
1599 unsigned nf;
1600 tree f;
1601 hashval_t hash;
1603 hstate2.add_int (RECORD_TYPE);
1604 for (f = TYPE_FIELDS (type), nf = 0; f; f = TREE_CHAIN (f))
1605 if (TREE_CODE (f) == FIELD_DECL)
1607 add_type (TREE_TYPE (f), hstate2);
1608 nf++;
1611 hstate2.add_int (nf);
1612 hash = hstate2.end ();
1613 hstate.add_hwi (hash);
1614 m_type_hash_cache.put (type, hash);
1616 else
1617 hstate.add_hwi (*val);
1621 /* Improve accumulated hash for HSTATE based on a gimple statement STMT. */
1623 void
1624 sem_function::hash_stmt (gimple *stmt, inchash::hash &hstate)
1626 enum gimple_code code = gimple_code (stmt);
1628 hstate.add_int (code);
1630 switch (code)
1632 case GIMPLE_SWITCH:
1633 add_expr (gimple_switch_index (as_a <gswitch *> (stmt)), hstate);
1634 break;
1635 case GIMPLE_ASSIGN:
1636 hstate.add_int (gimple_assign_rhs_code (stmt));
1637 if (commutative_tree_code (gimple_assign_rhs_code (stmt))
1638 || commutative_ternary_tree_code (gimple_assign_rhs_code (stmt)))
1640 inchash::hash one, two;
1642 add_expr (gimple_assign_rhs1 (stmt), one);
1643 add_type (TREE_TYPE (gimple_assign_rhs1 (stmt)), one);
1644 add_expr (gimple_assign_rhs2 (stmt), two);
1645 hstate.add_commutative (one, two);
1646 if (commutative_ternary_tree_code (gimple_assign_rhs_code (stmt)))
1648 add_expr (gimple_assign_rhs3 (stmt), hstate);
1649 add_type (TREE_TYPE (gimple_assign_rhs3 (stmt)), hstate);
1651 add_expr (gimple_assign_lhs (stmt), hstate);
1652 add_type (TREE_TYPE (gimple_assign_lhs (stmt)), two);
1653 break;
1655 /* fall through */
1656 case GIMPLE_CALL:
1657 case GIMPLE_ASM:
1658 case GIMPLE_COND:
1659 case GIMPLE_GOTO:
1660 case GIMPLE_RETURN:
1661 /* All these statements are equivalent if their operands are. */
1662 for (unsigned i = 0; i < gimple_num_ops (stmt); ++i)
1664 add_expr (gimple_op (stmt, i), hstate);
1665 if (gimple_op (stmt, i))
1666 add_type (TREE_TYPE (gimple_op (stmt, i)), hstate);
1668 /* Consider nocf_check attribute in hash as it affects code
1669 generation. */
1670 if (code == GIMPLE_CALL
1671 && flag_cf_protection & CF_BRANCH)
1672 hstate.add_flag (gimple_call_nocf_check_p (as_a <gcall *> (stmt)));
1673 default:
1674 break;
1679 /* Return true if polymorphic comparison must be processed. */
1681 bool
1682 sem_function::compare_polymorphic_p (void)
1684 struct cgraph_edge *e;
1686 if (!opt_for_fn (get_node ()->decl, flag_devirtualize))
1687 return false;
1688 if (get_node ()->indirect_calls != NULL)
1689 return true;
1690 /* TODO: We can do simple propagation determining what calls may lead to
1691 a polymorphic call. */
1692 for (e = get_node ()->callees; e; e = e->next_callee)
1693 if (e->callee->definition
1694 && opt_for_fn (e->callee->decl, flag_devirtualize))
1695 return true;
1696 return false;
1699 /* For a given call graph NODE, the function constructs new
1700 semantic function item. */
1702 sem_function *
1703 sem_function::parse (cgraph_node *node, bitmap_obstack *stack)
1705 tree fndecl = node->decl;
1706 function *func = DECL_STRUCT_FUNCTION (fndecl);
1708 if (!func || (!node->has_gimple_body_p () && !node->thunk.thunk_p))
1709 return NULL;
1711 if (lookup_attribute_by_prefix ("omp ", DECL_ATTRIBUTES (node->decl)) != NULL)
1712 return NULL;
1714 if (lookup_attribute_by_prefix ("oacc ",
1715 DECL_ATTRIBUTES (node->decl)) != NULL)
1716 return NULL;
1718 /* PR ipa/70306. */
1719 if (DECL_STATIC_CONSTRUCTOR (node->decl)
1720 || DECL_STATIC_DESTRUCTOR (node->decl))
1721 return NULL;
1723 sem_function *f = new sem_function (node, stack);
1725 f->init ();
1727 return f;
1730 /* For given basic blocks BB1 and BB2 (from functions FUNC1 and FUNC),
1731 return true if phi nodes are semantically equivalent in these blocks . */
1733 bool
1734 sem_function::compare_phi_node (basic_block bb1, basic_block bb2)
1736 gphi_iterator si1, si2;
1737 gphi *phi1, *phi2;
1738 unsigned size1, size2, i;
1739 tree t1, t2;
1740 edge e1, e2;
1742 gcc_assert (bb1 != NULL);
1743 gcc_assert (bb2 != NULL);
1745 si2 = gsi_start_phis (bb2);
1746 for (si1 = gsi_start_phis (bb1); !gsi_end_p (si1);
1747 gsi_next (&si1))
1749 gsi_next_nonvirtual_phi (&si1);
1750 gsi_next_nonvirtual_phi (&si2);
1752 if (gsi_end_p (si1) && gsi_end_p (si2))
1753 break;
1755 if (gsi_end_p (si1) || gsi_end_p (si2))
1756 return return_false();
1758 phi1 = si1.phi ();
1759 phi2 = si2.phi ();
1761 tree phi_result1 = gimple_phi_result (phi1);
1762 tree phi_result2 = gimple_phi_result (phi2);
1764 if (!m_checker->compare_operand (phi_result1, phi_result2))
1765 return return_false_with_msg ("PHI results are different");
1767 size1 = gimple_phi_num_args (phi1);
1768 size2 = gimple_phi_num_args (phi2);
1770 if (size1 != size2)
1771 return return_false ();
1773 for (i = 0; i < size1; ++i)
1775 t1 = gimple_phi_arg (phi1, i)->def;
1776 t2 = gimple_phi_arg (phi2, i)->def;
1778 if (!m_checker->compare_operand (t1, t2))
1779 return return_false ();
1781 e1 = gimple_phi_arg_edge (phi1, i);
1782 e2 = gimple_phi_arg_edge (phi2, i);
1784 if (!m_checker->compare_edge (e1, e2))
1785 return return_false ();
1788 gsi_next (&si2);
1791 return true;
1794 /* Returns true if tree T can be compared as a handled component. */
1796 bool
1797 sem_function::icf_handled_component_p (tree t)
1799 tree_code tc = TREE_CODE (t);
1801 return (handled_component_p (t)
1802 || tc == ADDR_EXPR || tc == MEM_REF || tc == OBJ_TYPE_REF);
1805 /* Basic blocks dictionary BB_DICT returns true if SOURCE index BB
1806 corresponds to TARGET. */
1808 bool
1809 sem_function::bb_dict_test (vec<int> *bb_dict, int source, int target)
1811 source++;
1812 target++;
1814 if (bb_dict->length () <= (unsigned)source)
1815 bb_dict->safe_grow_cleared (source + 1);
1817 if ((*bb_dict)[source] == 0)
1819 (*bb_dict)[source] = target;
1820 return true;
1822 else
1823 return (*bb_dict)[source] == target;
1826 sem_variable::sem_variable (bitmap_obstack *stack): sem_item (VAR, stack)
1830 sem_variable::sem_variable (varpool_node *node, bitmap_obstack *stack)
1831 : sem_item (VAR, node, stack)
1833 gcc_checking_assert (node);
1834 gcc_checking_assert (get_node ());
1837 /* Fast equality function based on knowledge known in WPA. */
1839 bool
1840 sem_variable::equals_wpa (sem_item *item,
1841 hash_map <symtab_node *, sem_item *> &ignored_nodes)
1843 gcc_assert (item->type == VAR);
1845 if (node->num_references () != item->node->num_references ())
1846 return return_false_with_msg ("different number of references");
1848 if (DECL_TLS_MODEL (decl) || DECL_TLS_MODEL (item->decl))
1849 return return_false_with_msg ("TLS model");
1851 /* DECL_ALIGN is safe to merge, because we will always chose the largest
1852 alignment out of all aliases. */
1854 if (DECL_VIRTUAL_P (decl) != DECL_VIRTUAL_P (item->decl))
1855 return return_false_with_msg ("Virtual flag mismatch");
1857 if (DECL_SIZE (decl) != DECL_SIZE (item->decl)
1858 && ((!DECL_SIZE (decl) || !DECL_SIZE (item->decl))
1859 || !operand_equal_p (DECL_SIZE (decl),
1860 DECL_SIZE (item->decl), OEP_ONLY_CONST)))
1861 return return_false_with_msg ("size mismatch");
1863 /* Do not attempt to mix data from different user sections;
1864 we do not know what user intends with those. */
1865 if (((DECL_SECTION_NAME (decl) && !node->implicit_section)
1866 || (DECL_SECTION_NAME (item->decl) && !item->node->implicit_section))
1867 && DECL_SECTION_NAME (decl) != DECL_SECTION_NAME (item->decl))
1868 return return_false_with_msg ("user section mismatch");
1870 if (DECL_IN_TEXT_SECTION (decl) != DECL_IN_TEXT_SECTION (item->decl))
1871 return return_false_with_msg ("text section");
1873 ipa_ref *ref = NULL, *ref2 = NULL;
1874 for (unsigned i = 0; node->iterate_reference (i, ref); i++)
1876 item->node->iterate_reference (i, ref2);
1878 if (ref->use != ref2->use)
1879 return return_false_with_msg ("reference use mismatch");
1881 if (!compare_symbol_references (ignored_nodes,
1882 ref->referred, ref2->referred,
1883 ref->address_matters_p ()))
1884 return false;
1887 return true;
1890 /* Returns true if the item equals to ITEM given as argument. */
1892 bool
1893 sem_variable::equals (sem_item *item,
1894 hash_map <symtab_node *, sem_item *> &)
1896 gcc_assert (item->type == VAR);
1897 bool ret;
1899 if (DECL_INITIAL (decl) == error_mark_node && in_lto_p)
1900 dyn_cast <varpool_node *>(node)->get_constructor ();
1901 if (DECL_INITIAL (item->decl) == error_mark_node && in_lto_p)
1902 dyn_cast <varpool_node *>(item->node)->get_constructor ();
1904 /* As seen in PR ipa/65303 we have to compare variables types. */
1905 if (!func_checker::compatible_types_p (TREE_TYPE (decl),
1906 TREE_TYPE (item->decl)))
1907 return return_false_with_msg ("variables types are different");
1909 ret = sem_variable::equals (DECL_INITIAL (decl),
1910 DECL_INITIAL (item->node->decl));
1911 if (dump_file && (dump_flags & TDF_DETAILS))
1912 fprintf (dump_file,
1913 "Equals called for vars: %s:%s with result: %s\n\n",
1914 node->dump_name (), item->node->dump_name (),
1915 ret ? "true" : "false");
1917 return ret;
1920 /* Compares trees T1 and T2 for semantic equality. */
1922 bool
1923 sem_variable::equals (tree t1, tree t2)
1925 if (!t1 || !t2)
1926 return return_with_debug (t1 == t2);
1927 if (t1 == t2)
1928 return true;
1929 tree_code tc1 = TREE_CODE (t1);
1930 tree_code tc2 = TREE_CODE (t2);
1932 if (tc1 != tc2)
1933 return return_false_with_msg ("TREE_CODE mismatch");
1935 switch (tc1)
1937 case CONSTRUCTOR:
1939 vec<constructor_elt, va_gc> *v1, *v2;
1940 unsigned HOST_WIDE_INT idx;
1942 enum tree_code typecode = TREE_CODE (TREE_TYPE (t1));
1943 if (typecode != TREE_CODE (TREE_TYPE (t2)))
1944 return return_false_with_msg ("constructor type mismatch");
1946 if (typecode == ARRAY_TYPE)
1948 HOST_WIDE_INT size_1 = int_size_in_bytes (TREE_TYPE (t1));
1949 /* For arrays, check that the sizes all match. */
1950 if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2))
1951 || size_1 == -1
1952 || size_1 != int_size_in_bytes (TREE_TYPE (t2)))
1953 return return_false_with_msg ("constructor array size mismatch");
1955 else if (!func_checker::compatible_types_p (TREE_TYPE (t1),
1956 TREE_TYPE (t2)))
1957 return return_false_with_msg ("constructor type incompatible");
1959 v1 = CONSTRUCTOR_ELTS (t1);
1960 v2 = CONSTRUCTOR_ELTS (t2);
1961 if (vec_safe_length (v1) != vec_safe_length (v2))
1962 return return_false_with_msg ("constructor number of elts mismatch");
1964 for (idx = 0; idx < vec_safe_length (v1); ++idx)
1966 constructor_elt *c1 = &(*v1)[idx];
1967 constructor_elt *c2 = &(*v2)[idx];
1969 /* Check that each value is the same... */
1970 if (!sem_variable::equals (c1->value, c2->value))
1971 return false;
1972 /* ... and that they apply to the same fields! */
1973 if (!sem_variable::equals (c1->index, c2->index))
1974 return false;
1976 return true;
1978 case MEM_REF:
1980 tree x1 = TREE_OPERAND (t1, 0);
1981 tree x2 = TREE_OPERAND (t2, 0);
1982 tree y1 = TREE_OPERAND (t1, 1);
1983 tree y2 = TREE_OPERAND (t2, 1);
1985 if (!func_checker::compatible_types_p (TREE_TYPE (x1), TREE_TYPE (x2)))
1986 return return_false ();
1988 /* Type of the offset on MEM_REF does not matter. */
1989 return return_with_debug (sem_variable::equals (x1, x2)
1990 && known_eq (wi::to_poly_offset (y1),
1991 wi::to_poly_offset (y2)));
1993 case ADDR_EXPR:
1994 case FDESC_EXPR:
1996 tree op1 = TREE_OPERAND (t1, 0);
1997 tree op2 = TREE_OPERAND (t2, 0);
1998 return sem_variable::equals (op1, op2);
2000 /* References to other vars/decls are compared using ipa-ref. */
2001 case FUNCTION_DECL:
2002 case VAR_DECL:
2003 if (decl_in_symtab_p (t1) && decl_in_symtab_p (t2))
2004 return true;
2005 return return_false_with_msg ("Declaration mismatch");
2006 case CONST_DECL:
2007 /* TODO: We can check CONST_DECL by its DECL_INITIAL, but for that we
2008 need to process its VAR/FUNCTION references without relying on ipa-ref
2009 compare. */
2010 case FIELD_DECL:
2011 case LABEL_DECL:
2012 return return_false_with_msg ("Declaration mismatch");
2013 case INTEGER_CST:
2014 /* Integer constants are the same only if the same width of type. */
2015 if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2)))
2016 return return_false_with_msg ("INTEGER_CST precision mismatch");
2017 if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2)))
2018 return return_false_with_msg ("INTEGER_CST mode mismatch");
2019 return return_with_debug (tree_int_cst_equal (t1, t2));
2020 case STRING_CST:
2021 if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2)))
2022 return return_false_with_msg ("STRING_CST mode mismatch");
2023 if (TREE_STRING_LENGTH (t1) != TREE_STRING_LENGTH (t2))
2024 return return_false_with_msg ("STRING_CST length mismatch");
2025 if (memcmp (TREE_STRING_POINTER (t1), TREE_STRING_POINTER (t2),
2026 TREE_STRING_LENGTH (t1)))
2027 return return_false_with_msg ("STRING_CST mismatch");
2028 return true;
2029 case FIXED_CST:
2030 /* Fixed constants are the same only if the same width of type. */
2031 if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2)))
2032 return return_false_with_msg ("FIXED_CST precision mismatch");
2034 return return_with_debug (FIXED_VALUES_IDENTICAL (TREE_FIXED_CST (t1),
2035 TREE_FIXED_CST (t2)));
2036 case COMPLEX_CST:
2037 return (sem_variable::equals (TREE_REALPART (t1), TREE_REALPART (t2))
2038 && sem_variable::equals (TREE_IMAGPART (t1), TREE_IMAGPART (t2)));
2039 case REAL_CST:
2040 /* Real constants are the same only if the same width of type. */
2041 if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2)))
2042 return return_false_with_msg ("REAL_CST precision mismatch");
2043 return return_with_debug (real_identical (&TREE_REAL_CST (t1),
2044 &TREE_REAL_CST (t2)));
2045 case VECTOR_CST:
2047 if (maybe_ne (VECTOR_CST_NELTS (t1), VECTOR_CST_NELTS (t2)))
2048 return return_false_with_msg ("VECTOR_CST nelts mismatch");
2050 unsigned int count
2051 = tree_vector_builder::binary_encoded_nelts (t1, t2);
2052 for (unsigned int i = 0; i < count; ++i)
2053 if (!sem_variable::equals (VECTOR_CST_ENCODED_ELT (t1, i),
2054 VECTOR_CST_ENCODED_ELT (t2, i)))
2055 return false;
2057 return true;
2059 case ARRAY_REF:
2060 case ARRAY_RANGE_REF:
2062 tree x1 = TREE_OPERAND (t1, 0);
2063 tree x2 = TREE_OPERAND (t2, 0);
2064 tree y1 = TREE_OPERAND (t1, 1);
2065 tree y2 = TREE_OPERAND (t2, 1);
2067 if (!sem_variable::equals (x1, x2) || !sem_variable::equals (y1, y2))
2068 return false;
2069 if (!sem_variable::equals (array_ref_low_bound (t1),
2070 array_ref_low_bound (t2)))
2071 return false;
2072 if (!sem_variable::equals (array_ref_element_size (t1),
2073 array_ref_element_size (t2)))
2074 return false;
2075 return true;
2078 case COMPONENT_REF:
2079 case POINTER_PLUS_EXPR:
2080 case PLUS_EXPR:
2081 case MINUS_EXPR:
2082 case RANGE_EXPR:
2084 tree x1 = TREE_OPERAND (t1, 0);
2085 tree x2 = TREE_OPERAND (t2, 0);
2086 tree y1 = TREE_OPERAND (t1, 1);
2087 tree y2 = TREE_OPERAND (t2, 1);
2089 return sem_variable::equals (x1, x2) && sem_variable::equals (y1, y2);
2092 CASE_CONVERT:
2093 case VIEW_CONVERT_EXPR:
2094 if (!func_checker::compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2)))
2095 return return_false ();
2096 return sem_variable::equals (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
2097 case ERROR_MARK:
2098 return return_false_with_msg ("ERROR_MARK");
2099 default:
2100 return return_false_with_msg ("Unknown TREE code reached");
2104 /* Parser function that visits a varpool NODE. */
2106 sem_variable *
2107 sem_variable::parse (varpool_node *node, bitmap_obstack *stack)
2109 if (TREE_THIS_VOLATILE (node->decl) || DECL_HARD_REGISTER (node->decl)
2110 || node->alias)
2111 return NULL;
2113 sem_variable *v = new sem_variable (node, stack);
2115 v->init ();
2117 return v;
2120 /* References independent hash function. */
2122 hashval_t
2123 sem_variable::get_hash (void)
2125 if (m_hash_set)
2126 return m_hash;
2128 /* All WPA streamed in symbols should have their hashes computed at compile
2129 time. At this point, the constructor may not be in memory at all.
2130 DECL_INITIAL (decl) would be error_mark_node in that case. */
2131 gcc_assert (!node->lto_file_data);
2132 tree ctor = DECL_INITIAL (decl);
2133 inchash::hash hstate;
2135 hstate.add_int (456346417);
2136 if (DECL_SIZE (decl) && tree_fits_shwi_p (DECL_SIZE (decl)))
2137 hstate.add_hwi (tree_to_shwi (DECL_SIZE (decl)));
2138 add_expr (ctor, hstate);
2139 set_hash (hstate.end ());
2141 return m_hash;
2144 /* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can
2145 be applied. */
2147 bool
2148 sem_variable::merge (sem_item *alias_item)
2150 gcc_assert (alias_item->type == VAR);
2152 if (!sem_item::target_supports_symbol_aliases_p ())
2154 if (dump_file)
2155 fprintf (dump_file, "Not unifying; "
2156 "Symbol aliases are not supported by target\n\n");
2157 return false;
2160 if (DECL_EXTERNAL (alias_item->decl))
2162 if (dump_file)
2163 fprintf (dump_file, "Not unifying; alias is external.\n\n");
2164 return false;
2167 sem_variable *alias_var = static_cast<sem_variable *> (alias_item);
2169 varpool_node *original = get_node ();
2170 varpool_node *alias = alias_var->get_node ();
2171 bool original_discardable = false;
2173 bool alias_address_matters = alias->address_matters_p ();
2175 /* See if original is in a section that can be discarded if the main
2176 symbol is not used.
2177 Also consider case where we have resolution info and we know that
2178 original's definition is not going to be used. In this case we can not
2179 create alias to original. */
2180 if (original->can_be_discarded_p ()
2181 || (node->resolution != LDPR_UNKNOWN
2182 && !decl_binds_to_current_def_p (node->decl)))
2183 original_discardable = true;
2185 gcc_assert (!TREE_ASM_WRITTEN (alias->decl));
2187 /* Constant pool machinery is not quite ready for aliases.
2188 TODO: varasm code contains logic for merging DECL_IN_CONSTANT_POOL.
2189 For LTO merging does not happen that is an important missing feature.
2190 We can enable merging with LTO if the DECL_IN_CONSTANT_POOL
2191 flag is dropped and non-local symbol name is assigned. */
2192 if (DECL_IN_CONSTANT_POOL (alias->decl)
2193 || DECL_IN_CONSTANT_POOL (original->decl))
2195 if (dump_file)
2196 fprintf (dump_file,
2197 "Not unifying; constant pool variables.\n\n");
2198 return false;
2201 /* Do not attempt to mix functions from different user sections;
2202 we do not know what user intends with those. */
2203 if (((DECL_SECTION_NAME (original->decl) && !original->implicit_section)
2204 || (DECL_SECTION_NAME (alias->decl) && !alias->implicit_section))
2205 && DECL_SECTION_NAME (original->decl) != DECL_SECTION_NAME (alias->decl))
2207 if (dump_file)
2208 fprintf (dump_file,
2209 "Not unifying; "
2210 "original and alias are in different sections.\n\n");
2211 return false;
2214 /* We can not merge if address comparsion metters. */
2215 if (alias_address_matters && flag_merge_constants < 2)
2217 if (dump_file)
2218 fprintf (dump_file,
2219 "Not unifying; address of original may be compared.\n\n");
2220 return false;
2223 if (DECL_ALIGN (original->decl) < DECL_ALIGN (alias->decl))
2225 if (dump_file)
2226 fprintf (dump_file, "Not unifying; "
2227 "original and alias have incompatible alignments\n\n");
2229 return false;
2232 if (DECL_COMDAT_GROUP (original->decl) != DECL_COMDAT_GROUP (alias->decl))
2234 if (dump_file)
2235 fprintf (dump_file, "Not unifying; alias cannot be created; "
2236 "across comdat group boundary\n\n");
2238 return false;
2241 if (original_discardable)
2243 if (dump_file)
2244 fprintf (dump_file, "Not unifying; alias cannot be created; "
2245 "target is discardable\n\n");
2247 return false;
2249 else
2251 gcc_assert (!original->alias);
2252 gcc_assert (!alias->alias);
2254 alias->analyzed = false;
2256 DECL_INITIAL (alias->decl) = NULL;
2257 ((symtab_node *)alias)->call_for_symbol_and_aliases (clear_decl_rtl,
2258 NULL, true);
2259 alias->need_bounds_init = false;
2260 alias->remove_all_references ();
2261 if (TREE_ADDRESSABLE (alias->decl))
2262 original->call_for_symbol_and_aliases (set_addressable, NULL, true);
2264 varpool_node::create_alias (alias_var->decl, decl);
2265 alias->resolve_alias (original);
2267 if (dump_file)
2268 fprintf (dump_file, "Unified; Variable alias has been created.\n");
2270 return true;
2274 /* Dump symbol to FILE. */
2276 void
2277 sem_variable::dump_to_file (FILE *file)
2279 gcc_assert (file);
2281 print_node (file, "", decl, 0);
2282 fprintf (file, "\n\n");
2285 unsigned int sem_item_optimizer::class_id = 0;
2287 sem_item_optimizer::sem_item_optimizer ()
2288 : worklist (0), m_classes (0), m_classes_count (0), m_cgraph_node_hooks (NULL),
2289 m_varpool_node_hooks (NULL), m_merged_variables ()
2291 m_items.create (0);
2292 bitmap_obstack_initialize (&m_bmstack);
2295 sem_item_optimizer::~sem_item_optimizer ()
2297 for (unsigned int i = 0; i < m_items.length (); i++)
2298 delete m_items[i];
2301 for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
2302 it != m_classes.end (); ++it)
2304 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
2305 delete (*it)->classes[i];
2307 (*it)->classes.release ();
2308 free (*it);
2311 m_items.release ();
2313 bitmap_obstack_release (&m_bmstack);
2314 m_merged_variables.release ();
2317 /* Write IPA ICF summary for symbols. */
2319 void
2320 sem_item_optimizer::write_summary (void)
2322 unsigned int count = 0;
2324 output_block *ob = create_output_block (LTO_section_ipa_icf);
2325 lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
2326 ob->symbol = NULL;
2328 /* Calculate number of symbols to be serialized. */
2329 for (lto_symtab_encoder_iterator lsei = lsei_start_in_partition (encoder);
2330 !lsei_end_p (lsei);
2331 lsei_next_in_partition (&lsei))
2333 symtab_node *node = lsei_node (lsei);
2335 if (m_symtab_node_map.get (node))
2336 count++;
2339 streamer_write_uhwi (ob, count);
2341 /* Process all of the symbols. */
2342 for (lto_symtab_encoder_iterator lsei = lsei_start_in_partition (encoder);
2343 !lsei_end_p (lsei);
2344 lsei_next_in_partition (&lsei))
2346 symtab_node *node = lsei_node (lsei);
2348 sem_item **item = m_symtab_node_map.get (node);
2350 if (item && *item)
2352 int node_ref = lto_symtab_encoder_encode (encoder, node);
2353 streamer_write_uhwi_stream (ob->main_stream, node_ref);
2355 streamer_write_uhwi (ob, (*item)->get_hash ());
2359 streamer_write_char_stream (ob->main_stream, 0);
2360 produce_asm (ob, NULL);
2361 destroy_output_block (ob);
2364 /* Reads a section from LTO stream file FILE_DATA. Input block for DATA
2365 contains LEN bytes. */
2367 void
2368 sem_item_optimizer::read_section (lto_file_decl_data *file_data,
2369 const char *data, size_t len)
2371 const lto_function_header *header
2372 = (const lto_function_header *) data;
2373 const int cfg_offset = sizeof (lto_function_header);
2374 const int main_offset = cfg_offset + header->cfg_size;
2375 const int string_offset = main_offset + header->main_size;
2376 data_in *data_in;
2377 unsigned int i;
2378 unsigned int count;
2380 lto_input_block ib_main ((const char *) data + main_offset, 0,
2381 header->main_size, file_data->mode_table);
2383 data_in
2384 = lto_data_in_create (file_data, (const char *) data + string_offset,
2385 header->string_size, vNULL);
2387 count = streamer_read_uhwi (&ib_main);
2389 for (i = 0; i < count; i++)
2391 unsigned int index;
2392 symtab_node *node;
2393 lto_symtab_encoder_t encoder;
2395 index = streamer_read_uhwi (&ib_main);
2396 encoder = file_data->symtab_node_encoder;
2397 node = lto_symtab_encoder_deref (encoder, index);
2399 hashval_t hash = streamer_read_uhwi (&ib_main);
2401 gcc_assert (node->definition);
2403 if (dump_file)
2404 fprintf (dump_file, "Symbol added: %s (tree: %p)\n",
2405 node->dump_asm_name (), (void *) node->decl);
2407 if (is_a<cgraph_node *> (node))
2409 cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
2411 sem_function *fn = new sem_function (cnode, &m_bmstack);
2412 fn->set_hash (hash);
2413 m_items.safe_push (fn);
2415 else
2417 varpool_node *vnode = dyn_cast <varpool_node *> (node);
2419 sem_variable *var = new sem_variable (vnode, &m_bmstack);
2420 var->set_hash (hash);
2421 m_items.safe_push (var);
2425 lto_free_section_data (file_data, LTO_section_ipa_icf, NULL, data,
2426 len);
2427 lto_data_in_delete (data_in);
2430 /* Read IPA ICF summary for symbols. */
2432 void
2433 sem_item_optimizer::read_summary (void)
2435 lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
2436 lto_file_decl_data *file_data;
2437 unsigned int j = 0;
2439 while ((file_data = file_data_vec[j++]))
2441 size_t len;
2442 const char *data = lto_get_section_data (file_data,
2443 LTO_section_ipa_icf, NULL, &len);
2445 if (data)
2446 read_section (file_data, data, len);
2450 /* Register callgraph and varpool hooks. */
2452 void
2453 sem_item_optimizer::register_hooks (void)
2455 if (!m_cgraph_node_hooks)
2456 m_cgraph_node_hooks = symtab->add_cgraph_removal_hook
2457 (&sem_item_optimizer::cgraph_removal_hook, this);
2459 if (!m_varpool_node_hooks)
2460 m_varpool_node_hooks = symtab->add_varpool_removal_hook
2461 (&sem_item_optimizer::varpool_removal_hook, this);
2464 /* Unregister callgraph and varpool hooks. */
2466 void
2467 sem_item_optimizer::unregister_hooks (void)
2469 if (m_cgraph_node_hooks)
2470 symtab->remove_cgraph_removal_hook (m_cgraph_node_hooks);
2472 if (m_varpool_node_hooks)
2473 symtab->remove_varpool_removal_hook (m_varpool_node_hooks);
2476 /* Adds a CLS to hashtable associated by hash value. */
2478 void
2479 sem_item_optimizer::add_class (congruence_class *cls)
2481 gcc_assert (cls->members.length ());
2483 congruence_class_group *group
2484 = get_group_by_hash (cls->members[0]->get_hash (),
2485 cls->members[0]->type);
2486 group->classes.safe_push (cls);
2489 /* Gets a congruence class group based on given HASH value and TYPE. */
2491 congruence_class_group *
2492 sem_item_optimizer::get_group_by_hash (hashval_t hash, sem_item_type type)
2494 congruence_class_group *item = XNEW (congruence_class_group);
2495 item->hash = hash;
2496 item->type = type;
2498 congruence_class_group **slot = m_classes.find_slot (item, INSERT);
2500 if (*slot)
2501 free (item);
2502 else
2504 item->classes.create (1);
2505 *slot = item;
2508 return *slot;
2511 /* Callgraph removal hook called for a NODE with a custom DATA. */
2513 void
2514 sem_item_optimizer::cgraph_removal_hook (cgraph_node *node, void *data)
2516 sem_item_optimizer *optimizer = (sem_item_optimizer *) data;
2517 optimizer->remove_symtab_node (node);
2520 /* Varpool removal hook called for a NODE with a custom DATA. */
2522 void
2523 sem_item_optimizer::varpool_removal_hook (varpool_node *node, void *data)
2525 sem_item_optimizer *optimizer = (sem_item_optimizer *) data;
2526 optimizer->remove_symtab_node (node);
2529 /* Remove symtab NODE triggered by symtab removal hooks. */
2531 void
2532 sem_item_optimizer::remove_symtab_node (symtab_node *node)
2534 gcc_assert (!m_classes.elements ());
2536 m_removed_items_set.add (node);
2539 void
2540 sem_item_optimizer::remove_item (sem_item *item)
2542 if (m_symtab_node_map.get (item->node))
2543 m_symtab_node_map.remove (item->node);
2544 delete item;
2547 /* Removes all callgraph and varpool nodes that are marked by symtab
2548 as deleted. */
2550 void
2551 sem_item_optimizer::filter_removed_items (void)
2553 auto_vec <sem_item *> filtered;
2555 for (unsigned int i = 0; i < m_items.length(); i++)
2557 sem_item *item = m_items[i];
2559 if (m_removed_items_set.contains (item->node))
2561 remove_item (item);
2562 continue;
2565 if (item->type == FUNC)
2567 cgraph_node *cnode = static_cast <sem_function *>(item)->get_node ();
2569 if (in_lto_p && (cnode->alias || cnode->body_removed))
2570 remove_item (item);
2571 else
2572 filtered.safe_push (item);
2574 else /* VAR. */
2576 if (!flag_ipa_icf_variables)
2577 remove_item (item);
2578 else
2580 /* Filter out non-readonly variables. */
2581 tree decl = item->decl;
2582 if (TREE_READONLY (decl))
2583 filtered.safe_push (item);
2584 else
2585 remove_item (item);
2590 /* Clean-up of released semantic items. */
2592 m_items.release ();
2593 for (unsigned int i = 0; i < filtered.length(); i++)
2594 m_items.safe_push (filtered[i]);
2597 /* Optimizer entry point which returns true in case it processes
2598 a merge operation. True is returned if there's a merge operation
2599 processed. */
2601 bool
2602 sem_item_optimizer::execute (void)
2604 filter_removed_items ();
2605 unregister_hooks ();
2607 build_graph ();
2608 update_hash_by_addr_refs ();
2609 build_hash_based_classes ();
2611 if (dump_file)
2612 fprintf (dump_file, "Dump after hash based groups\n");
2613 dump_cong_classes ();
2615 for (unsigned int i = 0; i < m_items.length(); i++)
2616 m_items[i]->init_wpa ();
2618 subdivide_classes_by_equality (true);
2620 if (dump_file)
2621 fprintf (dump_file, "Dump after WPA based types groups\n");
2623 dump_cong_classes ();
2625 process_cong_reduction ();
2626 checking_verify_classes ();
2628 if (dump_file)
2629 fprintf (dump_file, "Dump after callgraph-based congruence reduction\n");
2631 dump_cong_classes ();
2633 parse_nonsingleton_classes ();
2634 subdivide_classes_by_equality ();
2636 if (dump_file)
2637 fprintf (dump_file, "Dump after full equality comparison of groups\n");
2639 dump_cong_classes ();
2641 unsigned int prev_class_count = m_classes_count;
2643 process_cong_reduction ();
2644 dump_cong_classes ();
2645 checking_verify_classes ();
2646 bool merged_p = merge_classes (prev_class_count);
2648 if (dump_file && (dump_flags & TDF_DETAILS))
2649 symtab->dump (dump_file);
2651 return merged_p;
2654 /* Function responsible for visiting all potential functions and
2655 read-only variables that can be merged. */
2657 void
2658 sem_item_optimizer::parse_funcs_and_vars (void)
2660 cgraph_node *cnode;
2662 if (flag_ipa_icf_functions)
2663 FOR_EACH_DEFINED_FUNCTION (cnode)
2665 sem_function *f = sem_function::parse (cnode, &m_bmstack);
2666 if (f)
2668 m_items.safe_push (f);
2669 m_symtab_node_map.put (cnode, f);
2671 if (dump_file)
2672 fprintf (dump_file, "Parsed function:%s\n", f->node->asm_name ());
2674 if (dump_file && (dump_flags & TDF_DETAILS))
2675 f->dump_to_file (dump_file);
2677 else if (dump_file)
2678 fprintf (dump_file, "Not parsed function:%s\n", cnode->asm_name ());
2681 varpool_node *vnode;
2683 if (flag_ipa_icf_variables)
2684 FOR_EACH_DEFINED_VARIABLE (vnode)
2686 sem_variable *v = sem_variable::parse (vnode, &m_bmstack);
2688 if (v)
2690 m_items.safe_push (v);
2691 m_symtab_node_map.put (vnode, v);
2696 /* Makes pairing between a congruence class CLS and semantic ITEM. */
2698 void
2699 sem_item_optimizer::add_item_to_class (congruence_class *cls, sem_item *item)
2701 item->index_in_class = cls->members.length ();
2702 cls->members.safe_push (item);
2703 item->cls = cls;
2706 /* For each semantic item, append hash values of references. */
2708 void
2709 sem_item_optimizer::update_hash_by_addr_refs ()
2711 /* First, append to hash sensitive references and class type if it need to
2712 be matched for ODR. */
2713 for (unsigned i = 0; i < m_items.length (); i++)
2715 m_items[i]->update_hash_by_addr_refs (m_symtab_node_map);
2716 if (m_items[i]->type == FUNC)
2718 if (TREE_CODE (TREE_TYPE (m_items[i]->decl)) == METHOD_TYPE
2719 && contains_polymorphic_type_p
2720 (TYPE_METHOD_BASETYPE (TREE_TYPE (m_items[i]->decl)))
2721 && (DECL_CXX_CONSTRUCTOR_P (m_items[i]->decl)
2722 || (static_cast<sem_function *> (m_items[i])->param_used_p (0)
2723 && static_cast<sem_function *> (m_items[i])
2724 ->compare_polymorphic_p ())))
2726 tree class_type
2727 = TYPE_METHOD_BASETYPE (TREE_TYPE (m_items[i]->decl));
2728 inchash::hash hstate (m_items[i]->get_hash ());
2730 if (TYPE_NAME (class_type)
2731 && DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (class_type)))
2732 hstate.add_hwi
2733 (IDENTIFIER_HASH_VALUE
2734 (DECL_ASSEMBLER_NAME (TYPE_NAME (class_type))));
2736 m_items[i]->set_hash (hstate.end ());
2741 /* Once all symbols have enhanced hash value, we can append
2742 hash values of symbols that are seen by IPA ICF and are
2743 references by a semantic item. Newly computed values
2744 are saved to global_hash member variable. */
2745 for (unsigned i = 0; i < m_items.length (); i++)
2746 m_items[i]->update_hash_by_local_refs (m_symtab_node_map);
2748 /* Global hash value replace current hash values. */
2749 for (unsigned i = 0; i < m_items.length (); i++)
2750 m_items[i]->set_hash (m_items[i]->global_hash);
2753 /* Congruence classes are built by hash value. */
2755 void
2756 sem_item_optimizer::build_hash_based_classes (void)
2758 for (unsigned i = 0; i < m_items.length (); i++)
2760 sem_item *item = m_items[i];
2762 congruence_class_group *group
2763 = get_group_by_hash (item->get_hash (), item->type);
2765 if (!group->classes.length ())
2767 m_classes_count++;
2768 group->classes.safe_push (new congruence_class (class_id++));
2771 add_item_to_class (group->classes[0], item);
2775 /* Build references according to call graph. */
2777 void
2778 sem_item_optimizer::build_graph (void)
2780 for (unsigned i = 0; i < m_items.length (); i++)
2782 sem_item *item = m_items[i];
2783 m_symtab_node_map.put (item->node, item);
2785 /* Initialize hash values if we are not in LTO mode. */
2786 if (!in_lto_p)
2787 item->get_hash ();
2790 for (unsigned i = 0; i < m_items.length (); i++)
2792 sem_item *item = m_items[i];
2794 if (item->type == FUNC)
2796 cgraph_node *cnode = dyn_cast <cgraph_node *> (item->node);
2798 cgraph_edge *e = cnode->callees;
2799 while (e)
2801 sem_item **slot = m_symtab_node_map.get
2802 (e->callee->ultimate_alias_target ());
2803 if (slot)
2804 item->add_reference (*slot);
2806 e = e->next_callee;
2810 ipa_ref *ref = NULL;
2811 for (unsigned i = 0; item->node->iterate_reference (i, ref); i++)
2813 sem_item **slot = m_symtab_node_map.get
2814 (ref->referred->ultimate_alias_target ());
2815 if (slot)
2816 item->add_reference (*slot);
2821 /* Semantic items in classes having more than one element and initialized.
2822 In case of WPA, we load function body. */
2824 void
2825 sem_item_optimizer::parse_nonsingleton_classes (void)
2827 unsigned int init_called_count = 0;
2829 for (unsigned i = 0; i < m_items.length (); i++)
2830 if (m_items[i]->cls->members.length () > 1)
2832 m_items[i]->init ();
2833 init_called_count++;
2836 if (dump_file)
2837 fprintf (dump_file, "Init called for %u items (%.2f%%).\n",
2838 init_called_count,
2839 m_items.length () ? 100.0f * init_called_count / m_items.length ()
2840 : 0.0f);
2843 /* Equality function for semantic items is used to subdivide existing
2844 classes. If IN_WPA, fast equality function is invoked. */
2846 void
2847 sem_item_optimizer::subdivide_classes_by_equality (bool in_wpa)
2849 for (hash_table <congruence_class_hash>::iterator it = m_classes.begin ();
2850 it != m_classes.end (); ++it)
2852 unsigned int class_count = (*it)->classes.length ();
2854 for (unsigned i = 0; i < class_count; i++)
2856 congruence_class *c = (*it)->classes[i];
2858 if (c->members.length() > 1)
2860 auto_vec <sem_item *> new_vector;
2862 sem_item *first = c->members[0];
2863 new_vector.safe_push (first);
2865 unsigned class_split_first = (*it)->classes.length ();
2867 for (unsigned j = 1; j < c->members.length (); j++)
2869 sem_item *item = c->members[j];
2871 bool equals
2872 = in_wpa ? first->equals_wpa (item, m_symtab_node_map)
2873 : first->equals (item, m_symtab_node_map);
2875 if (equals)
2876 new_vector.safe_push (item);
2877 else
2879 bool integrated = false;
2881 for (unsigned k = class_split_first;
2882 k < (*it)->classes.length (); k++)
2884 sem_item *x = (*it)->classes[k]->members[0];
2885 bool equals
2886 = in_wpa ? x->equals_wpa (item, m_symtab_node_map)
2887 : x->equals (item, m_symtab_node_map);
2889 if (equals)
2891 integrated = true;
2892 add_item_to_class ((*it)->classes[k], item);
2894 break;
2898 if (!integrated)
2900 congruence_class *c
2901 = new congruence_class (class_id++);
2902 m_classes_count++;
2903 add_item_to_class (c, item);
2905 (*it)->classes.safe_push (c);
2910 // We replace newly created new_vector for the class we've just
2911 // splitted.
2912 c->members.release ();
2913 c->members.create (new_vector.length ());
2915 for (unsigned int j = 0; j < new_vector.length (); j++)
2916 add_item_to_class (c, new_vector[j]);
2921 checking_verify_classes ();
2924 /* Subdivide classes by address references that members of the class
2925 reference. Example can be a pair of functions that have an address
2926 taken from a function. If these addresses are different the class
2927 is split. */
2929 unsigned
2930 sem_item_optimizer::subdivide_classes_by_sensitive_refs ()
2932 typedef hash_map <symbol_compare_hash, vec <sem_item *> > subdivide_hash_map;
2934 unsigned newly_created_classes = 0;
2936 for (hash_table <congruence_class_hash>::iterator it = m_classes.begin ();
2937 it != m_classes.end (); ++it)
2939 unsigned int class_count = (*it)->classes.length ();
2940 auto_vec<congruence_class *> new_classes;
2942 for (unsigned i = 0; i < class_count; i++)
2944 congruence_class *c = (*it)->classes[i];
2946 if (c->members.length() > 1)
2948 subdivide_hash_map split_map;
2950 for (unsigned j = 0; j < c->members.length (); j++)
2952 sem_item *source_node = c->members[j];
2954 symbol_compare_collection *collection
2955 = new symbol_compare_collection (source_node->node);
2957 bool existed;
2958 vec <sem_item *> *slot
2959 = &split_map.get_or_insert (collection, &existed);
2960 gcc_checking_assert (slot);
2962 slot->safe_push (source_node);
2964 if (existed)
2965 delete collection;
2968 /* If the map contains more than one key, we have to split
2969 the map appropriately. */
2970 if (split_map.elements () != 1)
2972 bool first_class = true;
2974 for (subdivide_hash_map::iterator it2 = split_map.begin ();
2975 it2 != split_map.end (); ++it2)
2977 congruence_class *new_cls;
2978 new_cls = new congruence_class (class_id++);
2980 for (unsigned k = 0; k < (*it2).second.length (); k++)
2981 add_item_to_class (new_cls, (*it2).second[k]);
2983 worklist_push (new_cls);
2984 newly_created_classes++;
2986 if (first_class)
2988 (*it)->classes[i] = new_cls;
2989 first_class = false;
2991 else
2993 new_classes.safe_push (new_cls);
2994 m_classes_count++;
2999 /* Release memory. */
3000 for (subdivide_hash_map::iterator it2 = split_map.begin ();
3001 it2 != split_map.end (); ++it2)
3003 delete (*it2).first;
3004 (*it2).second.release ();
3009 for (unsigned i = 0; i < new_classes.length (); i++)
3010 (*it)->classes.safe_push (new_classes[i]);
3013 return newly_created_classes;
3016 /* Verify congruence classes, if checking is enabled. */
3018 void
3019 sem_item_optimizer::checking_verify_classes (void)
3021 if (flag_checking)
3022 verify_classes ();
3025 /* Verify congruence classes. */
3027 void
3028 sem_item_optimizer::verify_classes (void)
3030 for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
3031 it != m_classes.end (); ++it)
3033 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
3035 congruence_class *cls = (*it)->classes[i];
3037 gcc_assert (cls);
3038 gcc_assert (cls->members.length () > 0);
3040 for (unsigned int j = 0; j < cls->members.length (); j++)
3042 sem_item *item = cls->members[j];
3044 gcc_assert (item);
3045 gcc_assert (item->cls == cls);
3047 for (unsigned k = 0; k < item->usages.length (); k++)
3049 sem_usage_pair *usage = item->usages[k];
3050 gcc_assert (usage->item->index_in_class
3051 < usage->item->cls->members.length ());
3058 /* Disposes split map traverse function. CLS_PTR is pointer to congruence
3059 class, BSLOT is bitmap slot we want to release. DATA is mandatory,
3060 but unused argument. */
3062 bool
3063 sem_item_optimizer::release_split_map (congruence_class * const &,
3064 bitmap const &b, traverse_split_pair *)
3066 bitmap bmp = b;
3068 BITMAP_FREE (bmp);
3070 return true;
3073 /* Process split operation for a class given as pointer CLS_PTR,
3074 where bitmap B splits congruence class members. DATA is used
3075 as argument of split pair. */
3077 bool
3078 sem_item_optimizer::traverse_congruence_split (congruence_class * const &cls,
3079 bitmap const &b,
3080 traverse_split_pair *pair)
3082 sem_item_optimizer *optimizer = pair->optimizer;
3083 const congruence_class *splitter_cls = pair->cls;
3085 /* If counted bits are greater than zero and less than the number of members
3086 a group will be splitted. */
3087 unsigned popcount = bitmap_count_bits (b);
3089 if (popcount > 0 && popcount < cls->members.length ())
3091 auto_vec <congruence_class *, 2> newclasses;
3092 newclasses.quick_push (new congruence_class (class_id++));
3093 newclasses.quick_push (new congruence_class (class_id++));
3095 for (unsigned int i = 0; i < cls->members.length (); i++)
3097 int target = bitmap_bit_p (b, i);
3098 congruence_class *tc = newclasses[target];
3100 add_item_to_class (tc, cls->members[i]);
3103 if (flag_checking)
3105 for (unsigned int i = 0; i < 2; i++)
3106 gcc_assert (newclasses[i]->members.length ());
3109 if (splitter_cls == cls)
3110 optimizer->splitter_class_removed = true;
3112 /* Remove old class from worklist if presented. */
3113 bool in_worklist = cls->in_worklist;
3115 if (in_worklist)
3116 cls->in_worklist = false;
3118 congruence_class_group g;
3119 g.hash = cls->members[0]->get_hash ();
3120 g.type = cls->members[0]->type;
3122 congruence_class_group *slot = optimizer->m_classes.find (&g);
3124 for (unsigned int i = 0; i < slot->classes.length (); i++)
3125 if (slot->classes[i] == cls)
3127 slot->classes.ordered_remove (i);
3128 break;
3131 /* New class will be inserted and integrated to work list. */
3132 for (unsigned int i = 0; i < 2; i++)
3133 optimizer->add_class (newclasses[i]);
3135 /* Two classes replace one, so that increment just by one. */
3136 optimizer->m_classes_count++;
3138 /* If OLD class was presented in the worklist, we remove the class
3139 and replace it will both newly created classes. */
3140 if (in_worklist)
3141 for (unsigned int i = 0; i < 2; i++)
3142 optimizer->worklist_push (newclasses[i]);
3143 else /* Just smaller class is inserted. */
3145 unsigned int smaller_index
3146 = (newclasses[0]->members.length ()
3147 < newclasses[1]->members.length ()
3148 ? 0 : 1);
3149 optimizer->worklist_push (newclasses[smaller_index]);
3152 if (dump_file && (dump_flags & TDF_DETAILS))
3154 fprintf (dump_file, " congruence class splitted:\n");
3155 cls->dump (dump_file, 4);
3157 fprintf (dump_file, " newly created groups:\n");
3158 for (unsigned int i = 0; i < 2; i++)
3159 newclasses[i]->dump (dump_file, 4);
3162 /* Release class if not presented in work list. */
3163 if (!in_worklist)
3164 delete cls;
3168 return true;
3171 /* Tests if a class CLS used as INDEXth splits any congruence classes.
3172 Bitmap stack BMSTACK is used for bitmap allocation. */
3174 void
3175 sem_item_optimizer::do_congruence_step_for_index (congruence_class *cls,
3176 unsigned int index)
3178 hash_map <congruence_class *, bitmap> split_map;
3180 for (unsigned int i = 0; i < cls->members.length (); i++)
3182 sem_item *item = cls->members[i];
3184 /* Iterate all usages that have INDEX as usage of the item. */
3185 for (unsigned int j = 0; j < item->usages.length (); j++)
3187 sem_usage_pair *usage = item->usages[j];
3189 if (usage->index != index)
3190 continue;
3192 bitmap *slot = split_map.get (usage->item->cls);
3193 bitmap b;
3195 if(!slot)
3197 b = BITMAP_ALLOC (&m_bmstack);
3198 split_map.put (usage->item->cls, b);
3200 else
3201 b = *slot;
3203 gcc_checking_assert (usage->item->cls);
3204 gcc_checking_assert (usage->item->index_in_class
3205 < usage->item->cls->members.length ());
3207 bitmap_set_bit (b, usage->item->index_in_class);
3211 traverse_split_pair pair;
3212 pair.optimizer = this;
3213 pair.cls = cls;
3215 splitter_class_removed = false;
3216 split_map.traverse <traverse_split_pair *,
3217 sem_item_optimizer::traverse_congruence_split> (&pair);
3219 /* Bitmap clean-up. */
3220 split_map.traverse <traverse_split_pair *,
3221 sem_item_optimizer::release_split_map> (NULL);
3224 /* Every usage of a congruence class CLS is a candidate that can split the
3225 collection of classes. Bitmap stack BMSTACK is used for bitmap
3226 allocation. */
3228 void
3229 sem_item_optimizer::do_congruence_step (congruence_class *cls)
3231 bitmap_iterator bi;
3232 unsigned int i;
3234 bitmap usage = BITMAP_ALLOC (&m_bmstack);
3236 for (unsigned int i = 0; i < cls->members.length (); i++)
3237 bitmap_ior_into (usage, cls->members[i]->usage_index_bitmap);
3239 EXECUTE_IF_SET_IN_BITMAP (usage, 0, i, bi)
3241 if (dump_file && (dump_flags & TDF_DETAILS))
3242 fprintf (dump_file, " processing congruence step for class: %u, "
3243 "index: %u\n", cls->id, i);
3245 do_congruence_step_for_index (cls, i);
3247 if (splitter_class_removed)
3248 break;
3251 BITMAP_FREE (usage);
3254 /* Adds a newly created congruence class CLS to worklist. */
3256 void
3257 sem_item_optimizer::worklist_push (congruence_class *cls)
3259 /* Return if the class CLS is already presented in work list. */
3260 if (cls->in_worklist)
3261 return;
3263 cls->in_worklist = true;
3264 worklist.push_back (cls);
3267 /* Pops a class from worklist. */
3269 congruence_class *
3270 sem_item_optimizer::worklist_pop (void)
3272 congruence_class *cls;
3274 while (!worklist.empty ())
3276 cls = worklist.front ();
3277 worklist.pop_front ();
3278 if (cls->in_worklist)
3280 cls->in_worklist = false;
3282 return cls;
3284 else
3286 /* Work list item was already intended to be removed.
3287 The only reason for doing it is to split a class.
3288 Thus, the class CLS is deleted. */
3289 delete cls;
3293 return NULL;
3296 /* Iterative congruence reduction function. */
3298 void
3299 sem_item_optimizer::process_cong_reduction (void)
3301 for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
3302 it != m_classes.end (); ++it)
3303 for (unsigned i = 0; i < (*it)->classes.length (); i++)
3304 if ((*it)->classes[i]->is_class_used ())
3305 worklist_push ((*it)->classes[i]);
3307 if (dump_file)
3308 fprintf (dump_file, "Worklist has been filled with: %lu\n",
3309 (unsigned long) worklist.size ());
3311 if (dump_file && (dump_flags & TDF_DETAILS))
3312 fprintf (dump_file, "Congruence class reduction\n");
3314 congruence_class *cls;
3316 /* Process complete congruence reduction. */
3317 while ((cls = worklist_pop ()) != NULL)
3318 do_congruence_step (cls);
3320 /* Subdivide newly created classes according to references. */
3321 unsigned new_classes = subdivide_classes_by_sensitive_refs ();
3323 if (dump_file)
3324 fprintf (dump_file, "Address reference subdivision created: %u "
3325 "new classes.\n", new_classes);
3328 /* Debug function prints all informations about congruence classes. */
3330 void
3331 sem_item_optimizer::dump_cong_classes (void)
3333 if (!dump_file)
3334 return;
3336 fprintf (dump_file,
3337 "Congruence classes: %u (unique hash values: %lu), with total: "
3338 "%u items\n", m_classes_count,
3339 (unsigned long) m_classes.elements (), m_items.length ());
3341 /* Histogram calculation. */
3342 unsigned int max_index = 0;
3343 unsigned int* histogram = XCNEWVEC (unsigned int, m_items.length () + 1);
3345 for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
3346 it != m_classes.end (); ++it)
3347 for (unsigned i = 0; i < (*it)->classes.length (); i++)
3349 unsigned int c = (*it)->classes[i]->members.length ();
3350 histogram[c]++;
3352 if (c > max_index)
3353 max_index = c;
3356 fprintf (dump_file,
3357 "Class size histogram [num of members]: number of classe number "
3358 "of classess\n");
3360 for (unsigned int i = 0; i <= max_index; i++)
3361 if (histogram[i])
3362 fprintf (dump_file, "[%u]: %u classes\n", i, histogram[i]);
3364 fprintf (dump_file, "\n\n");
3366 if (dump_flags & TDF_DETAILS)
3367 for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
3368 it != m_classes.end (); ++it)
3370 fprintf (dump_file, " group: with %u classes:\n",
3371 (*it)->classes.length ());
3373 for (unsigned i = 0; i < (*it)->classes.length (); i++)
3375 (*it)->classes[i]->dump (dump_file, 4);
3377 if (i < (*it)->classes.length () - 1)
3378 fprintf (dump_file, " ");
3382 free (histogram);
3385 /* Sort pair of sem_items A and B by DECL_UID. */
3387 static int
3388 sort_sem_items_by_decl_uid (const void *a, const void *b)
3390 const sem_item *i1 = *(const sem_item * const *)a;
3391 const sem_item *i2 = *(const sem_item * const *)b;
3393 int uid1 = DECL_UID (i1->decl);
3394 int uid2 = DECL_UID (i2->decl);
3396 if (uid1 < uid2)
3397 return -1;
3398 else if (uid1 > uid2)
3399 return 1;
3400 else
3401 return 0;
3404 /* Sort pair of congruence_classes A and B by DECL_UID of the first member. */
3406 static int
3407 sort_congruence_classes_by_decl_uid (const void *a, const void *b)
3409 const congruence_class *c1 = *(const congruence_class * const *)a;
3410 const congruence_class *c2 = *(const congruence_class * const *)b;
3412 int uid1 = DECL_UID (c1->members[0]->decl);
3413 int uid2 = DECL_UID (c2->members[0]->decl);
3415 if (uid1 < uid2)
3416 return -1;
3417 else if (uid1 > uid2)
3418 return 1;
3419 else
3420 return 0;
3423 /* Sort pair of congruence_class_groups A and B by
3424 DECL_UID of the first member of a first group. */
3426 static int
3427 sort_congruence_class_groups_by_decl_uid (const void *a, const void *b)
3429 const congruence_class_group *g1
3430 = *(const congruence_class_group * const *)a;
3431 const congruence_class_group *g2
3432 = *(const congruence_class_group * const *)b;
3434 int uid1 = DECL_UID (g1->classes[0]->members[0]->decl);
3435 int uid2 = DECL_UID (g2->classes[0]->members[0]->decl);
3437 if (uid1 < uid2)
3438 return -1;
3439 else if (uid1 > uid2)
3440 return 1;
3441 else
3442 return 0;
3445 /* After reduction is done, we can declare all items in a group
3446 to be equal. PREV_CLASS_COUNT is start number of classes
3447 before reduction. True is returned if there's a merge operation
3448 processed. */
3450 bool
3451 sem_item_optimizer::merge_classes (unsigned int prev_class_count)
3453 unsigned int item_count = m_items.length ();
3454 unsigned int class_count = m_classes_count;
3455 unsigned int equal_items = item_count - class_count;
3457 unsigned int non_singular_classes_count = 0;
3458 unsigned int non_singular_classes_sum = 0;
3460 bool merged_p = false;
3462 /* PR lto/78211
3463 Sort functions in congruence classes by DECL_UID and do the same
3464 for the classes to not to break -fcompare-debug. */
3466 for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
3467 it != m_classes.end (); ++it)
3469 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
3471 congruence_class *c = (*it)->classes[i];
3472 c->members.qsort (sort_sem_items_by_decl_uid);
3475 (*it)->classes.qsort (sort_congruence_classes_by_decl_uid);
3478 for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
3479 it != m_classes.end (); ++it)
3480 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
3482 congruence_class *c = (*it)->classes[i];
3483 if (c->members.length () > 1)
3485 non_singular_classes_count++;
3486 non_singular_classes_sum += c->members.length ();
3490 auto_vec <congruence_class_group *> classes (m_classes.elements ());
3491 for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
3492 it != m_classes.end (); ++it)
3493 classes.quick_push (*it);
3495 classes.qsort (sort_congruence_class_groups_by_decl_uid);
3497 if (dump_file)
3499 fprintf (dump_file, "\nItem count: %u\n", item_count);
3500 fprintf (dump_file, "Congruent classes before: %u, after: %u\n",
3501 prev_class_count, class_count);
3502 fprintf (dump_file, "Average class size before: %.2f, after: %.2f\n",
3503 prev_class_count ? 1.0f * item_count / prev_class_count : 0.0f,
3504 class_count ? 1.0f * item_count / class_count : 0.0f);
3505 fprintf (dump_file, "Average non-singular class size: %.2f, count: %u\n",
3506 non_singular_classes_count ? 1.0f * non_singular_classes_sum /
3507 non_singular_classes_count : 0.0f,
3508 non_singular_classes_count);
3509 fprintf (dump_file, "Equal symbols: %u\n", equal_items);
3510 fprintf (dump_file, "Fraction of visited symbols: %.2f%%\n\n",
3511 item_count ? 100.0f * equal_items / item_count : 0.0f);
3514 unsigned int l;
3515 congruence_class_group *it;
3516 FOR_EACH_VEC_ELT (classes, l, it)
3517 for (unsigned int i = 0; i < it->classes.length (); i++)
3519 congruence_class *c = it->classes[i];
3521 if (c->members.length () == 1)
3522 continue;
3524 sem_item *source = c->members[0];
3526 if (DECL_NAME (source->decl)
3527 && MAIN_NAME_P (DECL_NAME (source->decl)))
3528 /* If merge via wrappers, picking main as the target can be
3529 problematic. */
3530 source = c->members[1];
3532 for (unsigned int j = 0; j < c->members.length (); j++)
3534 sem_item *alias = c->members[j];
3536 if (alias == source)
3537 continue;
3539 if (dump_file)
3541 fprintf (dump_file, "Semantic equality hit:%s->%s\n",
3542 xstrdup_for_dump (source->node->name ()),
3543 xstrdup_for_dump (alias->node->name ()));
3544 fprintf (dump_file, "Assembler symbol names:%s->%s\n",
3545 xstrdup_for_dump (source->node->asm_name ()),
3546 xstrdup_for_dump (alias->node->asm_name ()));
3549 if (lookup_attribute ("no_icf", DECL_ATTRIBUTES (alias->decl)))
3551 if (dump_file)
3552 fprintf (dump_file,
3553 "Merge operation is skipped due to no_icf "
3554 "attribute.\n\n");
3556 continue;
3559 if (dump_file && (dump_flags & TDF_DETAILS))
3561 source->dump_to_file (dump_file);
3562 alias->dump_to_file (dump_file);
3565 if (dbg_cnt (merged_ipa_icf))
3567 bool merged = source->merge (alias);
3568 merged_p |= merged;
3570 if (merged && alias->type == VAR)
3572 symtab_pair p = symtab_pair (source->node, alias->node);
3573 m_merged_variables.safe_push (p);
3579 if (!m_merged_variables.is_empty ())
3580 fixup_points_to_sets ();
3582 return merged_p;
3585 /* Fixup points to set PT. */
3587 void
3588 sem_item_optimizer::fixup_pt_set (struct pt_solution *pt)
3590 if (pt->vars == NULL)
3591 return;
3593 unsigned i;
3594 symtab_pair *item;
3595 FOR_EACH_VEC_ELT (m_merged_variables, i, item)
3596 if (bitmap_bit_p (pt->vars, DECL_UID (item->second->decl)))
3597 bitmap_set_bit (pt->vars, DECL_UID (item->first->decl));
3600 /* Set all points-to UIDs of aliases pointing to node N as UID. */
3602 static void
3603 set_alias_uids (symtab_node *n, int uid)
3605 ipa_ref *ref;
3606 FOR_EACH_ALIAS (n, ref)
3608 if (dump_file)
3609 fprintf (dump_file, " Setting points-to UID of [%s] as %d\n",
3610 xstrdup_for_dump (ref->referring->asm_name ()), uid);
3612 SET_DECL_PT_UID (ref->referring->decl, uid);
3613 set_alias_uids (ref->referring, uid);
3617 /* Fixup points to analysis info. */
3619 void
3620 sem_item_optimizer::fixup_points_to_sets (void)
3622 /* TODO: remove in GCC 9 and trigger PTA re-creation after IPA passes. */
3623 cgraph_node *cnode;
3625 FOR_EACH_DEFINED_FUNCTION (cnode)
3627 tree name;
3628 unsigned i;
3629 function *fn = DECL_STRUCT_FUNCTION (cnode->decl);
3630 if (!gimple_in_ssa_p (fn))
3631 continue;
3633 FOR_EACH_SSA_NAME (i, name, fn)
3634 if (POINTER_TYPE_P (TREE_TYPE (name))
3635 && SSA_NAME_PTR_INFO (name))
3636 fixup_pt_set (&SSA_NAME_PTR_INFO (name)->pt);
3637 fixup_pt_set (&fn->gimple_df->escaped);
3639 /* The above get's us to 99% I guess, at least catching the
3640 address compares. Below also gets us aliasing correct
3641 but as said we're giving leeway to the situation with
3642 readonly vars anyway, so ... */
3643 basic_block bb;
3644 FOR_EACH_BB_FN (bb, fn)
3645 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
3646 gsi_next (&gsi))
3648 gcall *call = dyn_cast<gcall *> (gsi_stmt (gsi));
3649 if (call)
3651 fixup_pt_set (gimple_call_use_set (call));
3652 fixup_pt_set (gimple_call_clobber_set (call));
3657 unsigned i;
3658 symtab_pair *item;
3659 FOR_EACH_VEC_ELT (m_merged_variables, i, item)
3660 set_alias_uids (item->first, DECL_UID (item->first->decl));
3663 /* Dump function prints all class members to a FILE with an INDENT. */
3665 void
3666 congruence_class::dump (FILE *file, unsigned int indent) const
3668 FPRINTF_SPACES (file, indent, "class with id: %u, hash: %u, items: %u\n",
3669 id, members[0]->get_hash (), members.length ());
3671 FPUTS_SPACES (file, indent + 2, "");
3672 for (unsigned i = 0; i < members.length (); i++)
3673 fprintf (file, "%s ", members[i]->node->dump_asm_name ());
3675 fprintf (file, "\n");
3678 /* Returns true if there's a member that is used from another group. */
3680 bool
3681 congruence_class::is_class_used (void)
3683 for (unsigned int i = 0; i < members.length (); i++)
3684 if (members[i]->usages.length ())
3685 return true;
3687 return false;
3690 /* Generate pass summary for IPA ICF pass. */
3692 static void
3693 ipa_icf_generate_summary (void)
3695 if (!optimizer)
3696 optimizer = new sem_item_optimizer ();
3698 optimizer->register_hooks ();
3699 optimizer->parse_funcs_and_vars ();
3702 /* Write pass summary for IPA ICF pass. */
3704 static void
3705 ipa_icf_write_summary (void)
3707 gcc_assert (optimizer);
3709 optimizer->write_summary ();
3712 /* Read pass summary for IPA ICF pass. */
3714 static void
3715 ipa_icf_read_summary (void)
3717 if (!optimizer)
3718 optimizer = new sem_item_optimizer ();
3720 optimizer->read_summary ();
3721 optimizer->register_hooks ();
3724 /* Semantic equality exection function. */
3726 static unsigned int
3727 ipa_icf_driver (void)
3729 gcc_assert (optimizer);
3731 bool merged_p = optimizer->execute ();
3733 delete optimizer;
3734 optimizer = NULL;
3736 return merged_p ? TODO_remove_functions : 0;
3739 const pass_data pass_data_ipa_icf =
3741 IPA_PASS, /* type */
3742 "icf", /* name */
3743 OPTGROUP_IPA, /* optinfo_flags */
3744 TV_IPA_ICF, /* tv_id */
3745 0, /* properties_required */
3746 0, /* properties_provided */
3747 0, /* properties_destroyed */
3748 0, /* todo_flags_start */
3749 0, /* todo_flags_finish */
3752 class pass_ipa_icf : public ipa_opt_pass_d
3754 public:
3755 pass_ipa_icf (gcc::context *ctxt)
3756 : ipa_opt_pass_d (pass_data_ipa_icf, ctxt,
3757 ipa_icf_generate_summary, /* generate_summary */
3758 ipa_icf_write_summary, /* write_summary */
3759 ipa_icf_read_summary, /* read_summary */
3760 NULL, /*
3761 write_optimization_summary */
3762 NULL, /*
3763 read_optimization_summary */
3764 NULL, /* stmt_fixup */
3765 0, /* function_transform_todo_flags_start */
3766 NULL, /* function_transform */
3767 NULL) /* variable_transform */
3770 /* opt_pass methods: */
3771 virtual bool gate (function *)
3773 return in_lto_p || flag_ipa_icf_variables || flag_ipa_icf_functions;
3776 virtual unsigned int execute (function *)
3778 return ipa_icf_driver();
3780 }; // class pass_ipa_icf
3782 } // ipa_icf namespace
3784 ipa_opt_pass_d *
3785 make_pass_ipa_icf (gcc::context *ctxt)
3787 return new ipa_icf::pass_ipa_icf (ctxt);