]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/ipa-icf.c
c++: Handle multiple aggregate overloads [PR95319].
[thirdparty/gcc.git] / gcc / ipa-icf.c
CommitLineData
b84d4347 1/* Interprocedural Identical Code Folding pass
8d9254fc 2 Copyright (C) 2014-2020 Free Software Foundation, Inc.
b84d4347
ML
3
4 Contributed by Jan Hubicka <hubicka@ucw.cz> and Martin Liska <mliska@suse.cz>
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 3, or (at your option) any later
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
19along with GCC; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. */
21
22/* Interprocedural Identical Code Folding for functions and
23 read-only variables.
24
25 The goal of this transformation is to discover functions and read-only
26 variables which do have exactly the same semantics.
27
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.
33
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.
51
52*/
53
54#include "config.h"
55#include "system.h"
56#include "coretypes.h"
c7131fb2 57#include "backend.h"
957060b5
AM
58#include "target.h"
59#include "rtl.h"
40e23961 60#include "tree.h"
b84d4347 61#include "gimple.h"
957060b5
AM
62#include "alloc-pool.h"
63#include "tree-pass.h"
c7131fb2 64#include "ssa.h"
957060b5
AM
65#include "cgraph.h"
66#include "coverage.h"
67#include "gimple-pretty-print.h"
68#include "data-streamer.h"
c7131fb2 69#include "fold-const.h"
36566b39 70#include "calls.h"
36566b39 71#include "varasm.h"
b84d4347 72#include "gimple-iterator.h"
b84d4347 73#include "tree-cfg.h"
dd912cb8 74#include "symbol-summary.h"
c582198b 75#include "ipa-prop.h"
27d020cf 76#include "ipa-fnsummary.h"
b84d4347 77#include "except.h"
b84d4347
ML
78#include "attribs.h"
79#include "print-tree.h"
b84d4347 80#include "ipa-utils.h"
b84d4347 81#include "ipa-icf-gimple.h"
c3af5442 82#include "fibonacci_heap.h"
b84d4347 83#include "ipa-icf.h"
46305737 84#include "stor-layout.h"
7aeb92b4 85#include "dbgcnt.h"
63570af0 86#include "tree-vector-builder.h"
b84d4347
ML
87
88using namespace ipa_icf_gimple;
89
90namespace ipa_icf {
5ebd0e61 91
69f6b1f4
JH
92/* Initialization and computation of symtab node hash, there data
93 are propagated later on. */
94
95static sem_item_optimizer *optimizer = NULL;
96
5ebd0e61
ML
97/* Constructor. */
98
99symbol_compare_collection::symbol_compare_collection (symtab_node *node)
100{
101 m_references.create (0);
102 m_interposables.create (0);
103
104 ipa_ref *ref;
105
106 if (is_a <varpool_node *> (node) && DECL_VIRTUAL_P (node->decl))
107 return;
108
977b01e3 109 for (unsigned i = 0; node->iterate_reference (i, ref); i++)
5ebd0e61 110 {
5ebd0e61
ML
111 if (ref->address_matters_p ())
112 m_references.safe_push (ref->referred);
113
114 if (ref->referred->get_availability () <= AVAIL_INTERPOSABLE)
115 {
0a7246ee 116 if (ref->address_matters_p ())
5ebd0e61
ML
117 m_references.safe_push (ref->referred);
118 else
119 m_interposables.safe_push (ref->referred);
120 }
121 }
122
123 if (is_a <cgraph_node *> (node))
124 {
125 cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
126
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);
130 }
131}
132
b84d4347
ML
133/* Constructor for key value pair, where _ITEM is key and _INDEX is a target. */
134
fedf2718
ML
135sem_usage_pair::sem_usage_pair (sem_item *_item, unsigned int _index)
136: item (_item), index (_index)
b84d4347
ML
137{
138}
139
fedf2718 140sem_item::sem_item (sem_item_type _type, bitmap_obstack *stack)
a9fae4b4 141: type (_type), referenced_by_count (0), m_hash (-1), m_hash_set (false)
b84d4347
ML
142{
143 setup (stack);
144}
145
b84d4347 146sem_item::sem_item (sem_item_type _type, symtab_node *_node,
fedf2718 147 bitmap_obstack *stack)
a9fae4b4
ML
148: type (_type), node (_node), referenced_by_count (0), m_hash (-1),
149 m_hash_set (false)
b84d4347
ML
150{
151 decl = node->decl;
152 setup (stack);
153}
154
155/* Add reference to a semantic TARGET. */
156
157void
a9fae4b4
ML
158sem_item::add_reference (ref_map *refs,
159 sem_item *target)
b84d4347 160{
a9fae4b4
ML
161 unsigned index = reference_count++;
162 bool existed;
163
164 vec<sem_item *> &v
165 = refs->get_or_insert (new sem_usage_pair (target, index), &existed);
166 v.safe_push (this);
b84d4347
ML
167 bitmap_set_bit (target->usage_index_bitmap, index);
168 refs_set.add (target->node);
a9fae4b4 169 ++target->referenced_by_count;
b84d4347
ML
170}
171
172/* Initialize internal data structures. Bitmap STACK is used for
173 bitmap memory allocation process. */
174
175void
176sem_item::setup (bitmap_obstack *stack)
177{
178 gcc_checking_assert (node);
179
a9fae4b4 180 reference_count = 0;
b84d4347 181 tree_refs.create (0);
b84d4347
ML
182 usage_index_bitmap = BITMAP_ALLOC (stack);
183}
184
185sem_item::~sem_item ()
186{
b84d4347 187 tree_refs.release ();
b84d4347
ML
188
189 BITMAP_FREE (usage_index_bitmap);
190}
191
192/* Dump function for debugging purpose. */
193
194DEBUG_FUNCTION void
195sem_item::dump (void)
196{
197 if (dump_file)
198 {
464d0118
ML
199 fprintf (dump_file, "[%s] %s (tree:%p)\n", type == FUNC ? "func" : "var",
200 node->dump_name (), (void *) node->decl);
b84d4347 201 fprintf (dump_file, " hash: %u\n", get_hash ());
b84d4347
ML
202 }
203}
204
f657d665
ML
205/* Return true if target supports alias symbols. */
206
207bool
208sem_item::target_supports_symbol_aliases_p (void)
209{
210#if !defined (ASM_OUTPUT_DEF) || (!defined(ASM_OUTPUT_WEAK_ALIAS) && !defined (ASM_WEAKEN_DECL))
211 return false;
212#else
213 return true;
214#endif
215}
216
808b6bb7
ML
217void sem_item::set_hash (hashval_t hash)
218{
219 m_hash = hash;
fedf2718 220 m_hash_set = true;
808b6bb7
ML
221}
222
6c72e55d
ML
223hash_map<const_tree, hashval_t> sem_item::m_type_hash_cache;
224
b84d4347
ML
225/* Semantic function constructor that uses STACK as bitmap memory stack. */
226
fedf2718
ML
227sem_function::sem_function (bitmap_obstack *stack)
228: sem_item (FUNC, stack), m_checker (NULL), m_compared_func (NULL)
b84d4347 229{
b84d4347
ML
230 bb_sizes.create (0);
231 bb_sorted.create (0);
232}
233
fedf2718
ML
234sem_function::sem_function (cgraph_node *node, bitmap_obstack *stack)
235: sem_item (FUNC, node, stack), m_checker (NULL), m_compared_func (NULL)
b84d4347 236{
b84d4347
ML
237 bb_sizes.create (0);
238 bb_sorted.create (0);
239}
240
241sem_function::~sem_function ()
242{
243 for (unsigned i = 0; i < bb_sorted.length (); i++)
e27d328a 244 delete (bb_sorted[i]);
b84d4347 245
b84d4347
ML
246 bb_sizes.release ();
247 bb_sorted.release ();
248}
249
250/* Calculates hash value based on a BASIC_BLOCK. */
251
252hashval_t
253sem_function::get_bb_hash (const sem_bb *basic_block)
254{
255 inchash::hash hstate;
256
257 hstate.add_int (basic_block->nondbg_stmt_count);
258 hstate.add_int (basic_block->edge_count);
259
260 return hstate.end ();
261}
262
263/* References independent hash function. */
264
265hashval_t
266sem_function::get_hash (void)
267{
fedf2718 268 if (!m_hash_set)
b84d4347
ML
269 {
270 inchash::hash hstate;
271 hstate.add_int (177454); /* Random number for function type. */
272
273 hstate.add_int (arg_count);
274 hstate.add_int (cfg_checksum);
275 hstate.add_int (gcode_hash);
276
277 for (unsigned i = 0; i < bb_sorted.length (); i++)
278 hstate.merge_hash (get_bb_hash (bb_sorted[i]));
279
280 for (unsigned i = 0; i < bb_sizes.length (); i++)
281 hstate.add_int (bb_sizes[i]);
282
69f6b1f4
JH
283 /* Add common features of declaration itself. */
284 if (DECL_FUNCTION_SPECIFIC_TARGET (decl))
449e9a33 285 hstate.add_hwi
69f6b1f4
JH
286 (cl_target_option_hash
287 (TREE_TARGET_OPTION (DECL_FUNCTION_SPECIFIC_TARGET (decl))));
288 if (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl))
449e9a33 289 hstate.add_hwi
69f6b1f4
JH
290 (cl_optimization_hash
291 (TREE_OPTIMIZATION (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl))));
69f6b1f4
JH
292 hstate.add_flag (DECL_CXX_CONSTRUCTOR_P (decl));
293 hstate.add_flag (DECL_CXX_DESTRUCTOR_P (decl));
294
808b6bb7 295 set_hash (hstate.end ());
b84d4347
ML
296 }
297
808b6bb7 298 return m_hash;
b84d4347
ML
299}
300
977b01e3
JH
301/* Compare properties of symbols N1 and N2 that does not affect semantics of
302 symbol itself but affects semantics of its references from USED_BY (which
956d615d 303 may be NULL if it is unknown). If comparison is false, symbols
977b01e3
JH
304 can still be merged but any symbols referring them can't.
305
306 If ADDRESS is true, do extra checking needed for IPA_REF_ADDR.
307
308 TODO: We can also split attributes to those that determine codegen of
309 a function body/variable constructor itself and those that are used when
310 referring to it. */
311
312bool
313sem_item::compare_referenced_symbol_properties (symtab_node *used_by,
314 symtab_node *n1,
315 symtab_node *n2,
316 bool address)
317{
318 if (is_a <cgraph_node *> (n1))
319 {
320 /* Inline properties matters: we do now want to merge uses of inline
321 function to uses of normal function because inline hint would be lost.
322 We however can merge inline function to noinline because the alias
323 will keep its DECL_DECLARED_INLINE flag.
324
325 Also ignore inline flag when optimizing for size or when function
326 is known to not be inlinable.
327
328 TODO: the optimize_size checks can also be assumed to be true if
329 unit has no !optimize_size functions. */
330
331 if ((!used_by || address || !is_a <cgraph_node *> (used_by)
332 || !opt_for_fn (used_by->decl, optimize_size))
333 && !opt_for_fn (n1->decl, optimize_size)
334 && n1->get_availability () > AVAIL_INTERPOSABLE
335 && (!DECL_UNINLINABLE (n1->decl) || !DECL_UNINLINABLE (n2->decl)))
336 {
337 if (DECL_DISREGARD_INLINE_LIMITS (n1->decl)
338 != DECL_DISREGARD_INLINE_LIMITS (n2->decl))
339 return return_false_with_msg
340 ("DECL_DISREGARD_INLINE_LIMITS are different");
341
342 if (DECL_DECLARED_INLINE_P (n1->decl)
343 != DECL_DECLARED_INLINE_P (n2->decl))
344 return return_false_with_msg ("inline attributes are different");
345 }
346
cb50701e
ML
347 if (DECL_IS_OPERATOR_NEW_P (n1->decl)
348 != DECL_IS_OPERATOR_NEW_P (n2->decl))
977b01e3 349 return return_false_with_msg ("operator new flags are different");
70df40ca
ML
350
351 if (DECL_IS_REPLACEABLE_OPERATOR (n1->decl)
352 != DECL_IS_REPLACEABLE_OPERATOR (n2->decl))
353 return return_false_with_msg ("replaceable operator flags are different");
977b01e3
JH
354 }
355
356 /* Merging two definitions with a reference to equivalent vtables, but
357 belonging to a different type may result in ipa-polymorphic-call analysis
358 giving a wrong answer about the dynamic type of instance. */
359 if (is_a <varpool_node *> (n1))
360 {
361 if ((DECL_VIRTUAL_P (n1->decl) || DECL_VIRTUAL_P (n2->decl))
362 && (DECL_VIRTUAL_P (n1->decl) != DECL_VIRTUAL_P (n2->decl)
363 || !types_must_be_same_for_odr (DECL_CONTEXT (n1->decl),
364 DECL_CONTEXT (n2->decl)))
365 && (!used_by || !is_a <cgraph_node *> (used_by) || address
366 || opt_for_fn (used_by->decl, flag_devirtualize)))
367 return return_false_with_msg
67914693 368 ("references to virtual tables cannot be merged");
b3587b99
JH
369
370 if (address && DECL_ALIGN (n1->decl) != DECL_ALIGN (n2->decl))
371 return return_false_with_msg ("alignment mismatch");
372
373 /* For functions we compare attributes in equals_wpa, because we do
374 not know what attributes may cause codegen differences, but for
375 variables just compare attributes for references - the codegen
376 for constructors is affected only by those attributes that we lower
377 to explicit representation (such as DECL_ALIGN or DECL_SECTION). */
14762cd0
ML
378 if (!attribute_list_equal (DECL_ATTRIBUTES (n1->decl),
379 DECL_ATTRIBUTES (n2->decl)))
b3587b99
JH
380 return return_false_with_msg ("different var decl attributes");
381 if (comp_type_attributes (TREE_TYPE (n1->decl),
382 TREE_TYPE (n2->decl)) != 1)
383 return return_false_with_msg ("different var type attributes");
977b01e3
JH
384 }
385
386 /* When matching virtual tables, be sure to also match information
387 relevant for polymorphic call analysis. */
388 if (used_by && is_a <varpool_node *> (used_by)
389 && DECL_VIRTUAL_P (used_by->decl))
390 {
391 if (DECL_VIRTUAL_P (n1->decl) != DECL_VIRTUAL_P (n2->decl))
392 return return_false_with_msg ("virtual flag mismatch");
393 if (DECL_VIRTUAL_P (n1->decl) && is_a <cgraph_node *> (n1)
394 && (DECL_FINAL_P (n1->decl) != DECL_FINAL_P (n2->decl)))
395 return return_false_with_msg ("final flag mismatch");
396 }
397 return true;
398}
399
400/* Hash properties that are compared by compare_referenced_symbol_properties. */
401
402void
403sem_item::hash_referenced_symbol_properties (symtab_node *ref,
404 inchash::hash &hstate,
405 bool address)
406{
407 if (is_a <cgraph_node *> (ref))
408 {
d57c9945 409 if ((type != FUNC || address || !opt_for_fn (decl, optimize_size))
977b01e3
JH
410 && !opt_for_fn (ref->decl, optimize_size)
411 && !DECL_UNINLINABLE (ref->decl))
412 {
413 hstate.add_flag (DECL_DISREGARD_INLINE_LIMITS (ref->decl));
414 hstate.add_flag (DECL_DECLARED_INLINE_P (ref->decl));
415 }
cb50701e 416 hstate.add_flag (DECL_IS_OPERATOR_NEW_P (ref->decl));
977b01e3
JH
417 }
418 else if (is_a <varpool_node *> (ref))
419 {
420 hstate.add_flag (DECL_VIRTUAL_P (ref->decl));
b3587b99
JH
421 if (address)
422 hstate.add_int (DECL_ALIGN (ref->decl));
977b01e3
JH
423 }
424}
425
426
b84d4347
ML
427/* For a given symbol table nodes N1 and N2, we check that FUNCTION_DECLs
428 point to a same function. Comparison can be skipped if IGNORED_NODES
b6cddc7f 429 contains these nodes. ADDRESS indicate if address is taken. */
b84d4347
ML
430
431bool
977b01e3 432sem_item::compare_symbol_references (
b6cddc7f
ML
433 hash_map <symtab_node *, sem_item *> &ignored_nodes,
434 symtab_node *n1, symtab_node *n2, bool address)
b84d4347 435{
b6cddc7f
ML
436 enum availability avail1, avail2;
437
fe75bd20
JH
438 if (n1 == n2)
439 return true;
440
523f0450
JH
441 /* Never match variable and function. */
442 if (is_a <varpool_node *> (n1) != is_a <varpool_node *> (n2))
443 return false;
444
977b01e3
JH
445 if (!compare_referenced_symbol_properties (node, n1, n2, address))
446 return false;
b6cddc7f
ML
447 if (address && n1->equal_address_to (n2) == 1)
448 return true;
449 if (!address && n1->semantically_equivalent_p (n2))
b84d4347
ML
450 return true;
451
b6cddc7f
ML
452 n1 = n1->ultimate_alias_target (&avail1);
453 n2 = n2->ultimate_alias_target (&avail2);
454
d7e2ff72
JH
455 if (avail1 > AVAIL_INTERPOSABLE && ignored_nodes.get (n1)
456 && avail2 > AVAIL_INTERPOSABLE && ignored_nodes.get (n2))
b6cddc7f 457 return true;
b84d4347
ML
458
459 return return_false_with_msg ("different references");
460}
461
462/* If cgraph edges E1 and E2 are indirect calls, verify that
463 ECF flags are the same. */
464
465bool sem_function::compare_edge_flags (cgraph_edge *e1, cgraph_edge *e2)
466{
467 if (e1->indirect_info && e2->indirect_info)
468 {
469 int e1_flags = e1->indirect_info->ecf_flags;
470 int e2_flags = e2->indirect_info->ecf_flags;
471
472 if (e1_flags != e2_flags)
473 return return_false_with_msg ("ICF flags are different");
474 }
475 else if (e1->indirect_info || e2->indirect_info)
476 return false;
477
478 return true;
479}
480
b3587b99
JH
481/* Return true if parameter I may be used. */
482
483bool
484sem_function::param_used_p (unsigned int i)
485{
486 if (ipa_node_params_sum == NULL)
b0187578 487 return true;
b3587b99 488
99b1c316 489 class ipa_node_params *parms_info = IPA_NODE_REF (get_node ());
b3587b99 490
6cf67b62 491 if (!parms_info || vec_safe_length (parms_info->descriptors) <= i)
f65f1ae3 492 return true;
b3587b99
JH
493
494 return ipa_is_param_used (IPA_NODE_REF (get_node ()), i);
495}
496
1628e36b
JH
497/* Perform additional check needed to match types function parameters that are
498 used. Unlike for normal decls it matters if type is TYPE_RESTRICT and we
499 make an assumption that REFERENCE_TYPE parameters are always non-NULL. */
500
501bool
502sem_function::compatible_parm_types_p (tree parm1, tree parm2)
503{
504 /* Be sure that parameters are TBAA compatible. */
505 if (!func_checker::compatible_types_p (parm1, parm2))
506 return return_false_with_msg ("parameter type is not compatible");
507
508 if (POINTER_TYPE_P (parm1)
509 && (TYPE_RESTRICT (parm1) != TYPE_RESTRICT (parm2)))
510 return return_false_with_msg ("argument restrict flag mismatch");
511
512 /* nonnull_arg_p implies non-zero range to REFERENCE types. */
513 if (POINTER_TYPE_P (parm1)
514 && TREE_CODE (parm1) != TREE_CODE (parm2)
515 && opt_for_fn (decl, flag_delete_null_pointer_checks))
516 return return_false_with_msg ("pointer wrt reference mismatch");
517
518 return true;
519}
520
b84d4347
ML
521/* Fast equality function based on knowledge known in WPA. */
522
523bool
524sem_function::equals_wpa (sem_item *item,
525 hash_map <symtab_node *, sem_item *> &ignored_nodes)
526{
527 gcc_assert (item->type == FUNC);
fb5c322e
JH
528 cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
529 cgraph_node *cnode2 = dyn_cast <cgraph_node *> (item->node);
b84d4347
ML
530
531 m_compared_func = static_cast<sem_function *> (item);
532
fb5c322e
JH
533 if (cnode->thunk.thunk_p != cnode2->thunk.thunk_p)
534 return return_false_with_msg ("thunk_p mismatch");
535
536 if (cnode->thunk.thunk_p)
537 {
538 if (cnode->thunk.fixed_offset != cnode2->thunk.fixed_offset)
539 return return_false_with_msg ("thunk fixed_offset mismatch");
540 if (cnode->thunk.virtual_value != cnode2->thunk.virtual_value)
541 return return_false_with_msg ("thunk virtual_value mismatch");
44662f68
EB
542 if (cnode->thunk.indirect_offset != cnode2->thunk.indirect_offset)
543 return return_false_with_msg ("thunk indirect_offset mismatch");
fb5c322e
JH
544 if (cnode->thunk.this_adjusting != cnode2->thunk.this_adjusting)
545 return return_false_with_msg ("thunk this_adjusting mismatch");
546 if (cnode->thunk.virtual_offset_p != cnode2->thunk.virtual_offset_p)
547 return return_false_with_msg ("thunk virtual_offset_p mismatch");
fb5c322e
JH
548 }
549
c4234544
JH
550 /* Compare special function DECL attributes. */
551 if (DECL_FUNCTION_PERSONALITY (decl)
552 != DECL_FUNCTION_PERSONALITY (item->decl))
553 return return_false_with_msg ("function personalities are different");
554
c4234544
JH
555 if (DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl)
556 != DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (item->decl))
956d615d 557 return return_false_with_msg ("instrument function entry exit "
c4234544
JH
558 "attributes are different");
559
560 if (DECL_NO_LIMIT_STACK (decl) != DECL_NO_LIMIT_STACK (item->decl))
561 return return_false_with_msg ("no stack limit attributes are different");
562
060cfff4 563 if (DECL_CXX_CONSTRUCTOR_P (decl) != DECL_CXX_CONSTRUCTOR_P (item->decl))
69f6b1f4 564 return return_false_with_msg ("DECL_CXX_CONSTRUCTOR mismatch");
060cfff4
JH
565
566 if (DECL_CXX_DESTRUCTOR_P (decl) != DECL_CXX_DESTRUCTOR_P (item->decl))
69f6b1f4 567 return return_false_with_msg ("DECL_CXX_DESTRUCTOR mismatch");
060cfff4 568
b3587b99
JH
569 /* TODO: pure/const flags mostly matters only for references, except for
570 the fact that codegen takes LOOPING flag as a hint that loops are
571 finite. We may arrange the code to always pick leader that has least
572 specified flags and then this can go into comparing symbol properties. */
c4234544
JH
573 if (flags_from_decl_or_type (decl) != flags_from_decl_or_type (item->decl))
574 return return_false_with_msg ("decl_or_type flags are different");
575
060cfff4
JH
576 /* Do not match polymorphic constructors of different types. They calls
577 type memory location for ipa-polymorphic-call and we do not want
578 it to get confused by wrong type. */
579 if (DECL_CXX_CONSTRUCTOR_P (decl)
580 && TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
581 {
582 if (TREE_CODE (TREE_TYPE (item->decl)) != METHOD_TYPE)
956d615d 583 return return_false_with_msg ("DECL_CXX_CONSTRUCTOR type mismatch");
060cfff4 584 else if (!func_checker::compatible_polymorphic_types_p
70e7f2a2
JH
585 (TYPE_METHOD_BASETYPE (TREE_TYPE (decl)),
586 TYPE_METHOD_BASETYPE (TREE_TYPE (item->decl)), false))
060cfff4
JH
587 return return_false_with_msg ("ctor polymorphic type mismatch");
588 }
589
c4234544
JH
590 /* Checking function TARGET and OPTIMIZATION flags. */
591 cl_target_option *tar1 = target_opts_for_fn (decl);
592 cl_target_option *tar2 = target_opts_for_fn (item->decl);
593
594 if (tar1 != tar2 && !cl_target_option_eq (tar1, tar2))
595 {
596 if (dump_file && (dump_flags & TDF_DETAILS))
597 {
598 fprintf (dump_file, "target flags difference");
599 cl_target_option_print_diff (dump_file, 2, tar1, tar2);
600 }
601
602 return return_false_with_msg ("Target flags are different");
603 }
604
605 cl_optimization *opt1 = opts_for_fn (decl);
606 cl_optimization *opt2 = opts_for_fn (item->decl);
607
c518c102 608 if (opt1 != opt2 && !cl_optimization_option_eq (opt1, opt2))
c4234544
JH
609 {
610 if (dump_file && (dump_flags & TDF_DETAILS))
611 {
612 fprintf (dump_file, "optimization flags difference");
613 cl_optimization_print_diff (dump_file, 2, opt1, opt2);
614 }
615
616 return return_false_with_msg ("optimization flags are different");
617 }
618
619 /* Result type checking. */
1628e36b
JH
620 if (!func_checker::compatible_types_p
621 (TREE_TYPE (TREE_TYPE (decl)),
622 TREE_TYPE (TREE_TYPE (m_compared_func->decl))))
c4234544
JH
623 return return_false_with_msg ("result types are different");
624
b84d4347 625 /* Checking types of arguments. */
1628e36b
JH
626 tree list1 = TYPE_ARG_TYPES (TREE_TYPE (decl)),
627 list2 = TYPE_ARG_TYPES (TREE_TYPE (m_compared_func->decl));
628 for (unsigned i = 0; list1 && list2;
629 list1 = TREE_CHAIN (list1), list2 = TREE_CHAIN (list2), i++)
b84d4347 630 {
1628e36b
JH
631 tree parm1 = TREE_VALUE (list1);
632 tree parm2 = TREE_VALUE (list2);
633
b84d4347 634 /* This guard is here for function pointer with attributes (pr59927.c). */
1628e36b 635 if (!parm1 || !parm2)
b84d4347
ML
636 return return_false_with_msg ("NULL argument type");
637
1628e36b
JH
638 /* Verify that types are compatible to ensure that both functions
639 have same calling conventions. */
640 if (!types_compatible_p (parm1, parm2))
641 return return_false_with_msg ("parameter types are not compatible");
b3587b99 642
b3587b99
JH
643 if (!param_used_p (i))
644 continue;
1628e36b
JH
645
646 /* Perform additional checks for used parameters. */
647 if (!compatible_parm_types_p (parm1, parm2))
648 return false;
b84d4347
ML
649 }
650
1628e36b
JH
651 if (list1 || list2)
652 return return_false_with_msg ("Mismatched number of parameters");
653
b84d4347
ML
654 if (node->num_references () != item->node->num_references ())
655 return return_false_with_msg ("different number of references");
656
b3587b99
JH
657 /* Checking function attributes.
658 This is quadratic in number of attributes */
fe75bd20
JH
659 if (comp_type_attributes (TREE_TYPE (decl),
660 TREE_TYPE (item->decl)) != 1)
661 return return_false_with_msg ("different type attributes");
14762cd0
ML
662 if (!attribute_list_equal (DECL_ATTRIBUTES (decl),
663 DECL_ATTRIBUTES (item->decl)))
b3587b99 664 return return_false_with_msg ("different decl attributes");
fe75bd20 665
060cfff4
JH
666 /* The type of THIS pointer type memory location for
667 ipa-polymorphic-call-analysis. */
668 if (opt_for_fn (decl, flag_devirtualize)
669 && (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
670 || TREE_CODE (TREE_TYPE (item->decl)) == METHOD_TYPE)
b3587b99 671 && param_used_p (0)
060cfff4
JH
672 && compare_polymorphic_p ())
673 {
674 if (TREE_CODE (TREE_TYPE (decl)) != TREE_CODE (TREE_TYPE (item->decl)))
675 return return_false_with_msg ("METHOD_TYPE and FUNCTION_TYPE mismatch");
676 if (!func_checker::compatible_polymorphic_types_p
70e7f2a2
JH
677 (TYPE_METHOD_BASETYPE (TREE_TYPE (decl)),
678 TYPE_METHOD_BASETYPE (TREE_TYPE (item->decl)), false))
060cfff4
JH
679 return return_false_with_msg ("THIS pointer ODR type mismatch");
680 }
681
b84d4347
ML
682 ipa_ref *ref = NULL, *ref2 = NULL;
683 for (unsigned i = 0; node->iterate_reference (i, ref); i++)
684 {
685 item->node->iterate_reference (i, ref2);
686
b3587b99
JH
687 if (ref->use != ref2->use)
688 return return_false_with_msg ("reference use mismatch");
689
977b01e3 690 if (!compare_symbol_references (ignored_nodes, ref->referred,
b6cddc7f
ML
691 ref2->referred,
692 ref->address_matters_p ()))
b84d4347
ML
693 return false;
694 }
695
696 cgraph_edge *e1 = dyn_cast <cgraph_node *> (node)->callees;
697 cgraph_edge *e2 = dyn_cast <cgraph_node *> (item->node)->callees;
698
699 while (e1 && e2)
700 {
977b01e3 701 if (!compare_symbol_references (ignored_nodes, e1->callee,
b6cddc7f 702 e2->callee, false))
b84d4347 703 return false;
b3587b99
JH
704 if (!compare_edge_flags (e1, e2))
705 return false;
b84d4347
ML
706
707 e1 = e1->next_callee;
708 e2 = e2->next_callee;
709 }
710
711 if (e1 || e2)
b3587b99
JH
712 return return_false_with_msg ("different number of calls");
713
714 e1 = dyn_cast <cgraph_node *> (node)->indirect_calls;
715 e2 = dyn_cast <cgraph_node *> (item->node)->indirect_calls;
716
717 while (e1 && e2)
718 {
719 if (!compare_edge_flags (e1, e2))
720 return false;
721
722 e1 = e1->next_callee;
723 e2 = e2->next_callee;
724 }
725
726 if (e1 || e2)
727 return return_false_with_msg ("different number of indirect calls");
b84d4347
ML
728
729 return true;
730}
731
3ab93359 732/* Update hash by address sensitive references. We iterate over all
956d615d 733 sensitive references (address_matters_p) and we hash ultimate alias
3ab93359 734 target of these nodes, which can improve a semantic item hash.
977b01e3
JH
735
736 Also hash in referenced symbols properties. This can be done at any time
737 (as the properties should not change), but it is convenient to do it here
738 while we walk the references anyway. */
3ab93359
ML
739
740void
741sem_item::update_hash_by_addr_refs (hash_map <symtab_node *,
742 sem_item *> &m_symtab_node_map)
743{
3ab93359 744 ipa_ref* ref;
808b6bb7 745 inchash::hash hstate (get_hash ());
977b01e3
JH
746
747 for (unsigned i = 0; node->iterate_reference (i, ref); i++)
3ab93359 748 {
b3587b99 749 hstate.add_int (ref->use);
977b01e3
JH
750 hash_referenced_symbol_properties (ref->referred, hstate,
751 ref->use == IPA_REF_ADDR);
3ab93359 752 if (ref->address_matters_p () || !m_symtab_node_map.get (ref->referred))
f45be077 753 hstate.add_int (ref->referred->ultimate_alias_target ()->order);
3ab93359
ML
754 }
755
756 if (is_a <cgraph_node *> (node))
757 {
758 for (cgraph_edge *e = dyn_cast <cgraph_node *> (node)->callers; e;
759 e = e->next_caller)
760 {
761 sem_item **result = m_symtab_node_map.get (e->callee);
977b01e3 762 hash_referenced_symbol_properties (e->callee, hstate, false);
3ab93359 763 if (!result)
f45be077 764 hstate.add_int (e->callee->ultimate_alias_target ()->order);
3ab93359
ML
765 }
766 }
767
808b6bb7 768 set_hash (hstate.end ());
3ab93359
ML
769}
770
771/* Update hash by computed local hash values taken from different
977b01e3
JH
772 semantic items.
773 TODO: stronger SCC based hashing would be desirable here. */
3ab93359
ML
774
775void
776sem_item::update_hash_by_local_refs (hash_map <symtab_node *,
777 sem_item *> &m_symtab_node_map)
778{
977b01e3 779 ipa_ref* ref;
808b6bb7 780 inchash::hash state (get_hash ());
977b01e3
JH
781
782 for (unsigned j = 0; node->iterate_reference (j, ref); j++)
3ab93359 783 {
3ab93359
ML
784 sem_item **result = m_symtab_node_map.get (ref->referring);
785 if (result)
808b6bb7 786 state.merge_hash ((*result)->get_hash ());
3ab93359
ML
787 }
788
789 if (type == FUNC)
790 {
791 for (cgraph_edge *e = dyn_cast <cgraph_node *> (node)->callees; e;
792 e = e->next_callee)
793 {
794 sem_item **result = m_symtab_node_map.get (e->caller);
795 if (result)
808b6bb7 796 state.merge_hash ((*result)->get_hash ());
3ab93359
ML
797 }
798 }
799
800 global_hash = state.end ();
801}
802
b84d4347
ML
803/* Returns true if the item equals to ITEM given as argument. */
804
805bool
806sem_function::equals (sem_item *item,
fb5c322e 807 hash_map <symtab_node *, sem_item *> &)
b84d4347
ML
808{
809 gcc_assert (item->type == FUNC);
fb5c322e 810 bool eq = equals_private (item);
b84d4347
ML
811
812 if (m_checker != NULL)
813 {
814 delete m_checker;
815 m_checker = NULL;
816 }
817
818 if (dump_file && (dump_flags & TDF_DETAILS))
819 fprintf (dump_file,
464d0118
ML
820 "Equals called for: %s:%s with result: %s\n\n",
821 node->dump_name (),
822 item->node->dump_name (),
1aec2ecc 823 eq ? "true" : "false");
b84d4347
ML
824
825 return eq;
826}
827
828/* Processes function equality comparison. */
829
830bool
fb5c322e 831sem_function::equals_private (sem_item *item)
b84d4347
ML
832{
833 if (item->type != FUNC)
834 return false;
835
836 basic_block bb1, bb2;
837 edge e1, e2;
838 edge_iterator ei1, ei2;
b84d4347
ML
839 bool result = true;
840 tree arg1, arg2;
841
842 m_compared_func = static_cast<sem_function *> (item);
843
844 gcc_assert (decl != item->decl);
845
846 if (bb_sorted.length () != m_compared_func->bb_sorted.length ()
847 || edge_count != m_compared_func->edge_count
848 || cfg_checksum != m_compared_func->cfg_checksum)
849 return return_false ();
850
b84d4347 851 m_checker = new func_checker (decl, m_compared_func->decl,
b84d4347
ML
852 false,
853 &refs_set,
854 &m_compared_func->refs_set);
1628e36b
JH
855 arg1 = DECL_ARGUMENTS (decl);
856 arg2 = DECL_ARGUMENTS (m_compared_func->decl);
857 for (unsigned i = 0;
858 arg1 && arg2; arg1 = DECL_CHAIN (arg1), arg2 = DECL_CHAIN (arg2), i++)
859 {
860 if (!types_compatible_p (TREE_TYPE (arg1), TREE_TYPE (arg2)))
861 return return_false_with_msg ("argument types are not compatible");
862 if (!param_used_p (i))
863 continue;
864 /* Perform additional checks for used parameters. */
865 if (!compatible_parm_types_p (TREE_TYPE (arg1), TREE_TYPE (arg2)))
866 return false;
867 if (!m_checker->compare_decl (arg1, arg2))
868 return return_false ();
869 }
870 if (arg1 || arg2)
871 return return_false_with_msg ("Mismatched number of arguments");
b84d4347 872
fb5c322e
JH
873 if (!dyn_cast <cgraph_node *> (node)->has_gimple_body_p ())
874 return true;
875
b84d4347
ML
876 /* Fill-up label dictionary. */
877 for (unsigned i = 0; i < bb_sorted.length (); ++i)
878 {
879 m_checker->parse_labels (bb_sorted[i]);
880 m_checker->parse_labels (m_compared_func->bb_sorted[i]);
881 }
882
883 /* Checking all basic blocks. */
884 for (unsigned i = 0; i < bb_sorted.length (); ++i)
885 if(!m_checker->compare_bb (bb_sorted[i], m_compared_func->bb_sorted[i]))
a5e2beb9 886 return return_false ();
b84d4347 887
c190efcc
ML
888 auto_vec <int> bb_dict;
889
b84d4347
ML
890 /* Basic block edges check. */
891 for (unsigned i = 0; i < bb_sorted.length (); ++i)
892 {
b84d4347
ML
893 bb1 = bb_sorted[i]->bb;
894 bb2 = m_compared_func->bb_sorted[i]->bb;
895
896 ei2 = ei_start (bb2->preds);
897
898 for (ei1 = ei_start (bb1->preds); ei_cond (ei1, &e1); ei_next (&ei1))
899 {
900 ei_cond (ei2, &e2);
901
902 if (e1->flags != e2->flags)
903 return return_false_with_msg ("flags comparison returns false");
904
1216ea72 905 if (!bb_dict_test (&bb_dict, e1->src->index, e2->src->index))
b84d4347
ML
906 return return_false_with_msg ("edge comparison returns false");
907
1216ea72 908 if (!bb_dict_test (&bb_dict, e1->dest->index, e2->dest->index))
b84d4347
ML
909 return return_false_with_msg ("BB comparison returns false");
910
911 if (!m_checker->compare_edge (e1, e2))
912 return return_false_with_msg ("edge comparison returns false");
913
914 ei_next (&ei2);
915 }
916 }
917
918 /* Basic block PHI nodes comparison. */
919 for (unsigned i = 0; i < bb_sorted.length (); i++)
920 if (!compare_phi_node (bb_sorted[i]->bb, m_compared_func->bb_sorted[i]->bb))
921 return return_false_with_msg ("PHI node comparison returns false");
922
923 return result;
924}
925
106b5466
JH
926/* Set LOCAL_P of NODE to true if DATA is non-NULL.
927 Helper for call_for_symbol_thunks_and_aliases. */
928
929static bool
930set_local (cgraph_node *node, void *data)
931{
87f94429 932 node->local = data != NULL;
106b5466
JH
933 return false;
934}
935
412049de 936/* TREE_ADDRESSABLE of NODE to true.
0a7246ee
JH
937 Helper for call_for_symbol_thunks_and_aliases. */
938
939static bool
940set_addressable (varpool_node *node, void *)
941{
942 TREE_ADDRESSABLE (node->decl) = 1;
943 return false;
944}
945
412049de
JH
946/* Clear DECL_RTL of NODE.
947 Helper for call_for_symbol_thunks_and_aliases. */
948
949static bool
950clear_decl_rtl (symtab_node *node, void *)
951{
952 SET_DECL_RTL (node->decl, NULL);
953 return false;
954}
955
0a7246ee
JH
956/* Redirect all callers of N and its aliases to TO. Remove aliases if
957 possible. Return number of redirections made. */
958
959static int
960redirect_all_callers (cgraph_node *n, cgraph_node *to)
961{
962 int nredirected = 0;
963 ipa_ref *ref;
17d1bf76 964 cgraph_edge *e = n->callers;
0a7246ee 965
17d1bf76 966 while (e)
0a7246ee 967 {
17d1bf76
ML
968 /* Redirecting thunks to interposable symbols or symbols in other sections
969 may not be supported by target output code. Play safe for now and
970 punt on redirection. */
971 if (!e->caller->thunk.thunk_p)
972 {
973 struct cgraph_edge *nexte = e->next_caller;
974 e->redirect_callee (to);
975 e = nexte;
976 nredirected++;
977 }
978 else
979 e = e->next_callee;
0a7246ee
JH
980 }
981 for (unsigned i = 0; n->iterate_direct_aliases (i, ref);)
982 {
983 bool removed = false;
984 cgraph_node *n_alias = dyn_cast <cgraph_node *> (ref->referring);
985
986 if ((DECL_COMDAT_GROUP (n->decl)
987 && (DECL_COMDAT_GROUP (n->decl)
988 == DECL_COMDAT_GROUP (n_alias->decl)))
989 || (n_alias->get_availability () > AVAIL_INTERPOSABLE
990 && n->get_availability () > AVAIL_INTERPOSABLE))
991 {
992 nredirected += redirect_all_callers (n_alias, to);
993 if (n_alias->can_remove_if_no_direct_calls_p ()
17d1bf76
ML
994 && !n_alias->call_for_symbol_and_aliases (cgraph_node::has_thunk_p,
995 NULL, true)
0a7246ee
JH
996 && !n_alias->has_aliases_p ())
997 n_alias->remove ();
998 }
999 if (!removed)
1000 i++;
1001 }
1002 return nredirected;
1003}
1004
b84d4347
ML
1005/* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can
1006 be applied. */
0a7246ee 1007
b84d4347
ML
1008bool
1009sem_function::merge (sem_item *alias_item)
1010{
1011 gcc_assert (alias_item->type == FUNC);
1012
1013 sem_function *alias_func = static_cast<sem_function *> (alias_item);
1014
1015 cgraph_node *original = get_node ();
0a7246ee 1016 cgraph_node *local_original = NULL;
b84d4347 1017 cgraph_node *alias = alias_func->get_node ();
b84d4347 1018
0a7246ee 1019 bool create_wrapper = false;
b84d4347
ML
1020 bool create_alias = false;
1021 bool redirect_callers = false;
0a7246ee
JH
1022 bool remove = false;
1023
b84d4347 1024 bool original_discardable = false;
c7a06bc1 1025 bool original_discarded = false;
b84d4347 1026
0a7246ee
JH
1027 bool original_address_matters = original->address_matters_p ();
1028 bool alias_address_matters = alias->address_matters_p ();
1029
fe6c4dc4
ML
1030 AUTO_DUMP_SCOPE ("merge",
1031 dump_user_location_t::from_function_decl (decl));
1032
257291fc
JH
1033 if (DECL_EXTERNAL (alias->decl))
1034 {
fe6c4dc4
ML
1035 if (dump_enabled_p ())
1036 dump_printf (MSG_MISSED_OPTIMIZATION,
1037 "Not unifying; alias is external.\n");
257291fc
JH
1038 return false;
1039 }
1040
0a7246ee
JH
1041 if (DECL_NO_INLINE_WARNING_P (original->decl)
1042 != DECL_NO_INLINE_WARNING_P (alias->decl))
1043 {
fe6c4dc4
ML
1044 if (dump_enabled_p ())
1045 dump_printf (MSG_MISSED_OPTIMIZATION,
1046 "Not unifying; DECL_NO_INLINE_WARNING mismatch.\n");
0a7246ee
JH
1047 return false;
1048 }
1049
b84d4347
ML
1050 /* Do not attempt to mix functions from different user sections;
1051 we do not know what user intends with those. */
1052 if (((DECL_SECTION_NAME (original->decl) && !original->implicit_section)
1053 || (DECL_SECTION_NAME (alias->decl) && !alias->implicit_section))
1054 && DECL_SECTION_NAME (original->decl) != DECL_SECTION_NAME (alias->decl))
1055 {
fe6c4dc4
ML
1056 if (dump_enabled_p ())
1057 dump_printf (MSG_MISSED_OPTIMIZATION,
1058 "Not unifying; "
1059 "original and alias are in different sections.\n");
b84d4347
ML
1060 return false;
1061 }
1062
fcb6fced
ML
1063 if (!original->in_same_comdat_group_p (alias)
1064 || original->comdat_local_p ())
1065 {
fe6c4dc4
ML
1066 if (dump_enabled_p ())
1067 dump_printf (MSG_MISSED_OPTIMIZATION,
1068 "Not unifying; alias nor wrapper cannot be created; "
1069 "across comdat group boundary\n");
fcb6fced
ML
1070 return false;
1071 }
1072
b84d4347 1073 /* See if original is in a section that can be discarded if the main
c7a06bc1 1074 symbol is not used. */
0a7246ee 1075
c7a06bc1
JH
1076 if (original->can_be_discarded_p ())
1077 original_discardable = true;
1078 /* Also consider case where we have resolution info and we know that
67914693 1079 original's definition is not going to be used. In this case we cannot
0a7246ee 1080 create alias to original. */
c7a06bc1
JH
1081 if (node->resolution != LDPR_UNKNOWN
1082 && !decl_binds_to_current_def_p (node->decl))
1083 original_discardable = original_discarded = true;
b84d4347 1084
0a7246ee 1085 /* Creating a symtab alias is the optimal way to merge.
67914693 1086 It however cannot be used in the following cases:
0a7246ee
JH
1087
1088 1) if ORIGINAL and ALIAS may be possibly compared for address equality.
1089 2) if ORIGINAL is in a section that may be discarded by linker or if
67914693 1090 it is an external functions where we cannot create an alias
0a7246ee
JH
1091 (ORIGINAL_DISCARDABLE)
1092 3) if target do not support symbol aliases.
bbcdfb93 1093 4) original and alias lie in different comdat groups.
0a7246ee 1094
67914693 1095 If we cannot produce alias, we will turn ALIAS into WRAPPER of ORIGINAL
0a7246ee
JH
1096 and/or redirect all callers from ALIAS to ORIGINAL. */
1097 if ((original_address_matters && alias_address_matters)
bbcdfb93
JH
1098 || (original_discardable
1099 && (!DECL_COMDAT_GROUP (alias->decl)
1100 || (DECL_COMDAT_GROUP (alias->decl)
1101 != DECL_COMDAT_GROUP (original->decl))))
c7a06bc1 1102 || original_discarded
bbcdfb93
JH
1103 || !sem_item::target_supports_symbol_aliases_p ()
1104 || DECL_COMDAT_GROUP (alias->decl) != DECL_COMDAT_GROUP (original->decl))
b84d4347 1105 {
0a7246ee
JH
1106 /* First see if we can produce wrapper. */
1107
977b01e3
JH
1108 /* Symbol properties that matter for references must be preserved.
1109 TODO: We can produce wrapper, but we need to produce alias of ORIGINAL
1110 with proper properties. */
1111 if (!sem_item::compare_referenced_symbol_properties (NULL, original, alias,
1112 alias->address_taken))
1113 {
fe6c4dc4
ML
1114 if (dump_enabled_p ())
1115 dump_printf (MSG_MISSED_OPTIMIZATION,
1116 "Wrapper cannot be created because referenced symbol "
1117 "properties mismatch\n");
977b01e3 1118 }
0a7246ee
JH
1119 /* Do not turn function in one comdat group into wrapper to another
1120 comdat group. Other compiler producing the body of the
956d615d 1121 another comdat group may make opposite decision and with unfortunate
0a7246ee 1122 linker choices this may close a loop. */
977b01e3
JH
1123 else if (DECL_COMDAT_GROUP (original->decl)
1124 && DECL_COMDAT_GROUP (alias->decl)
1125 && (DECL_COMDAT_GROUP (alias->decl)
1126 != DECL_COMDAT_GROUP (original->decl)))
0a7246ee 1127 {
fe6c4dc4
ML
1128 if (dump_enabled_p ())
1129 dump_printf (MSG_MISSED_OPTIMIZATION,
1130 "Wrapper cannot be created because of COMDAT\n");
0a7246ee 1131 }
4ebd491f
EB
1132 else if (DECL_STATIC_CHAIN (alias->decl)
1133 || DECL_STATIC_CHAIN (original->decl))
0a7246ee 1134 {
fe6c4dc4
ML
1135 if (dump_enabled_p ())
1136 dump_printf (MSG_MISSED_OPTIMIZATION,
1137 "Cannot create wrapper of nested function.\n");
0a7246ee
JH
1138 }
1139 /* TODO: We can also deal with variadic functions never calling
1140 VA_START. */
1141 else if (stdarg_p (TREE_TYPE (alias->decl)))
1142 {
fe6c4dc4
ML
1143 if (dump_enabled_p ())
1144 dump_printf (MSG_MISSED_OPTIMIZATION,
1145 "cannot create wrapper of stdarg function.\n");
0a7246ee 1146 }
0bceb671 1147 else if (ipa_fn_summaries
f658ad30
JH
1148 && ipa_size_summaries->get (alias) != NULL
1149 && ipa_size_summaries->get (alias)->self_size <= 2)
0a7246ee 1150 {
fe6c4dc4
ML
1151 if (dump_enabled_p ())
1152 dump_printf (MSG_MISSED_OPTIMIZATION, "Wrapper creation is not "
1153 "profitable (function is too small).\n");
0a7246ee
JH
1154 }
1155 /* If user paid attention to mark function noinline, assume it is
155ed511
SL
1156 somewhat special and do not try to turn it into a wrapper that
1157 cannot be undone by inliner. */
0a7246ee
JH
1158 else if (lookup_attribute ("noinline", DECL_ATTRIBUTES (alias->decl)))
1159 {
fe6c4dc4
ML
1160 if (dump_enabled_p ())
1161 dump_printf (MSG_MISSED_OPTIMIZATION,
1162 "Wrappers are not created for noinline.\n");
0a7246ee
JH
1163 }
1164 else
1165 create_wrapper = true;
1166
956d615d 1167 /* We can redirect local calls in the case both alias and original
0a7246ee 1168 are not interposable. */
b84d4347 1169 redirect_callers
0a7246ee 1170 = alias->get_availability () > AVAIL_INTERPOSABLE
31db0fe0 1171 && original->get_availability () > AVAIL_INTERPOSABLE;
977b01e3
JH
1172 /* TODO: We can redirect, but we need to produce alias of ORIGINAL
1173 with proper properties. */
1174 if (!sem_item::compare_referenced_symbol_properties (NULL, original, alias,
1175 alias->address_taken))
1176 redirect_callers = false;
b84d4347 1177
0a7246ee
JH
1178 if (!redirect_callers && !create_wrapper)
1179 {
fe6c4dc4
ML
1180 if (dump_enabled_p ())
1181 dump_printf (MSG_MISSED_OPTIMIZATION,
1182 "Not unifying; cannot redirect callers nor "
1183 "produce wrapper\n");
0a7246ee
JH
1184 return false;
1185 }
1186
1187 /* Work out the symbol the wrapper should call.
1188 If ORIGINAL is interposable, we need to call a local alias.
c7a06bc1
JH
1189 Also produce local alias (if possible) as an optimization.
1190
67914693 1191 Local aliases cannot be created inside comdat groups because that
c7a06bc1
JH
1192 prevents inlining. */
1193 if (!original_discardable && !original->get_comdat_group ())
0a7246ee
JH
1194 {
1195 local_original
1196 = dyn_cast <cgraph_node *> (original->noninterposable_alias ());
1197 if (!local_original
1198 && original->get_availability () > AVAIL_INTERPOSABLE)
1199 local_original = original;
0a7246ee 1200 }
67914693 1201 /* If we cannot use local alias, fallback to the original
0a7246ee
JH
1202 when possible. */
1203 else if (original->get_availability () > AVAIL_INTERPOSABLE)
1204 local_original = original;
c7a06bc1 1205
67914693 1206 /* If original is COMDAT local, we cannot really redirect calls outside
c7a06bc1
JH
1207 of its comdat group to it. */
1208 if (original->comdat_local_p ())
1209 redirect_callers = false;
0a7246ee
JH
1210 if (!local_original)
1211 {
fe6c4dc4
ML
1212 if (dump_enabled_p ())
1213 dump_printf (MSG_MISSED_OPTIMIZATION,
1214 "Not unifying; cannot produce local alias.\n");
0a7246ee
JH
1215 return false;
1216 }
f657d665 1217
0a7246ee
JH
1218 if (!redirect_callers && !create_wrapper)
1219 {
fe6c4dc4
ML
1220 if (dump_enabled_p ())
1221 dump_printf (MSG_MISSED_OPTIMIZATION,
1222 "Not unifying; "
1223 "cannot redirect callers nor produce a wrapper\n");
0a7246ee
JH
1224 return false;
1225 }
1226 if (!create_wrapper
17d1bf76
ML
1227 && !alias->call_for_symbol_and_aliases (cgraph_node::has_thunk_p,
1228 NULL, true)
0a7246ee
JH
1229 && !alias->can_remove_if_no_direct_calls_p ())
1230 {
fe6c4dc4
ML
1231 if (dump_enabled_p ())
1232 dump_printf (MSG_MISSED_OPTIMIZATION,
1233 "Not unifying; cannot make wrapper and "
1234 "function has other uses than direct calls\n");
0a7246ee
JH
1235 return false;
1236 }
544dafa6 1237 }
0a7246ee
JH
1238 else
1239 create_alias = true;
544dafa6 1240
b84d4347
ML
1241 if (redirect_callers)
1242 {
0a7246ee 1243 int nredirected = redirect_all_callers (alias, local_original);
b84d4347 1244
0a7246ee
JH
1245 if (nredirected)
1246 {
1247 alias->icf_merged = true;
1248 local_original->icf_merged = true;
b84d4347 1249
fe6c4dc4
ML
1250 if (dump_enabled_p ())
1251 dump_printf (MSG_NOTE,
1252 "%i local calls have been "
1253 "redirected.\n", nredirected);
b84d4347
ML
1254 }
1255
0a7246ee
JH
1256 /* If all callers was redirected, do not produce wrapper. */
1257 if (alias->can_remove_if_no_direct_calls_p ()
824ca15e 1258 && !DECL_VIRTUAL_P (alias->decl)
0a7246ee
JH
1259 && !alias->has_aliases_p ())
1260 {
1261 create_wrapper = false;
1262 remove = true;
1263 }
1264 gcc_assert (!create_alias);
b84d4347 1265 }
b84d4347
ML
1266 else if (create_alias)
1267 {
1268 alias->icf_merged = true;
1269
1270 /* Remove the function's body. */
1271 ipa_merge_profiles (original, alias);
b1e65564 1272 symtab->call_cgraph_removal_hooks (alias);
b84d4347
ML
1273 alias->release_body (true);
1274 alias->reset ();
412049de
JH
1275 /* Notice global symbol possibly produced RTL. */
1276 ((symtab_node *)alias)->call_for_symbol_and_aliases (clear_decl_rtl,
1277 NULL, true);
b84d4347
ML
1278
1279 /* Create the alias. */
1280 cgraph_node::create_alias (alias_func->decl, decl);
1281 alias->resolve_alias (original);
1282
106b5466
JH
1283 original->call_for_symbol_thunks_and_aliases
1284 (set_local, (void *)(size_t) original->local_p (), true);
9d4ded75 1285
fe6c4dc4
ML
1286 if (dump_enabled_p ())
1287 dump_printf (MSG_OPTIMIZED_LOCATIONS,
1288 "Unified; Function alias has been created.\n");
b84d4347 1289 }
0a7246ee 1290 if (create_wrapper)
b84d4347 1291 {
0a7246ee
JH
1292 gcc_assert (!create_alias);
1293 alias->icf_merged = true;
b1e65564 1294 symtab->call_cgraph_removal_hooks (alias);
0a7246ee 1295 local_original->icf_merged = true;
b84d4347 1296
3995f3a2
JH
1297 /* FIXME update local_original counts. */
1298 ipa_merge_profiles (original, alias, true);
0a7246ee 1299 alias->create_wrapper (local_original);
b1e65564 1300 symtab->call_cgraph_insertion_hooks (alias);
b84d4347 1301
fe6c4dc4
ML
1302 if (dump_enabled_p ())
1303 dump_printf (MSG_OPTIMIZED_LOCATIONS,
1304 "Unified; Wrapper has been created.\n");
0a7246ee 1305 }
17d1bf76
ML
1306
1307 /* It's possible that redirection can hit thunks that block
1308 redirection opportunities. */
1309 gcc_assert (alias->icf_merged || remove || redirect_callers);
0a7246ee 1310 original->icf_merged = true;
34b42fb0 1311
88636b62
JH
1312 /* We use merged flag to track cases where COMDAT function is known to be
1313 compatible its callers. If we merged in non-COMDAT, we need to give up
1314 on this optimization. */
1315 if (original->merged_comdat && !alias->merged_comdat)
1316 {
fe6c4dc4
ML
1317 if (dump_enabled_p ())
1318 dump_printf (MSG_NOTE, "Dropping merged_comdat flag.\n");
e9e70798
JH
1319 if (local_original)
1320 local_original->merged_comdat = false;
1321 original->merged_comdat = false;
88636b62 1322 }
34b42fb0 1323
0a7246ee
JH
1324 if (remove)
1325 {
1326 ipa_merge_profiles (original, alias);
1327 alias->release_body ();
1328 alias->reset ();
1329 alias->body_removed = true;
b84d4347 1330 alias->icf_merged = true;
fe6c4dc4
ML
1331 if (dump_enabled_p ())
1332 dump_printf (MSG_OPTIMIZED_LOCATIONS,
1333 "Unified; Function body was removed.\n");
b84d4347 1334 }
b84d4347
ML
1335
1336 return true;
1337}
1338
1339/* Semantic item initialization function. */
1340
1341void
a37f58f5 1342sem_function::init (ipa_icf_gimple::func_checker *checker)
b84d4347 1343{
a37f58f5 1344 m_checker = checker;
b84d4347 1345 if (in_lto_p)
70486010 1346 get_node ()->get_untransformed_body ();
b84d4347
ML
1347
1348 tree fndecl = node->decl;
1349 function *func = DECL_STRUCT_FUNCTION (fndecl);
1350
1351 gcc_assert (func);
1352 gcc_assert (SSANAMES (func));
1353
1354 ssa_names_size = SSANAMES (func)->length ();
1355 node = node;
1356
1357 decl = fndecl;
1358 region_tree = func->eh->region_tree;
1359
1360 /* iterating all function arguments. */
1361 arg_count = count_formal_params (fndecl);
1362
1363 edge_count = n_edges_for_fn (func);
fb5c322e
JH
1364 cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
1365 if (!cnode->thunk.thunk_p)
1366 {
1367 cfg_checksum = coverage_compute_cfg_checksum (func);
b84d4347 1368
fb5c322e 1369 inchash::hash hstate;
b84d4347 1370
fb5c322e
JH
1371 basic_block bb;
1372 FOR_EACH_BB_FN (bb, func)
b84d4347 1373 {
fb5c322e 1374 unsigned nondbg_stmt_count = 0;
b84d4347 1375
fb5c322e
JH
1376 edge e;
1377 for (edge_iterator ei = ei_start (bb->preds); ei_cond (ei, &e);
1378 ei_next (&ei))
1379 cfg_checksum = iterative_hash_host_wide_int (e->flags,
1380 cfg_checksum);
1381
1382 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
1383 gsi_next (&gsi))
b84d4347 1384 {
355fe088 1385 gimple *stmt = gsi_stmt (gsi);
fb5c322e
JH
1386
1387 if (gimple_code (stmt) != GIMPLE_DEBUG
1388 && gimple_code (stmt) != GIMPLE_PREDICT)
1389 {
1390 hash_stmt (stmt, hstate);
1391 nondbg_stmt_count++;
1392 }
b84d4347 1393 }
b84d4347 1394
5c5f0b65 1395 hstate.commit_flag ();
fb5c322e
JH
1396 gcode_hash = hstate.end ();
1397 bb_sizes.safe_push (nondbg_stmt_count);
b84d4347 1398
fb5c322e
JH
1399 /* Inserting basic block to hash table. */
1400 sem_bb *semantic_bb = new sem_bb (bb, nondbg_stmt_count,
1401 EDGE_COUNT (bb->preds)
1402 + EDGE_COUNT (bb->succs));
b84d4347 1403
fb5c322e
JH
1404 bb_sorted.safe_push (semantic_bb);
1405 }
1406 }
1407 else
1408 {
1409 cfg_checksum = 0;
1410 inchash::hash hstate;
449e9a33
RS
1411 hstate.add_hwi (cnode->thunk.fixed_offset);
1412 hstate.add_hwi (cnode->thunk.virtual_value);
fb5c322e
JH
1413 hstate.add_flag (cnode->thunk.this_adjusting);
1414 hstate.add_flag (cnode->thunk.virtual_offset_p);
fb5c322e
JH
1415 gcode_hash = hstate.end ();
1416 }
33b3af3f
ML
1417
1418 m_checker = NULL;
b84d4347
ML
1419}
1420
1421/* Improve accumulated hash for HSTATE based on a gimple statement STMT. */
1422
1423void
355fe088 1424sem_function::hash_stmt (gimple *stmt, inchash::hash &hstate)
b84d4347
ML
1425{
1426 enum gimple_code code = gimple_code (stmt);
1427
a8d93817 1428 hstate.add_int (code);
b84d4347 1429
a8d93817 1430 switch (code)
b84d4347 1431 {
69f6b1f4 1432 case GIMPLE_SWITCH:
a37f58f5
ML
1433 m_checker->hash_operand (gimple_switch_index (as_a <gswitch *> (stmt)),
1434 hstate, 0);
69f6b1f4 1435 break;
a8d93817 1436 case GIMPLE_ASSIGN:
69f6b1f4 1437 hstate.add_int (gimple_assign_rhs_code (stmt));
a8d93817
JH
1438 if (commutative_tree_code (gimple_assign_rhs_code (stmt))
1439 || commutative_ternary_tree_code (gimple_assign_rhs_code (stmt)))
b84d4347 1440 {
a37f58f5
ML
1441 m_checker->hash_operand (gimple_assign_rhs1 (stmt), hstate, 0);
1442 m_checker->hash_operand (gimple_assign_rhs2 (stmt), hstate, 0);
69f6b1f4 1443 if (commutative_ternary_tree_code (gimple_assign_rhs_code (stmt)))
a37f58f5
ML
1444 m_checker->hash_operand (gimple_assign_rhs3 (stmt), hstate, 0);
1445 m_checker->hash_operand (gimple_assign_lhs (stmt), hstate, 0);
b84d4347 1446 }
191816a3 1447 /* fall through */
a8d93817
JH
1448 case GIMPLE_CALL:
1449 case GIMPLE_ASM:
1450 case GIMPLE_COND:
1451 case GIMPLE_GOTO:
1452 case GIMPLE_RETURN:
1453 /* All these statements are equivalent if their operands are. */
1454 for (unsigned i = 0; i < gimple_num_ops (stmt); ++i)
a37f58f5 1455 m_checker->hash_operand (gimple_op (stmt, i), hstate, 0);
5c5f0b65
IT
1456 /* Consider nocf_check attribute in hash as it affects code
1457 generation. */
1458 if (code == GIMPLE_CALL
1459 && flag_cf_protection & CF_BRANCH)
1460 hstate.add_flag (gimple_call_nocf_check_p (as_a <gcall *> (stmt)));
a8d93817
JH
1461 default:
1462 break;
b84d4347
ML
1463 }
1464}
1465
1466
1467/* Return true if polymorphic comparison must be processed. */
1468
1469bool
1470sem_function::compare_polymorphic_p (void)
1471{
060cfff4
JH
1472 struct cgraph_edge *e;
1473
69f6b1f4 1474 if (!opt_for_fn (get_node ()->decl, flag_devirtualize))
060cfff4 1475 return false;
69f6b1f4 1476 if (get_node ()->indirect_calls != NULL)
060cfff4
JH
1477 return true;
1478 /* TODO: We can do simple propagation determining what calls may lead to
1479 a polymorphic call. */
69f6b1f4 1480 for (e = get_node ()->callees; e; e = e->next_callee)
060cfff4
JH
1481 if (e->callee->definition
1482 && opt_for_fn (e->callee->decl, flag_devirtualize))
1483 return true;
1484 return false;
b84d4347
ML
1485}
1486
1487/* For a given call graph NODE, the function constructs new
1488 semantic function item. */
1489
1490sem_function *
a37f58f5
ML
1491sem_function::parse (cgraph_node *node, bitmap_obstack *stack,
1492 func_checker *checker)
b84d4347
ML
1493{
1494 tree fndecl = node->decl;
1495 function *func = DECL_STRUCT_FUNCTION (fndecl);
1496
fb5c322e 1497 if (!func || (!node->has_gimple_body_p () && !node->thunk.thunk_p))
b84d4347
ML
1498 return NULL;
1499
1500 if (lookup_attribute_by_prefix ("omp ", DECL_ATTRIBUTES (node->decl)) != NULL)
1501 return NULL;
1502
97ad3aef
CP
1503 if (lookup_attribute_by_prefix ("oacc ",
1504 DECL_ATTRIBUTES (node->decl)) != NULL)
1505 return NULL;
1506
2a85ddbb
ML
1507 /* PR ipa/70306. */
1508 if (DECL_STATIC_CONSTRUCTOR (node->decl)
1509 || DECL_STATIC_DESTRUCTOR (node->decl))
1510 return NULL;
1511
fedf2718 1512 sem_function *f = new sem_function (node, stack);
a37f58f5 1513 f->init (checker);
b84d4347
ML
1514
1515 return f;
1516}
1517
b84d4347
ML
1518/* For given basic blocks BB1 and BB2 (from functions FUNC1 and FUNC),
1519 return true if phi nodes are semantically equivalent in these blocks . */
1520
1521bool
1522sem_function::compare_phi_node (basic_block bb1, basic_block bb2)
1523{
538dd0b7
DM
1524 gphi_iterator si1, si2;
1525 gphi *phi1, *phi2;
b84d4347
ML
1526 unsigned size1, size2, i;
1527 tree t1, t2;
1528 edge e1, e2;
1529
1530 gcc_assert (bb1 != NULL);
1531 gcc_assert (bb2 != NULL);
1532
880dcdae
VI
1533 si2 = gsi_start_nonvirtual_phis (bb2);
1534 for (si1 = gsi_start_nonvirtual_phis (bb1); !gsi_end_p (si1);
1535 gsi_next_nonvirtual_phi (&si1))
b84d4347 1536 {
b84d4347
ML
1537 if (gsi_end_p (si1) && gsi_end_p (si2))
1538 break;
1539
1540 if (gsi_end_p (si1) || gsi_end_p (si2))
1541 return return_false();
1542
538dd0b7
DM
1543 phi1 = si1.phi ();
1544 phi2 = si2.phi ();
b84d4347 1545
59f084e0
ML
1546 tree phi_result1 = gimple_phi_result (phi1);
1547 tree phi_result2 = gimple_phi_result (phi2);
1548
1549 if (!m_checker->compare_operand (phi_result1, phi_result2))
1550 return return_false_with_msg ("PHI results are different");
1551
b84d4347
ML
1552 size1 = gimple_phi_num_args (phi1);
1553 size2 = gimple_phi_num_args (phi2);
1554
1555 if (size1 != size2)
1556 return return_false ();
1557
1558 for (i = 0; i < size1; ++i)
1559 {
1560 t1 = gimple_phi_arg (phi1, i)->def;
1561 t2 = gimple_phi_arg (phi2, i)->def;
1562
1563 if (!m_checker->compare_operand (t1, t2))
1564 return return_false ();
1565
1566 e1 = gimple_phi_arg_edge (phi1, i);
1567 e2 = gimple_phi_arg_edge (phi2, i);
1568
1569 if (!m_checker->compare_edge (e1, e2))
1570 return return_false ();
1571 }
1572
880dcdae 1573 gsi_next_nonvirtual_phi (&si2);
b84d4347
ML
1574 }
1575
1576 return true;
1577}
1578
b84d4347
ML
1579/* Basic blocks dictionary BB_DICT returns true if SOURCE index BB
1580 corresponds to TARGET. */
1581
1582bool
1216ea72 1583sem_function::bb_dict_test (vec<int> *bb_dict, int source, int target)
b84d4347 1584{
c190efcc
ML
1585 source++;
1586 target++;
1587
1216ea72
TS
1588 if (bb_dict->length () <= (unsigned)source)
1589 bb_dict->safe_grow_cleared (source + 1);
c190efcc 1590
1216ea72 1591 if ((*bb_dict)[source] == 0)
b84d4347 1592 {
1216ea72 1593 (*bb_dict)[source] = target;
b84d4347
ML
1594 return true;
1595 }
1596 else
1216ea72 1597 return (*bb_dict)[source] == target;
b84d4347
ML
1598}
1599
b84d4347
ML
1600sem_variable::sem_variable (bitmap_obstack *stack): sem_item (VAR, stack)
1601{
1602}
1603
fedf2718
ML
1604sem_variable::sem_variable (varpool_node *node, bitmap_obstack *stack)
1605: sem_item (VAR, node, stack)
b84d4347
ML
1606{
1607 gcc_checking_assert (node);
1608 gcc_checking_assert (get_node ());
1609}
1610
46305737
JH
1611/* Fast equality function based on knowledge known in WPA. */
1612
1613bool
1614sem_variable::equals_wpa (sem_item *item,
1615 hash_map <symtab_node *, sem_item *> &ignored_nodes)
1616{
1617 gcc_assert (item->type == VAR);
1618
1619 if (node->num_references () != item->node->num_references ())
1620 return return_false_with_msg ("different number of references");
1621
1622 if (DECL_TLS_MODEL (decl) || DECL_TLS_MODEL (item->decl))
1623 return return_false_with_msg ("TLS model");
1624
b3587b99
JH
1625 /* DECL_ALIGN is safe to merge, because we will always chose the largest
1626 alignment out of all aliases. */
46305737
JH
1627
1628 if (DECL_VIRTUAL_P (decl) != DECL_VIRTUAL_P (item->decl))
1629 return return_false_with_msg ("Virtual flag mismatch");
1630
1631 if (DECL_SIZE (decl) != DECL_SIZE (item->decl)
1632 && ((!DECL_SIZE (decl) || !DECL_SIZE (item->decl))
1633 || !operand_equal_p (DECL_SIZE (decl),
1634 DECL_SIZE (item->decl), OEP_ONLY_CONST)))
1635 return return_false_with_msg ("size mismatch");
1636
1637 /* Do not attempt to mix data from different user sections;
1638 we do not know what user intends with those. */
1639 if (((DECL_SECTION_NAME (decl) && !node->implicit_section)
1640 || (DECL_SECTION_NAME (item->decl) && !item->node->implicit_section))
1641 && DECL_SECTION_NAME (decl) != DECL_SECTION_NAME (item->decl))
1642 return return_false_with_msg ("user section mismatch");
1643
1644 if (DECL_IN_TEXT_SECTION (decl) != DECL_IN_TEXT_SECTION (item->decl))
1645 return return_false_with_msg ("text section");
1646
1647 ipa_ref *ref = NULL, *ref2 = NULL;
1648 for (unsigned i = 0; node->iterate_reference (i, ref); i++)
1649 {
1650 item->node->iterate_reference (i, ref2);
1651
b3587b99
JH
1652 if (ref->use != ref2->use)
1653 return return_false_with_msg ("reference use mismatch");
1654
977b01e3 1655 if (!compare_symbol_references (ignored_nodes,
46305737
JH
1656 ref->referred, ref2->referred,
1657 ref->address_matters_p ()))
1658 return false;
1659 }
1660
1661 return true;
1662}
1663
b84d4347 1664/* Returns true if the item equals to ITEM given as argument. */
c4c0f336 1665
b84d4347
ML
1666bool
1667sem_variable::equals (sem_item *item,
c4c0f336 1668 hash_map <symtab_node *, sem_item *> &)
b84d4347
ML
1669{
1670 gcc_assert (item->type == VAR);
c4c0f336 1671 bool ret;
b84d4347 1672
c4c0f336
ML
1673 if (DECL_INITIAL (decl) == error_mark_node && in_lto_p)
1674 dyn_cast <varpool_node *>(node)->get_constructor ();
1675 if (DECL_INITIAL (item->decl) == error_mark_node && in_lto_p)
1676 dyn_cast <varpool_node *>(item->node)->get_constructor ();
b84d4347 1677
9374ef82
ML
1678 /* As seen in PR ipa/65303 we have to compare variables types. */
1679 if (!func_checker::compatible_types_p (TREE_TYPE (decl),
1680 TREE_TYPE (item->decl)))
1681 return return_false_with_msg ("variables types are different");
1682
c4c0f336
ML
1683 ret = sem_variable::equals (DECL_INITIAL (decl),
1684 DECL_INITIAL (item->node->decl));
1685 if (dump_file && (dump_flags & TDF_DETAILS))
1686 fprintf (dump_file,
464d0118
ML
1687 "Equals called for vars: %s:%s with result: %s\n\n",
1688 node->dump_name (), item->node->dump_name (),
1689 ret ? "true" : "false");
b84d4347 1690
c4c0f336 1691 return ret;
b84d4347
ML
1692}
1693
1694/* Compares trees T1 and T2 for semantic equality. */
1695
1696bool
1697sem_variable::equals (tree t1, tree t2)
1698{
46305737
JH
1699 if (!t1 || !t2)
1700 return return_with_debug (t1 == t2);
1701 if (t1 == t2)
1702 return true;
b84d4347
ML
1703 tree_code tc1 = TREE_CODE (t1);
1704 tree_code tc2 = TREE_CODE (t2);
1705
1706 if (tc1 != tc2)
46305737 1707 return return_false_with_msg ("TREE_CODE mismatch");
b84d4347
ML
1708
1709 switch (tc1)
1710 {
1711 case CONSTRUCTOR:
1712 {
46305737
JH
1713 vec<constructor_elt, va_gc> *v1, *v2;
1714 unsigned HOST_WIDE_INT idx;
b84d4347 1715
46305737
JH
1716 enum tree_code typecode = TREE_CODE (TREE_TYPE (t1));
1717 if (typecode != TREE_CODE (TREE_TYPE (t2)))
1718 return return_false_with_msg ("constructor type mismatch");
b84d4347 1719
46305737
JH
1720 if (typecode == ARRAY_TYPE)
1721 {
1722 HOST_WIDE_INT size_1 = int_size_in_bytes (TREE_TYPE (t1));
1723 /* For arrays, check that the sizes all match. */
1724 if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2))
1725 || size_1 == -1
1726 || size_1 != int_size_in_bytes (TREE_TYPE (t2)))
1727 return return_false_with_msg ("constructor array size mismatch");
1728 }
1729 else if (!func_checker::compatible_types_p (TREE_TYPE (t1),
1730 TREE_TYPE (t2)))
1731 return return_false_with_msg ("constructor type incompatible");
b84d4347 1732
46305737
JH
1733 v1 = CONSTRUCTOR_ELTS (t1);
1734 v2 = CONSTRUCTOR_ELTS (t2);
1735 if (vec_safe_length (v1) != vec_safe_length (v2))
1736 return return_false_with_msg ("constructor number of elts mismatch");
1737
1738 for (idx = 0; idx < vec_safe_length (v1); ++idx)
1739 {
1740 constructor_elt *c1 = &(*v1)[idx];
1741 constructor_elt *c2 = &(*v2)[idx];
1742
1743 /* Check that each value is the same... */
1744 if (!sem_variable::equals (c1->value, c2->value))
1745 return false;
1746 /* ... and that they apply to the same fields! */
1747 if (!sem_variable::equals (c1->index, c2->index))
1748 return false;
1749 }
b84d4347
ML
1750 return true;
1751 }
1752 case MEM_REF:
1753 {
1754 tree x1 = TREE_OPERAND (t1, 0);
1755 tree x2 = TREE_OPERAND (t2, 0);
1756 tree y1 = TREE_OPERAND (t1, 1);
1757 tree y2 = TREE_OPERAND (t2, 1);
1758
060cfff4 1759 if (!func_checker::compatible_types_p (TREE_TYPE (x1), TREE_TYPE (x2)))
b84d4347
ML
1760 return return_false ();
1761
1762 /* Type of the offset on MEM_REF does not matter. */
46305737 1763 return return_with_debug (sem_variable::equals (x1, x2)
6e246559
RS
1764 && known_eq (wi::to_poly_offset (y1),
1765 wi::to_poly_offset (y2)));
b84d4347 1766 }
b84d4347 1767 case ADDR_EXPR:
46305737 1768 case FDESC_EXPR:
b84d4347
ML
1769 {
1770 tree op1 = TREE_OPERAND (t1, 0);
1771 tree op2 = TREE_OPERAND (t2, 0);
1772 return sem_variable::equals (op1, op2);
1773 }
46305737 1774 /* References to other vars/decls are compared using ipa-ref. */
b84d4347
ML
1775 case FUNCTION_DECL:
1776 case VAR_DECL:
46305737
JH
1777 if (decl_in_symtab_p (t1) && decl_in_symtab_p (t2))
1778 return true;
1779 return return_false_with_msg ("Declaration mismatch");
1780 case CONST_DECL:
1781 /* TODO: We can check CONST_DECL by its DECL_INITIAL, but for that we
1782 need to process its VAR/FUNCTION references without relying on ipa-ref
1783 compare. */
b84d4347
ML
1784 case FIELD_DECL:
1785 case LABEL_DECL:
46305737 1786 return return_false_with_msg ("Declaration mismatch");
b84d4347 1787 case INTEGER_CST:
46305737
JH
1788 /* Integer constants are the same only if the same width of type. */
1789 if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2)))
1790 return return_false_with_msg ("INTEGER_CST precision mismatch");
1791 if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2)))
1792 return return_false_with_msg ("INTEGER_CST mode mismatch");
1793 return return_with_debug (tree_int_cst_equal (t1, t2));
b84d4347 1794 case STRING_CST:
46305737
JH
1795 if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2)))
1796 return return_false_with_msg ("STRING_CST mode mismatch");
1797 if (TREE_STRING_LENGTH (t1) != TREE_STRING_LENGTH (t2))
1798 return return_false_with_msg ("STRING_CST length mismatch");
1799 if (memcmp (TREE_STRING_POINTER (t1), TREE_STRING_POINTER (t2),
1800 TREE_STRING_LENGTH (t1)))
1801 return return_false_with_msg ("STRING_CST mismatch");
1802 return true;
1803 case FIXED_CST:
1804 /* Fixed constants are the same only if the same width of type. */
1805 if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2)))
1806 return return_false_with_msg ("FIXED_CST precision mismatch");
1807
1808 return return_with_debug (FIXED_VALUES_IDENTICAL (TREE_FIXED_CST (t1),
1809 TREE_FIXED_CST (t2)));
b84d4347 1810 case COMPLEX_CST:
46305737
JH
1811 return (sem_variable::equals (TREE_REALPART (t1), TREE_REALPART (t2))
1812 && sem_variable::equals (TREE_IMAGPART (t1), TREE_IMAGPART (t2)));
1813 case REAL_CST:
1814 /* Real constants are the same only if the same width of type. */
1815 if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2)))
1816 return return_false_with_msg ("REAL_CST precision mismatch");
1a25c6b1
RS
1817 return return_with_debug (real_identical (&TREE_REAL_CST (t1),
1818 &TREE_REAL_CST (t2)));
46305737
JH
1819 case VECTOR_CST:
1820 {
928686b1
RS
1821 if (maybe_ne (VECTOR_CST_NELTS (t1), VECTOR_CST_NELTS (t2)))
1822 return return_false_with_msg ("VECTOR_CST nelts mismatch");
46305737 1823
63570af0
RS
1824 unsigned int count
1825 = tree_vector_builder::binary_encoded_nelts (t1, t2);
1826 for (unsigned int i = 0; i < count; ++i)
1827 if (!sem_variable::equals (VECTOR_CST_ENCODED_ELT (t1, i),
1828 VECTOR_CST_ENCODED_ELT (t2, i)))
1829 return false;
46305737 1830
63570af0 1831 return true;
46305737 1832 }
b84d4347 1833 case ARRAY_REF:
46305737
JH
1834 case ARRAY_RANGE_REF:
1835 {
1836 tree x1 = TREE_OPERAND (t1, 0);
1837 tree x2 = TREE_OPERAND (t2, 0);
1838 tree y1 = TREE_OPERAND (t1, 1);
1839 tree y2 = TREE_OPERAND (t2, 1);
1840
3c031cbe 1841 if (!sem_variable::equals (x1, x2) || !sem_variable::equals (y1, y2))
46305737
JH
1842 return false;
1843 if (!sem_variable::equals (array_ref_low_bound (t1),
1844 array_ref_low_bound (t2)))
1845 return false;
1846 if (!sem_variable::equals (array_ref_element_size (t1),
1847 array_ref_element_size (t2)))
1848 return false;
1849 return true;
1850 }
1851
1852 case COMPONENT_REF:
b84d4347 1853 case POINTER_PLUS_EXPR:
46305737
JH
1854 case PLUS_EXPR:
1855 case MINUS_EXPR:
1856 case RANGE_EXPR:
b84d4347
ML
1857 {
1858 tree x1 = TREE_OPERAND (t1, 0);
1859 tree x2 = TREE_OPERAND (t2, 0);
1860 tree y1 = TREE_OPERAND (t1, 1);
1861 tree y2 = TREE_OPERAND (t2, 1);
1862
1863 return sem_variable::equals (x1, x2) && sem_variable::equals (y1, y2);
1864 }
46305737
JH
1865
1866 CASE_CONVERT:
1867 case VIEW_CONVERT_EXPR:
060cfff4 1868 if (!func_checker::compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2)))
46305737
JH
1869 return return_false ();
1870 return sem_variable::equals (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
b84d4347
ML
1871 case ERROR_MARK:
1872 return return_false_with_msg ("ERROR_MARK");
1873 default:
1874 return return_false_with_msg ("Unknown TREE code reached");
1875 }
1876}
1877
1878/* Parser function that visits a varpool NODE. */
1879
1880sem_variable *
a37f58f5
ML
1881sem_variable::parse (varpool_node *node, bitmap_obstack *stack,
1882 func_checker *checker)
b84d4347 1883{
6fb12821
ML
1884 if (TREE_THIS_VOLATILE (node->decl) || DECL_HARD_REGISTER (node->decl)
1885 || node->alias)
b84d4347
ML
1886 return NULL;
1887
fedf2718 1888 sem_variable *v = new sem_variable (node, stack);
a37f58f5 1889 v->init (checker);
b84d4347
ML
1890
1891 return v;
1892}
1893
a37f58f5 1894/* Semantic variable initialization function. */
b84d4347 1895
a37f58f5
ML
1896void
1897sem_variable::init (ipa_icf_gimple::func_checker *checker)
b84d4347 1898{
a37f58f5 1899 decl = get_node ()->decl;
3ab93359 1900
a8d93817
JH
1901 /* All WPA streamed in symbols should have their hashes computed at compile
1902 time. At this point, the constructor may not be in memory at all.
1903 DECL_INITIAL (decl) would be error_mark_node in that case. */
a37f58f5
ML
1904 if (!m_hash_set)
1905 {
1906 gcc_assert (!node->lto_file_data);
1907 inchash::hash hstate;
1908 hstate.add_int (456346417);
1909 checker->hash_operand (DECL_INITIAL (decl), hstate, 0);
1910 set_hash (hstate.end ());
1911 }
1912}
b84d4347 1913
a37f58f5 1914/* References independent hash function. */
b84d4347 1915
a37f58f5
ML
1916hashval_t
1917sem_variable::get_hash (void)
1918{
1919 gcc_checking_assert (m_hash_set);
808b6bb7 1920 return m_hash;
b84d4347
ML
1921}
1922
1923/* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can
1924 be applied. */
1925
1926bool
1927sem_variable::merge (sem_item *alias_item)
1928{
1929 gcc_assert (alias_item->type == VAR);
1930
fe6c4dc4
ML
1931 AUTO_DUMP_SCOPE ("merge",
1932 dump_user_location_t::from_function_decl (decl));
f657d665
ML
1933 if (!sem_item::target_supports_symbol_aliases_p ())
1934 {
fe6c4dc4
ML
1935 if (dump_enabled_p ())
1936 dump_printf (MSG_MISSED_OPTIMIZATION, "Not unifying; "
1937 "Symbol aliases are not supported by target\n");
f657d665
ML
1938 return false;
1939 }
1940
257291fc
JH
1941 if (DECL_EXTERNAL (alias_item->decl))
1942 {
fe6c4dc4
ML
1943 if (dump_enabled_p ())
1944 dump_printf (MSG_MISSED_OPTIMIZATION,
1945 "Not unifying; alias is external.\n");
257291fc
JH
1946 return false;
1947 }
1948
b84d4347
ML
1949 sem_variable *alias_var = static_cast<sem_variable *> (alias_item);
1950
1951 varpool_node *original = get_node ();
1952 varpool_node *alias = alias_var->get_node ();
1953 bool original_discardable = false;
1954
0a7246ee
JH
1955 bool alias_address_matters = alias->address_matters_p ();
1956
b84d4347 1957 /* See if original is in a section that can be discarded if the main
0a7246ee
JH
1958 symbol is not used.
1959 Also consider case where we have resolution info and we know that
67914693 1960 original's definition is not going to be used. In this case we cannot
0a7246ee
JH
1961 create alias to original. */
1962 if (original->can_be_discarded_p ()
1963 || (node->resolution != LDPR_UNKNOWN
1964 && !decl_binds_to_current_def_p (node->decl)))
b84d4347
ML
1965 original_discardable = true;
1966
1967 gcc_assert (!TREE_ASM_WRITTEN (alias->decl));
1968
0a7246ee
JH
1969 /* Constant pool machinery is not quite ready for aliases.
1970 TODO: varasm code contains logic for merging DECL_IN_CONSTANT_POOL.
1971 For LTO merging does not happen that is an important missing feature.
1972 We can enable merging with LTO if the DECL_IN_CONSTANT_POOL
1973 flag is dropped and non-local symbol name is assigned. */
1974 if (DECL_IN_CONSTANT_POOL (alias->decl)
1975 || DECL_IN_CONSTANT_POOL (original->decl))
b84d4347 1976 {
fe6c4dc4
ML
1977 if (dump_enabled_p ())
1978 dump_printf (MSG_MISSED_OPTIMIZATION,
1979 "Not unifying; constant pool variables.\n");
0a7246ee
JH
1980 return false;
1981 }
b84d4347 1982
0a7246ee
JH
1983 /* Do not attempt to mix functions from different user sections;
1984 we do not know what user intends with those. */
1985 if (((DECL_SECTION_NAME (original->decl) && !original->implicit_section)
1986 || (DECL_SECTION_NAME (alias->decl) && !alias->implicit_section))
1987 && DECL_SECTION_NAME (original->decl) != DECL_SECTION_NAME (alias->decl))
1988 {
fe6c4dc4
ML
1989 if (dump_enabled_p ())
1990 dump_printf (MSG_MISSED_OPTIMIZATION,
1991 "Not unifying; "
1992 "original and alias are in different sections.\n");
b84d4347
ML
1993 return false;
1994 }
0a7246ee 1995
956d615d 1996 /* We cannot merge if address comparison matters. */
a13f439f 1997 if (alias_address_matters && flag_merge_constants < 2)
b84d4347 1998 {
fe6c4dc4
ML
1999 if (dump_enabled_p ())
2000 dump_printf (MSG_MISSED_OPTIMIZATION,
2001 "Not unifying; address of original may be compared.\n");
0a7246ee
JH
2002 return false;
2003 }
90a7a40b
AM
2004
2005 if (DECL_ALIGN (original->decl) < DECL_ALIGN (alias->decl))
2006 {
fe6c4dc4
ML
2007 if (dump_enabled_p ())
2008 dump_printf (MSG_MISSED_OPTIMIZATION,
2009 "Not unifying; "
2010 "original and alias have incompatible alignments\n");
90a7a40b
AM
2011
2012 return false;
2013 }
2014
c7a06bc1
JH
2015 if (DECL_COMDAT_GROUP (original->decl) != DECL_COMDAT_GROUP (alias->decl))
2016 {
fe6c4dc4
ML
2017 if (dump_enabled_p ())
2018 dump_printf (MSG_MISSED_OPTIMIZATION,
2019 "Not unifying; alias cannot be created; "
2020 "across comdat group boundary\n");
c7a06bc1
JH
2021
2022 return false;
2023 }
b84d4347 2024
c7a06bc1 2025 if (original_discardable)
0a7246ee 2026 {
fe6c4dc4
ML
2027 if (dump_enabled_p ())
2028 dump_printf (MSG_MISSED_OPTIMIZATION,
2029 "Not unifying; alias cannot be created; "
2030 "target is discardable\n");
b84d4347 2031
0a7246ee
JH
2032 return false;
2033 }
2034 else
2035 {
2036 gcc_assert (!original->alias);
2037 gcc_assert (!alias->alias);
b84d4347
ML
2038
2039 alias->analyzed = false;
2040
2041 DECL_INITIAL (alias->decl) = NULL;
412049de
JH
2042 ((symtab_node *)alias)->call_for_symbol_and_aliases (clear_decl_rtl,
2043 NULL, true);
b84d4347 2044 alias->remove_all_references ();
0a7246ee
JH
2045 if (TREE_ADDRESSABLE (alias->decl))
2046 original->call_for_symbol_and_aliases (set_addressable, NULL, true);
b84d4347
ML
2047
2048 varpool_node::create_alias (alias_var->decl, decl);
2049 alias->resolve_alias (original);
2050
fe6c4dc4
ML
2051 if (dump_enabled_p ())
2052 dump_printf (MSG_OPTIMIZED_LOCATIONS,
2053 "Unified; Variable alias has been created.\n");
b84d4347
ML
2054
2055 return true;
2056 }
2057}
2058
b84d4347
ML
2059/* Dump symbol to FILE. */
2060
2061void
2062sem_variable::dump_to_file (FILE *file)
2063{
2064 gcc_assert (file);
2065
2066 print_node (file, "", decl, 0);
2067 fprintf (file, "\n\n");
2068}
2069
b84d4347
ML
2070unsigned int sem_item_optimizer::class_id = 0;
2071
fedf2718
ML
2072sem_item_optimizer::sem_item_optimizer ()
2073: worklist (0), m_classes (0), m_classes_count (0), m_cgraph_node_hooks (NULL),
a9fae4b4 2074 m_varpool_node_hooks (NULL), m_merged_variables (), m_references ()
b84d4347
ML
2075{
2076 m_items.create (0);
2077 bitmap_obstack_initialize (&m_bmstack);
2078}
2079
2080sem_item_optimizer::~sem_item_optimizer ()
2081{
2082 for (unsigned int i = 0; i < m_items.length (); i++)
2083 delete m_items[i];
2084
3746a4b2
ML
2085
2086 for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
2087 it != m_classes.end (); ++it)
b84d4347 2088 {
3746a4b2
ML
2089 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
2090 delete (*it)->classes[i];
b84d4347 2091
3746a4b2
ML
2092 (*it)->classes.release ();
2093 free (*it);
b84d4347
ML
2094 }
2095
2096 m_items.release ();
2097
2098 bitmap_obstack_release (&m_bmstack);
0dbacfcf 2099 m_merged_variables.release ();
b84d4347
ML
2100}
2101
2102/* Write IPA ICF summary for symbols. */
2103
2104void
2105sem_item_optimizer::write_summary (void)
2106{
2107 unsigned int count = 0;
2108
2109 output_block *ob = create_output_block (LTO_section_ipa_icf);
2110 lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
2111 ob->symbol = NULL;
2112
2113 /* Calculate number of symbols to be serialized. */
2114 for (lto_symtab_encoder_iterator lsei = lsei_start_in_partition (encoder);
2115 !lsei_end_p (lsei);
2116 lsei_next_in_partition (&lsei))
2117 {
2118 symtab_node *node = lsei_node (lsei);
2119
2120 if (m_symtab_node_map.get (node))
2121 count++;
2122 }
2123
2124 streamer_write_uhwi (ob, count);
2125
2126 /* Process all of the symbols. */
2127 for (lto_symtab_encoder_iterator lsei = lsei_start_in_partition (encoder);
2128 !lsei_end_p (lsei);
2129 lsei_next_in_partition (&lsei))
2130 {
2131 symtab_node *node = lsei_node (lsei);
2132
2133 sem_item **item = m_symtab_node_map.get (node);
2134
2135 if (item && *item)
2136 {
2137 int node_ref = lto_symtab_encoder_encode (encoder, node);
2138 streamer_write_uhwi_stream (ob->main_stream, node_ref);
2139
2140 streamer_write_uhwi (ob, (*item)->get_hash ());
2141 }
2142 }
2143
2144 streamer_write_char_stream (ob->main_stream, 0);
2145 produce_asm (ob, NULL);
2146 destroy_output_block (ob);
2147}
2148
2149/* Reads a section from LTO stream file FILE_DATA. Input block for DATA
2150 contains LEN bytes. */
2151
2152void
2153sem_item_optimizer::read_section (lto_file_decl_data *file_data,
2154 const char *data, size_t len)
2155{
df8391b4
JJ
2156 const lto_function_header *header
2157 = (const lto_function_header *) data;
b84d4347
ML
2158 const int cfg_offset = sizeof (lto_function_header);
2159 const int main_offset = cfg_offset + header->cfg_size;
2160 const int string_offset = main_offset + header->main_size;
2161 data_in *data_in;
2162 unsigned int i;
2163 unsigned int count;
2164
2165 lto_input_block ib_main ((const char *) data + main_offset, 0,
db847fa8 2166 header->main_size, file_data->mode_table);
b84d4347 2167
df8391b4
JJ
2168 data_in
2169 = lto_data_in_create (file_data, (const char *) data + string_offset,
2170 header->string_size, vNULL);
b84d4347
ML
2171
2172 count = streamer_read_uhwi (&ib_main);
2173
2174 for (i = 0; i < count; i++)
2175 {
2176 unsigned int index;
2177 symtab_node *node;
2178 lto_symtab_encoder_t encoder;
2179
2180 index = streamer_read_uhwi (&ib_main);
2181 encoder = file_data->symtab_node_encoder;
2182 node = lto_symtab_encoder_deref (encoder, index);
2183
2184 hashval_t hash = streamer_read_uhwi (&ib_main);
b84d4347
ML
2185 gcc_assert (node->definition);
2186
b84d4347
ML
2187 if (is_a<cgraph_node *> (node))
2188 {
2189 cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
2190
fedf2718
ML
2191 sem_function *fn = new sem_function (cnode, &m_bmstack);
2192 fn->set_hash (hash);
2193 m_items.safe_push (fn);
b84d4347
ML
2194 }
2195 else
2196 {
2197 varpool_node *vnode = dyn_cast <varpool_node *> (node);
2198
fedf2718
ML
2199 sem_variable *var = new sem_variable (vnode, &m_bmstack);
2200 var->set_hash (hash);
2201 m_items.safe_push (var);
b84d4347
ML
2202 }
2203 }
2204
2205 lto_free_section_data (file_data, LTO_section_ipa_icf, NULL, data,
2206 len);
2207 lto_data_in_delete (data_in);
2208}
2209
026c3cfd 2210/* Read IPA ICF summary for symbols. */
b84d4347
ML
2211
2212void
2213sem_item_optimizer::read_summary (void)
2214{
2215 lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
2216 lto_file_decl_data *file_data;
2217 unsigned int j = 0;
2218
2219 while ((file_data = file_data_vec[j++]))
2220 {
2221 size_t len;
3c56d8d8
ML
2222 const char *data
2223 = lto_get_summary_section_data (file_data, LTO_section_ipa_icf, &len);
b84d4347
ML
2224 if (data)
2225 read_section (file_data, data, len);
2226 }
2227}
2228
2229/* Register callgraph and varpool hooks. */
2230
2231void
2232sem_item_optimizer::register_hooks (void)
2233{
e3e968e9
ML
2234 if (!m_cgraph_node_hooks)
2235 m_cgraph_node_hooks = symtab->add_cgraph_removal_hook
2236 (&sem_item_optimizer::cgraph_removal_hook, this);
b84d4347 2237
e3e968e9
ML
2238 if (!m_varpool_node_hooks)
2239 m_varpool_node_hooks = symtab->add_varpool_removal_hook
2240 (&sem_item_optimizer::varpool_removal_hook, this);
b84d4347
ML
2241}
2242
2243/* Unregister callgraph and varpool hooks. */
2244
2245void
2246sem_item_optimizer::unregister_hooks (void)
2247{
2248 if (m_cgraph_node_hooks)
2249 symtab->remove_cgraph_removal_hook (m_cgraph_node_hooks);
2250
2251 if (m_varpool_node_hooks)
2252 symtab->remove_varpool_removal_hook (m_varpool_node_hooks);
2253}
2254
2255/* Adds a CLS to hashtable associated by hash value. */
2256
2257void
2258sem_item_optimizer::add_class (congruence_class *cls)
2259{
2260 gcc_assert (cls->members.length ());
2261
df8391b4
JJ
2262 congruence_class_group *group
2263 = get_group_by_hash (cls->members[0]->get_hash (),
2264 cls->members[0]->type);
b84d4347
ML
2265 group->classes.safe_push (cls);
2266}
2267
2268/* Gets a congruence class group based on given HASH value and TYPE. */
2269
2270congruence_class_group *
2271sem_item_optimizer::get_group_by_hash (hashval_t hash, sem_item_type type)
2272{
2273 congruence_class_group *item = XNEW (congruence_class_group);
2274 item->hash = hash;
2275 item->type = type;
2276
2277 congruence_class_group **slot = m_classes.find_slot (item, INSERT);
2278
2279 if (*slot)
2280 free (item);
2281 else
2282 {
2283 item->classes.create (1);
2284 *slot = item;
2285 }
2286
2287 return *slot;
2288}
2289
2290/* Callgraph removal hook called for a NODE with a custom DATA. */
2291
2292void
2293sem_item_optimizer::cgraph_removal_hook (cgraph_node *node, void *data)
2294{
2295 sem_item_optimizer *optimizer = (sem_item_optimizer *) data;
2296 optimizer->remove_symtab_node (node);
2297}
2298
2299/* Varpool removal hook called for a NODE with a custom DATA. */
2300
2301void
2302sem_item_optimizer::varpool_removal_hook (varpool_node *node, void *data)
2303{
2304 sem_item_optimizer *optimizer = (sem_item_optimizer *) data;
2305 optimizer->remove_symtab_node (node);
2306}
2307
2308/* Remove symtab NODE triggered by symtab removal hooks. */
2309
2310void
2311sem_item_optimizer::remove_symtab_node (symtab_node *node)
2312{
b119c055 2313 gcc_assert (m_classes.is_empty ());
b84d4347
ML
2314
2315 m_removed_items_set.add (node);
2316}
2317
2318void
2319sem_item_optimizer::remove_item (sem_item *item)
2320{
2321 if (m_symtab_node_map.get (item->node))
2322 m_symtab_node_map.remove (item->node);
2323 delete item;
2324}
2325
2326/* Removes all callgraph and varpool nodes that are marked by symtab
2327 as deleted. */
2328
2329void
2330sem_item_optimizer::filter_removed_items (void)
2331{
2332 auto_vec <sem_item *> filtered;
2333
2334 for (unsigned int i = 0; i < m_items.length(); i++)
2335 {
2336 sem_item *item = m_items[i];
2337
90190bb3
ML
2338 if (m_removed_items_set.contains (item->node))
2339 {
b84d4347
ML
2340 remove_item (item);
2341 continue;
90190bb3 2342 }
b84d4347
ML
2343
2344 if (item->type == FUNC)
90190bb3 2345 {
b84d4347
ML
2346 cgraph_node *cnode = static_cast <sem_function *>(item)->get_node ();
2347
060cfff4 2348 if (in_lto_p && (cnode->alias || cnode->body_removed))
90190bb3
ML
2349 remove_item (item);
2350 else
2351 filtered.safe_push (item);
2352 }
2353 else /* VAR. */
2354 {
2355 if (!flag_ipa_icf_variables)
2356 remove_item (item);
2357 else
c4c0f336
ML
2358 {
2359 /* Filter out non-readonly variables. */
2360 tree decl = item->decl;
2361 if (TREE_READONLY (decl))
2362 filtered.safe_push (item);
2363 else
2364 remove_item (item);
2365 }
90190bb3 2366 }
b84d4347
ML
2367 }
2368
2369 /* Clean-up of released semantic items. */
2370
2371 m_items.release ();
2372 for (unsigned int i = 0; i < filtered.length(); i++)
2373 m_items.safe_push (filtered[i]);
2374}
2375
bd31fe14
ML
2376/* Optimizer entry point which returns true in case it processes
2377 a merge operation. True is returned if there's a merge operation
2378 processed. */
b84d4347 2379
bd31fe14 2380bool
b84d4347
ML
2381sem_item_optimizer::execute (void)
2382{
2383 filter_removed_items ();
8b048701
JJ
2384 unregister_hooks ();
2385
3ab93359
ML
2386 build_graph ();
2387 update_hash_by_addr_refs ();
b84d4347
ML
2388 build_hash_based_classes ();
2389
2390 if (dump_file)
2391 fprintf (dump_file, "Dump after hash based groups\n");
2392 dump_cong_classes ();
2393
b84d4347
ML
2394 subdivide_classes_by_equality (true);
2395
2396 if (dump_file)
2397 fprintf (dump_file, "Dump after WPA based types groups\n");
2398
2399 dump_cong_classes ();
2400
2401 process_cong_reduction ();
b2b29377 2402 checking_verify_classes ();
b84d4347
ML
2403
2404 if (dump_file)
2405 fprintf (dump_file, "Dump after callgraph-based congruence reduction\n");
2406
2407 dump_cong_classes ();
2408
5d97670f 2409 unsigned int loaded_symbols = parse_nonsingleton_classes ();
b84d4347
ML
2410 subdivide_classes_by_equality ();
2411
2412 if (dump_file)
2413 fprintf (dump_file, "Dump after full equality comparison of groups\n");
2414
2415 dump_cong_classes ();
2416
2417 unsigned int prev_class_count = m_classes_count;
2418
2419 process_cong_reduction ();
2420 dump_cong_classes ();
b2b29377 2421 checking_verify_classes ();
5d97670f 2422 bool merged_p = merge_classes (prev_class_count, loaded_symbols);
b84d4347
ML
2423
2424 if (dump_file && (dump_flags & TDF_DETAILS))
6c52831d 2425 symtab->dump (dump_file);
bd31fe14
ML
2426
2427 return merged_p;
b84d4347
ML
2428}
2429
2430/* Function responsible for visiting all potential functions and
2431 read-only variables that can be merged. */
2432
2433void
2434sem_item_optimizer::parse_funcs_and_vars (void)
2435{
2436 cgraph_node *cnode;
2437
a37f58f5
ML
2438 /* Create dummy func_checker for hashing purpose. */
2439 func_checker checker;
2440
b84d4347
ML
2441 if (flag_ipa_icf_functions)
2442 FOR_EACH_DEFINED_FUNCTION (cnode)
2443 {
a37f58f5 2444 sem_function *f = sem_function::parse (cnode, &m_bmstack, &checker);
b84d4347
ML
2445 if (f)
2446 {
2447 m_items.safe_push (f);
2448 m_symtab_node_map.put (cnode, f);
b84d4347 2449 }
b84d4347
ML
2450 }
2451
2452 varpool_node *vnode;
2453
2454 if (flag_ipa_icf_variables)
2455 FOR_EACH_DEFINED_VARIABLE (vnode)
2456 {
a37f58f5 2457 sem_variable *v = sem_variable::parse (vnode, &m_bmstack, &checker);
b84d4347
ML
2458
2459 if (v)
2460 {
2461 m_items.safe_push (v);
2462 m_symtab_node_map.put (vnode, v);
2463 }
2464 }
2465}
2466
2467/* Makes pairing between a congruence class CLS and semantic ITEM. */
2468
2469void
2470sem_item_optimizer::add_item_to_class (congruence_class *cls, sem_item *item)
2471{
2472 item->index_in_class = cls->members.length ();
2473 cls->members.safe_push (item);
c3af5442 2474 cls->referenced_by_count += item->referenced_by_count;
b84d4347
ML
2475 item->cls = cls;
2476}
2477
3ab93359
ML
2478/* For each semantic item, append hash values of references. */
2479
2480void
2481sem_item_optimizer::update_hash_by_addr_refs ()
2482{
69f6b1f4
JH
2483 /* First, append to hash sensitive references and class type if it need to
2484 be matched for ODR. */
3ab93359 2485 for (unsigned i = 0; i < m_items.length (); i++)
69f6b1f4
JH
2486 {
2487 m_items[i]->update_hash_by_addr_refs (m_symtab_node_map);
2488 if (m_items[i]->type == FUNC)
2489 {
2490 if (TREE_CODE (TREE_TYPE (m_items[i]->decl)) == METHOD_TYPE
2491 && contains_polymorphic_type_p
70e7f2a2 2492 (TYPE_METHOD_BASETYPE (TREE_TYPE (m_items[i]->decl)))
69f6b1f4 2493 && (DECL_CXX_CONSTRUCTOR_P (m_items[i]->decl)
b3587b99 2494 || (static_cast<sem_function *> (m_items[i])->param_used_p (0)
69f6b1f4
JH
2495 && static_cast<sem_function *> (m_items[i])
2496 ->compare_polymorphic_p ())))
2497 {
2498 tree class_type
70e7f2a2 2499 = TYPE_METHOD_BASETYPE (TREE_TYPE (m_items[i]->decl));
808b6bb7 2500 inchash::hash hstate (m_items[i]->get_hash ());
69f6b1f4
JH
2501
2502 if (TYPE_NAME (class_type)
2503 && DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (class_type)))
449e9a33 2504 hstate.add_hwi
69f6b1f4
JH
2505 (IDENTIFIER_HASH_VALUE
2506 (DECL_ASSEMBLER_NAME (TYPE_NAME (class_type))));
2507
808b6bb7 2508 m_items[i]->set_hash (hstate.end ());
69f6b1f4
JH
2509 }
2510 }
2511 }
3ab93359
ML
2512
2513 /* Once all symbols have enhanced hash value, we can append
2514 hash values of symbols that are seen by IPA ICF and are
2515 references by a semantic item. Newly computed values
2516 are saved to global_hash member variable. */
2517 for (unsigned i = 0; i < m_items.length (); i++)
2518 m_items[i]->update_hash_by_local_refs (m_symtab_node_map);
2519
2520 /* Global hash value replace current hash values. */
2521 for (unsigned i = 0; i < m_items.length (); i++)
808b6bb7 2522 m_items[i]->set_hash (m_items[i]->global_hash);
3ab93359
ML
2523}
2524
b84d4347
ML
2525/* Congruence classes are built by hash value. */
2526
2527void
2528sem_item_optimizer::build_hash_based_classes (void)
2529{
2530 for (unsigned i = 0; i < m_items.length (); i++)
2531 {
2532 sem_item *item = m_items[i];
2533
df8391b4
JJ
2534 congruence_class_group *group
2535 = get_group_by_hash (item->get_hash (), item->type);
b84d4347
ML
2536
2537 if (!group->classes.length ())
2538 {
2539 m_classes_count++;
2540 group->classes.safe_push (new congruence_class (class_id++));
2541 }
2542
2543 add_item_to_class (group->classes[0], item);
2544 }
2545}
2546
2547/* Build references according to call graph. */
2548
2549void
2550sem_item_optimizer::build_graph (void)
2551{
2552 for (unsigned i = 0; i < m_items.length (); i++)
2553 {
2554 sem_item *item = m_items[i];
2555 m_symtab_node_map.put (item->node, item);
808b6bb7
ML
2556
2557 /* Initialize hash values if we are not in LTO mode. */
2558 if (!in_lto_p)
2559 item->get_hash ();
b84d4347
ML
2560 }
2561
2562 for (unsigned i = 0; i < m_items.length (); i++)
2563 {
2564 sem_item *item = m_items[i];
2565
2566 if (item->type == FUNC)
2567 {
2568 cgraph_node *cnode = dyn_cast <cgraph_node *> (item->node);
2569
2570 cgraph_edge *e = cnode->callees;
2571 while (e)
2572 {
b6cddc7f
ML
2573 sem_item **slot = m_symtab_node_map.get
2574 (e->callee->ultimate_alias_target ());
b84d4347 2575 if (slot)
a9fae4b4 2576 item->add_reference (&m_references, *slot);
b84d4347
ML
2577
2578 e = e->next_callee;
2579 }
2580 }
2581
2582 ipa_ref *ref = NULL;
2583 for (unsigned i = 0; item->node->iterate_reference (i, ref); i++)
2584 {
b6cddc7f
ML
2585 sem_item **slot = m_symtab_node_map.get
2586 (ref->referred->ultimate_alias_target ());
b84d4347 2587 if (slot)
a9fae4b4 2588 item->add_reference (&m_references, *slot);
b84d4347
ML
2589 }
2590 }
2591}
2592
2593/* Semantic items in classes having more than one element and initialized.
2594 In case of WPA, we load function body. */
2595
5d97670f 2596unsigned int
b84d4347
ML
2597sem_item_optimizer::parse_nonsingleton_classes (void)
2598{
07b8d0af 2599 unsigned int counter = 0;
b84d4347 2600
a37f58f5
ML
2601 /* Create dummy func_checker for hashing purpose. */
2602 func_checker checker;
2603
b84d4347
ML
2604 for (unsigned i = 0; i < m_items.length (); i++)
2605 if (m_items[i]->cls->members.length () > 1)
2606 {
a37f58f5 2607 m_items[i]->init (&checker);
07b8d0af 2608 ++counter;
b84d4347
ML
2609 }
2610
2611 if (dump_file)
07b8d0af
ML
2612 {
2613 float f = m_items.length () ? 100.0f * counter / m_items.length () : 0.0f;
2614 fprintf (dump_file, "Init called for %u items (%.2f%%).\n", counter, f);
2615 }
5d97670f
ML
2616
2617 return counter;
b84d4347
ML
2618}
2619
2620/* Equality function for semantic items is used to subdivide existing
2621 classes. If IN_WPA, fast equality function is invoked. */
2622
2623void
2624sem_item_optimizer::subdivide_classes_by_equality (bool in_wpa)
2625{
3746a4b2
ML
2626 for (hash_table <congruence_class_hash>::iterator it = m_classes.begin ();
2627 it != m_classes.end (); ++it)
b84d4347 2628 {
3746a4b2 2629 unsigned int class_count = (*it)->classes.length ();
b84d4347
ML
2630
2631 for (unsigned i = 0; i < class_count; i++)
2632 {
3746a4b2 2633 congruence_class *c = (*it)->classes[i];
b84d4347
ML
2634
2635 if (c->members.length() > 1)
2636 {
2637 auto_vec <sem_item *> new_vector;
2638
2639 sem_item *first = c->members[0];
2640 new_vector.safe_push (first);
2641
3746a4b2 2642 unsigned class_split_first = (*it)->classes.length ();
b84d4347
ML
2643
2644 for (unsigned j = 1; j < c->members.length (); j++)
2645 {
2646 sem_item *item = c->members[j];
2647
df8391b4
JJ
2648 bool equals
2649 = in_wpa ? first->equals_wpa (item, m_symtab_node_map)
2650 : first->equals (item, m_symtab_node_map);
b84d4347
ML
2651
2652 if (equals)
2653 new_vector.safe_push (item);
2654 else
2655 {
2656 bool integrated = false;
2657
df8391b4 2658 for (unsigned k = class_split_first;
3746a4b2 2659 k < (*it)->classes.length (); k++)
b84d4347 2660 {
3746a4b2 2661 sem_item *x = (*it)->classes[k]->members[0];
df8391b4
JJ
2662 bool equals
2663 = in_wpa ? x->equals_wpa (item, m_symtab_node_map)
2664 : x->equals (item, m_symtab_node_map);
b84d4347
ML
2665
2666 if (equals)
2667 {
2668 integrated = true;
3746a4b2 2669 add_item_to_class ((*it)->classes[k], item);
b84d4347
ML
2670
2671 break;
2672 }
2673 }
2674
2675 if (!integrated)
2676 {
df8391b4
JJ
2677 congruence_class *c
2678 = new congruence_class (class_id++);
b84d4347
ML
2679 m_classes_count++;
2680 add_item_to_class (c, item);
2681
3746a4b2 2682 (*it)->classes.safe_push (c);
b84d4347
ML
2683 }
2684 }
2685 }
2686
df8391b4
JJ
2687 // We replace newly created new_vector for the class we've just
2688 // splitted.
b84d4347
ML
2689 c->members.release ();
2690 c->members.create (new_vector.length ());
2691
2692 for (unsigned int j = 0; j < new_vector.length (); j++)
2693 add_item_to_class (c, new_vector[j]);
2694 }
2695 }
2696 }
2697
b2b29377 2698 checking_verify_classes ();
b84d4347
ML
2699}
2700
5ebd0e61
ML
2701/* Subdivide classes by address references that members of the class
2702 reference. Example can be a pair of functions that have an address
2703 taken from a function. If these addresses are different the class
2704 is split. */
2705
2706unsigned
2707sem_item_optimizer::subdivide_classes_by_sensitive_refs ()
2708{
fb5c464a 2709 typedef hash_map <symbol_compare_hash, vec <sem_item *> > subdivide_hash_map;
bbd08a5d 2710
5ebd0e61
ML
2711 unsigned newly_created_classes = 0;
2712
3746a4b2
ML
2713 for (hash_table <congruence_class_hash>::iterator it = m_classes.begin ();
2714 it != m_classes.end (); ++it)
5ebd0e61 2715 {
3746a4b2 2716 unsigned int class_count = (*it)->classes.length ();
5ebd0e61
ML
2717 auto_vec<congruence_class *> new_classes;
2718
2719 for (unsigned i = 0; i < class_count; i++)
2720 {
3746a4b2 2721 congruence_class *c = (*it)->classes[i];
5ebd0e61
ML
2722
2723 if (c->members.length() > 1)
2724 {
bbd08a5d 2725 subdivide_hash_map split_map;
5ebd0e61
ML
2726
2727 for (unsigned j = 0; j < c->members.length (); j++)
2728 {
2729 sem_item *source_node = c->members[j];
2730
df8391b4
JJ
2731 symbol_compare_collection *collection
2732 = new symbol_compare_collection (source_node->node);
5ebd0e61 2733
bbd08a5d 2734 bool existed;
df8391b4
JJ
2735 vec <sem_item *> *slot
2736 = &split_map.get_or_insert (collection, &existed);
5ebd0e61
ML
2737 gcc_checking_assert (slot);
2738
2739 slot->safe_push (source_node);
bbd08a5d
ML
2740
2741 if (existed)
2742 delete collection;
5ebd0e61
ML
2743 }
2744
df8391b4
JJ
2745 /* If the map contains more than one key, we have to split
2746 the map appropriately. */
5ebd0e61
ML
2747 if (split_map.elements () != 1)
2748 {
2749 bool first_class = true;
2750
bbd08a5d
ML
2751 for (subdivide_hash_map::iterator it2 = split_map.begin ();
2752 it2 != split_map.end (); ++it2)
5ebd0e61
ML
2753 {
2754 congruence_class *new_cls;
2755 new_cls = new congruence_class (class_id++);
2756
2757 for (unsigned k = 0; k < (*it2).second.length (); k++)
2758 add_item_to_class (new_cls, (*it2).second[k]);
2759
2760 worklist_push (new_cls);
2761 newly_created_classes++;
2762
2763 if (first_class)
2764 {
3746a4b2 2765 (*it)->classes[i] = new_cls;
5ebd0e61
ML
2766 first_class = false;
2767 }
2768 else
2769 {
2770 new_classes.safe_push (new_cls);
2771 m_classes_count++;
2772 }
2773 }
2774 }
bbd08a5d
ML
2775
2776 /* Release memory. */
2777 for (subdivide_hash_map::iterator it2 = split_map.begin ();
2778 it2 != split_map.end (); ++it2)
2779 {
2780 delete (*it2).first;
2781 (*it2).second.release ();
2782 }
5ebd0e61
ML
2783 }
2784 }
2785
2786 for (unsigned i = 0; i < new_classes.length (); i++)
3746a4b2 2787 (*it)->classes.safe_push (new_classes[i]);
5ebd0e61
ML
2788 }
2789
2790 return newly_created_classes;
2791}
2792
b2b29377
MM
2793/* Verify congruence classes, if checking is enabled. */
2794
2795void
2796sem_item_optimizer::checking_verify_classes (void)
2797{
2798 if (flag_checking)
2799 verify_classes ();
2800}
2801
2802/* Verify congruence classes. */
b84d4347
ML
2803
2804void
2805sem_item_optimizer::verify_classes (void)
2806{
3746a4b2
ML
2807 for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
2808 it != m_classes.end (); ++it)
b84d4347 2809 {
3746a4b2 2810 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
b84d4347 2811 {
3746a4b2 2812 congruence_class *cls = (*it)->classes[i];
b84d4347 2813
b2b29377
MM
2814 gcc_assert (cls);
2815 gcc_assert (cls->members.length () > 0);
b84d4347
ML
2816
2817 for (unsigned int j = 0; j < cls->members.length (); j++)
2818 {
2819 sem_item *item = cls->members[j];
2820
b2b29377
MM
2821 gcc_assert (item);
2822 gcc_assert (item->cls == cls);
b84d4347
ML
2823 }
2824 }
2825 }
b84d4347
ML
2826}
2827
2828/* Disposes split map traverse function. CLS_PTR is pointer to congruence
2829 class, BSLOT is bitmap slot we want to release. DATA is mandatory,
2830 but unused argument. */
2831
2832bool
2833sem_item_optimizer::release_split_map (congruence_class * const &,
2834 bitmap const &b, traverse_split_pair *)
2835{
2836 bitmap bmp = b;
2837
2838 BITMAP_FREE (bmp);
2839
2840 return true;
2841}
2842
2843/* Process split operation for a class given as pointer CLS_PTR,
2844 where bitmap B splits congruence class members. DATA is used
2845 as argument of split pair. */
2846
2847bool
2848sem_item_optimizer::traverse_congruence_split (congruence_class * const &cls,
df8391b4
JJ
2849 bitmap const &b,
2850 traverse_split_pair *pair)
b84d4347
ML
2851{
2852 sem_item_optimizer *optimizer = pair->optimizer;
2853 const congruence_class *splitter_cls = pair->cls;
2854
2855 /* If counted bits are greater than zero and less than the number of members
2856 a group will be splitted. */
2857 unsigned popcount = bitmap_count_bits (b);
2858
2859 if (popcount > 0 && popcount < cls->members.length ())
2860 {
c9ab724f
ML
2861 auto_vec <congruence_class *, 2> newclasses;
2862 newclasses.quick_push (new congruence_class (class_id++));
2863 newclasses.quick_push (new congruence_class (class_id++));
b84d4347
ML
2864
2865 for (unsigned int i = 0; i < cls->members.length (); i++)
2866 {
2867 int target = bitmap_bit_p (b, i);
2868 congruence_class *tc = newclasses[target];
2869
2870 add_item_to_class (tc, cls->members[i]);
2871 }
2872
b2b29377
MM
2873 if (flag_checking)
2874 {
2875 for (unsigned int i = 0; i < 2; i++)
2876 gcc_assert (newclasses[i]->members.length ());
2877 }
b84d4347
ML
2878
2879 if (splitter_cls == cls)
2880 optimizer->splitter_class_removed = true;
2881
2882 /* Remove old class from worklist if presented. */
2883 bool in_worklist = cls->in_worklist;
2884
2885 if (in_worklist)
2886 cls->in_worklist = false;
2887
2888 congruence_class_group g;
2889 g.hash = cls->members[0]->get_hash ();
2890 g.type = cls->members[0]->type;
2891
df8391b4 2892 congruence_class_group *slot = optimizer->m_classes.find (&g);
b84d4347
ML
2893
2894 for (unsigned int i = 0; i < slot->classes.length (); i++)
2895 if (slot->classes[i] == cls)
2896 {
2897 slot->classes.ordered_remove (i);
2898 break;
2899 }
2900
2901 /* New class will be inserted and integrated to work list. */
2902 for (unsigned int i = 0; i < 2; i++)
2903 optimizer->add_class (newclasses[i]);
2904
2905 /* Two classes replace one, so that increment just by one. */
2906 optimizer->m_classes_count++;
2907
2908 /* If OLD class was presented in the worklist, we remove the class
2909 and replace it will both newly created classes. */
2910 if (in_worklist)
2911 for (unsigned int i = 0; i < 2; i++)
2912 optimizer->worklist_push (newclasses[i]);
2913 else /* Just smaller class is inserted. */
2914 {
df8391b4
JJ
2915 unsigned int smaller_index
2916 = (newclasses[0]->members.length ()
2917 < newclasses[1]->members.length ()
2918 ? 0 : 1);
b84d4347
ML
2919 optimizer->worklist_push (newclasses[smaller_index]);
2920 }
2921
2922 if (dump_file && (dump_flags & TDF_DETAILS))
2923 {
2924 fprintf (dump_file, " congruence class splitted:\n");
2925 cls->dump (dump_file, 4);
2926
2927 fprintf (dump_file, " newly created groups:\n");
2928 for (unsigned int i = 0; i < 2; i++)
2929 newclasses[i]->dump (dump_file, 4);
2930 }
2931
2932 /* Release class if not presented in work list. */
2933 if (!in_worklist)
2934 delete cls;
b84d4347 2935
a9fae4b4
ML
2936 return true;
2937 }
b84d4347 2938
a9fae4b4 2939 return false;
b84d4347
ML
2940}
2941
9e1f4e00
RB
2942/* Compare function for sorting pairs in do_congruence_step_f. */
2943
2944int
2945sem_item_optimizer::sort_congruence_split (const void *a_, const void *b_)
2946{
2947 const std::pair<congruence_class *, bitmap> *a
2948 = (const std::pair<congruence_class *, bitmap> *)a_;
2949 const std::pair<congruence_class *, bitmap> *b
2950 = (const std::pair<congruence_class *, bitmap> *)b_;
2951 if (a->first->id < b->first->id)
2952 return -1;
2953 else if (a->first->id > b->first->id)
2954 return 1;
2955 return 0;
2956}
2957
b84d4347
ML
2958/* Tests if a class CLS used as INDEXth splits any congruence classes.
2959 Bitmap stack BMSTACK is used for bitmap allocation. */
2960
a9fae4b4 2961bool
b84d4347 2962sem_item_optimizer::do_congruence_step_for_index (congruence_class *cls,
df8391b4 2963 unsigned int index)
b84d4347
ML
2964{
2965 hash_map <congruence_class *, bitmap> split_map;
2966
2967 for (unsigned int i = 0; i < cls->members.length (); i++)
2968 {
2969 sem_item *item = cls->members[i];
a9fae4b4
ML
2970 sem_usage_pair needle (item, index);
2971 vec<sem_item *> *callers = m_references.get (&needle);
2972 if (callers == NULL)
2973 continue;
b84d4347 2974
a9fae4b4 2975 for (unsigned int j = 0; j < callers->length (); j++)
b84d4347 2976 {
a9fae4b4
ML
2977 sem_item *caller = (*callers)[j];
2978 if (caller->cls->members.length () < 2)
b84d4347 2979 continue;
a9fae4b4 2980 bitmap *slot = split_map.get (caller->cls);
b84d4347
ML
2981 bitmap b;
2982
2983 if(!slot)
2984 {
2985 b = BITMAP_ALLOC (&m_bmstack);
a9fae4b4 2986 split_map.put (caller->cls, b);
b84d4347
ML
2987 }
2988 else
2989 b = *slot;
2990
a9fae4b4
ML
2991 gcc_checking_assert (caller->cls);
2992 gcc_checking_assert (caller->index_in_class
2993 < caller->cls->members.length ());
b84d4347 2994
a9fae4b4 2995 bitmap_set_bit (b, caller->index_in_class);
b84d4347
ML
2996 }
2997 }
2998
9e1f4e00
RB
2999 auto_vec<std::pair<congruence_class *, bitmap> > to_split;
3000 to_split.reserve_exact (split_map.elements ());
3001 for (hash_map <congruence_class *, bitmap>::iterator i = split_map.begin ();
3002 i != split_map.end (); ++i)
3003 to_split.safe_push (*i);
3004 to_split.qsort (sort_congruence_split);
3005
b84d4347
ML
3006 traverse_split_pair pair;
3007 pair.optimizer = this;
3008 pair.cls = cls;
3009
3010 splitter_class_removed = false;
a9fae4b4 3011 bool r = false;
9e1f4e00 3012 for (unsigned i = 0; i < to_split.length (); ++i)
a9fae4b4
ML
3013 r |= traverse_congruence_split (to_split[i].first, to_split[i].second,
3014 &pair);
b84d4347
ML
3015
3016 /* Bitmap clean-up. */
df8391b4
JJ
3017 split_map.traverse <traverse_split_pair *,
3018 sem_item_optimizer::release_split_map> (NULL);
a9fae4b4
ML
3019
3020 return r;
b84d4347
ML
3021}
3022
3023/* Every usage of a congruence class CLS is a candidate that can split the
3024 collection of classes. Bitmap stack BMSTACK is used for bitmap
3025 allocation. */
3026
3027void
3028sem_item_optimizer::do_congruence_step (congruence_class *cls)
3029{
3030 bitmap_iterator bi;
3031 unsigned int i;
3032
3033 bitmap usage = BITMAP_ALLOC (&m_bmstack);
3034
3035 for (unsigned int i = 0; i < cls->members.length (); i++)
3036 bitmap_ior_into (usage, cls->members[i]->usage_index_bitmap);
3037
3038 EXECUTE_IF_SET_IN_BITMAP (usage, 0, i, bi)
3039 {
3040 if (dump_file && (dump_flags & TDF_DETAILS))
a9fae4b4 3041 fprintf (dump_file, " processing congruence step for class: %u "
c3af5442
ML
3042 "(%u items, %u references), index: %u\n", cls->id,
3043 cls->referenced_by_count, cls->members.length (), i);
b84d4347
ML
3044 do_congruence_step_for_index (cls, i);
3045
3046 if (splitter_class_removed)
3047 break;
3048 }
3049
3050 BITMAP_FREE (usage);
3051}
3052
3053/* Adds a newly created congruence class CLS to worklist. */
3054
3055void
3056sem_item_optimizer::worklist_push (congruence_class *cls)
3057{
3058 /* Return if the class CLS is already presented in work list. */
3059 if (cls->in_worklist)
3060 return;
3061
3062 cls->in_worklist = true;
c3af5442 3063 worklist.insert (cls->referenced_by_count, cls);
b84d4347
ML
3064}
3065
3066/* Pops a class from worklist. */
3067
3068congruence_class *
3069sem_item_optimizer::worklist_pop (void)
3070{
3071 congruence_class *cls;
3072
3073 while (!worklist.empty ())
3074 {
c3af5442 3075 cls = worklist.extract_min ();
b84d4347
ML
3076 if (cls->in_worklist)
3077 {
3078 cls->in_worklist = false;
3079
3080 return cls;
3081 }
3082 else
3083 {
3084 /* Work list item was already intended to be removed.
3085 The only reason for doing it is to split a class.
3086 Thus, the class CLS is deleted. */
3087 delete cls;
3088 }
3089 }
3090
3091 return NULL;
3092}
3093
3094/* Iterative congruence reduction function. */
3095
3096void
3097sem_item_optimizer::process_cong_reduction (void)
3098{
3746a4b2
ML
3099 for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
3100 it != m_classes.end (); ++it)
3101 for (unsigned i = 0; i < (*it)->classes.length (); i++)
3102 if ((*it)->classes[i]->is_class_used ())
3103 worklist_push ((*it)->classes[i]);
b84d4347
ML
3104
3105 if (dump_file)
3106 fprintf (dump_file, "Worklist has been filled with: %lu\n",
c3af5442 3107 (unsigned long) worklist.nodes ());
b84d4347
ML
3108
3109 if (dump_file && (dump_flags & TDF_DETAILS))
3110 fprintf (dump_file, "Congruence class reduction\n");
3111
3112 congruence_class *cls;
5ebd0e61
ML
3113
3114 /* Process complete congruence reduction. */
b84d4347
ML
3115 while ((cls = worklist_pop ()) != NULL)
3116 do_congruence_step (cls);
5ebd0e61
ML
3117
3118 /* Subdivide newly created classes according to references. */
3119 unsigned new_classes = subdivide_classes_by_sensitive_refs ();
3120
3121 if (dump_file)
3122 fprintf (dump_file, "Address reference subdivision created: %u "
3123 "new classes.\n", new_classes);
b84d4347
ML
3124}
3125
3126/* Debug function prints all informations about congruence classes. */
3127
3128void
3129sem_item_optimizer::dump_cong_classes (void)
3130{
3131 if (!dump_file)
3132 return;
3133
b84d4347
ML
3134 /* Histogram calculation. */
3135 unsigned int max_index = 0;
07b8d0af 3136 unsigned int single_element_classes = 0;
b84d4347
ML
3137 unsigned int* histogram = XCNEWVEC (unsigned int, m_items.length () + 1);
3138
3746a4b2
ML
3139 for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
3140 it != m_classes.end (); ++it)
3141 for (unsigned i = 0; i < (*it)->classes.length (); i++)
b84d4347 3142 {
3746a4b2 3143 unsigned int c = (*it)->classes[i]->members.length ();
b84d4347
ML
3144 histogram[c]++;
3145
3146 if (c > max_index)
3147 max_index = c;
07b8d0af
ML
3148
3149 if (c == 1)
3150 ++single_element_classes;
b84d4347
ML
3151 }
3152
07b8d0af
ML
3153 fprintf (dump_file,
3154 "Congruence classes: %lu with total: %u items (in a non-singular "
3155 "class: %u)\n", (unsigned long) m_classes.elements (),
3156 m_items.length (), m_items.length () - single_element_classes);
b84d4347 3157 fprintf (dump_file,
7650c805 3158 "Class size histogram [number of members]: number of classes\n");
b84d4347
ML
3159 for (unsigned int i = 0; i <= max_index; i++)
3160 if (histogram[i])
07b8d0af 3161 fprintf (dump_file, "%6u: %6u\n", i, histogram[i]);
b84d4347 3162
b84d4347 3163 if (dump_flags & TDF_DETAILS)
07b8d0af
ML
3164 for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
3165 it != m_classes.end (); ++it)
b84d4347 3166 {
df8391b4 3167 fprintf (dump_file, " group: with %u classes:\n",
3746a4b2 3168 (*it)->classes.length ());
b84d4347 3169
3746a4b2 3170 for (unsigned i = 0; i < (*it)->classes.length (); i++)
b84d4347 3171 {
3746a4b2 3172 (*it)->classes[i]->dump (dump_file, 4);
b84d4347 3173
3746a4b2 3174 if (i < (*it)->classes.length () - 1)
b84d4347
ML
3175 fprintf (dump_file, " ");
3176 }
3177 }
3178
3179 free (histogram);
3180}
3181
a0843aed
ML
3182/* Sort pair of sem_items A and B by DECL_UID. */
3183
3184static int
3185sort_sem_items_by_decl_uid (const void *a, const void *b)
3186{
3187 const sem_item *i1 = *(const sem_item * const *)a;
3188 const sem_item *i2 = *(const sem_item * const *)b;
3189
3190 int uid1 = DECL_UID (i1->decl);
3191 int uid2 = DECL_UID (i2->decl);
37bc3aa0 3192 return uid1 - uid2;
a0843aed
ML
3193}
3194
3195/* Sort pair of congruence_classes A and B by DECL_UID of the first member. */
3196
3197static int
3198sort_congruence_classes_by_decl_uid (const void *a, const void *b)
3199{
3200 const congruence_class *c1 = *(const congruence_class * const *)a;
3201 const congruence_class *c2 = *(const congruence_class * const *)b;
3202
3203 int uid1 = DECL_UID (c1->members[0]->decl);
3204 int uid2 = DECL_UID (c2->members[0]->decl);
37bc3aa0 3205 return uid1 - uid2;
a0843aed
ML
3206}
3207
3208/* Sort pair of congruence_class_groups A and B by
3209 DECL_UID of the first member of a first group. */
3210
3211static int
3212sort_congruence_class_groups_by_decl_uid (const void *a, const void *b)
3213{
37bc3aa0 3214 const std::pair<congruence_class_group *, int> *g1
9f576d30 3215 = (const std::pair<congruence_class_group *, int> *) a;
37bc3aa0 3216 const std::pair<congruence_class_group *, int> *g2
9f576d30 3217 = (const std::pair<congruence_class_group *, int> *) b;
37bc3aa0 3218 return g1->second - g2->second;
a0843aed
ML
3219}
3220
b84d4347
ML
3221/* After reduction is done, we can declare all items in a group
3222 to be equal. PREV_CLASS_COUNT is start number of classes
bd31fe14 3223 before reduction. True is returned if there's a merge operation
5d97670f
ML
3224 processed. LOADED_SYMBOLS is number of symbols that were loaded
3225 in WPA. */
b84d4347 3226
bd31fe14 3227bool
5d97670f
ML
3228sem_item_optimizer::merge_classes (unsigned int prev_class_count,
3229 unsigned int loaded_symbols)
b84d4347
ML
3230{
3231 unsigned int item_count = m_items.length ();
3232 unsigned int class_count = m_classes_count;
3233 unsigned int equal_items = item_count - class_count;
3234
3235 unsigned int non_singular_classes_count = 0;
3236 unsigned int non_singular_classes_sum = 0;
3237
bd31fe14
ML
3238 bool merged_p = false;
3239
a0843aed
ML
3240 /* PR lto/78211
3241 Sort functions in congruence classes by DECL_UID and do the same
3242 for the classes to not to break -fcompare-debug. */
3243
3244 for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
3245 it != m_classes.end (); ++it)
3246 {
3247 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
3248 {
3249 congruence_class *c = (*it)->classes[i];
3250 c->members.qsort (sort_sem_items_by_decl_uid);
3251 }
3252
3253 (*it)->classes.qsort (sort_congruence_classes_by_decl_uid);
3254 }
3255
3746a4b2
ML
3256 for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
3257 it != m_classes.end (); ++it)
3258 for (unsigned int i = 0; i < (*it)->classes.length (); i++)
b84d4347 3259 {
3746a4b2 3260 congruence_class *c = (*it)->classes[i];
b84d4347
ML
3261 if (c->members.length () > 1)
3262 {
3263 non_singular_classes_count++;
3264 non_singular_classes_sum += c->members.length ();
3265 }
3266 }
3267
37bc3aa0
ML
3268 auto_vec<std::pair<congruence_class_group *, int> > classes (
3269 m_classes.elements ());
a0843aed
ML
3270 for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
3271 it != m_classes.end (); ++it)
37bc3aa0
ML
3272 {
3273 int uid = DECL_UID ((*it)->classes[0]->members[0]->decl);
3274 classes.quick_push (std::pair<congruence_class_group *, int> (*it, uid));
3275 }
a0843aed
ML
3276
3277 classes.qsort (sort_congruence_class_groups_by_decl_uid);
3278
b84d4347
ML
3279 if (dump_file)
3280 {
3281 fprintf (dump_file, "\nItem count: %u\n", item_count);
3282 fprintf (dump_file, "Congruent classes before: %u, after: %u\n",
3283 prev_class_count, class_count);
3284 fprintf (dump_file, "Average class size before: %.2f, after: %.2f\n",
f1c859ee
ML
3285 prev_class_count ? 1.0f * item_count / prev_class_count : 0.0f,
3286 class_count ? 1.0f * item_count / class_count : 0.0f);
b84d4347 3287 fprintf (dump_file, "Average non-singular class size: %.2f, count: %u\n",
f1c859ee
ML
3288 non_singular_classes_count ? 1.0f * non_singular_classes_sum /
3289 non_singular_classes_count : 0.0f,
b84d4347
ML
3290 non_singular_classes_count);
3291 fprintf (dump_file, "Equal symbols: %u\n", equal_items);
5d97670f
ML
3292 unsigned total = equal_items + non_singular_classes_count;
3293 fprintf (dump_file, "Totally needed symbols: %u"
3294 ", fraction of loaded symbols: %.2f%%\n\n", total,
3295 loaded_symbols ? 100.0f * total / loaded_symbols: 0.0f);
b84d4347
ML
3296 }
3297
a0843aed 3298 unsigned int l;
37bc3aa0 3299 std::pair<congruence_class_group *, int> *it;
a0843aed 3300 FOR_EACH_VEC_ELT (classes, l, it)
37bc3aa0 3301 for (unsigned int i = 0; i < it->first->classes.length (); i++)
b84d4347 3302 {
37bc3aa0 3303 congruence_class *c = it->first->classes[i];
b84d4347
ML
3304
3305 if (c->members.length () == 1)
3306 continue;
3307
b84d4347
ML
3308 sem_item *source = c->members[0];
3309
78fcec3f
JH
3310 if (DECL_NAME (source->decl)
3311 && MAIN_NAME_P (DECL_NAME (source->decl)))
aa398781
NS
3312 /* If merge via wrappers, picking main as the target can be
3313 problematic. */
3314 source = c->members[1];
3315
3316 for (unsigned int j = 0; j < c->members.length (); j++)
b84d4347
ML
3317 {
3318 sem_item *alias = c->members[j];
b84d4347 3319
aa398781
NS
3320 if (alias == source)
3321 continue;
3322
fe6c4dc4
ML
3323 dump_user_location_t loc
3324 = dump_user_location_t::from_function_decl (source->decl);
3325 if (dump_enabled_p ())
b84d4347 3326 {
fe6c4dc4
ML
3327 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
3328 "Semantic equality hit:%s->%s\n",
3629ff8a
ML
3329 source->node->dump_name (),
3330 alias->node->dump_name ());
fe6c4dc4
ML
3331 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
3332 "Assembler symbol names:%s->%s\n",
3629ff8a
ML
3333 source->node->dump_asm_name (),
3334 alias->node->dump_asm_name ());
b84d4347
ML
3335 }
3336
185c9e56
ML
3337 if (lookup_attribute ("no_icf", DECL_ATTRIBUTES (alias->decl)))
3338 {
fe6c4dc4
ML
3339 if (dump_enabled_p ())
3340 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
3341 "Merge operation is skipped due to no_icf "
3342 "attribute.\n");
185c9e56
ML
3343 continue;
3344 }
3345
b84d4347
ML
3346 if (dump_file && (dump_flags & TDF_DETAILS))
3347 {
3348 source->dump_to_file (dump_file);
3349 alias->dump_to_file (dump_file);
3350 }
3351
7aeb92b4 3352 if (dbg_cnt (merged_ipa_icf))
0dbacfcf
ML
3353 {
3354 bool merged = source->merge (alias);
3355 merged_p |= merged;
3356
3357 if (merged && alias->type == VAR)
3358 {
3359 symtab_pair p = symtab_pair (source->node, alias->node);
3360 m_merged_variables.safe_push (p);
3361 }
3362 }
b84d4347
ML
3363 }
3364 }
bd31fe14 3365
0dbacfcf
ML
3366 if (!m_merged_variables.is_empty ())
3367 fixup_points_to_sets ();
3368
bd31fe14 3369 return merged_p;
b84d4347
ML
3370}
3371
0dbacfcf
ML
3372/* Fixup points to set PT. */
3373
3374void
3375sem_item_optimizer::fixup_pt_set (struct pt_solution *pt)
3376{
3377 if (pt->vars == NULL)
3378 return;
3379
3380 unsigned i;
3381 symtab_pair *item;
3382 FOR_EACH_VEC_ELT (m_merged_variables, i, item)
3383 if (bitmap_bit_p (pt->vars, DECL_UID (item->second->decl)))
3384 bitmap_set_bit (pt->vars, DECL_UID (item->first->decl));
3385}
3386
3387/* Set all points-to UIDs of aliases pointing to node N as UID. */
3388
3389static void
3390set_alias_uids (symtab_node *n, int uid)
3391{
3392 ipa_ref *ref;
3393 FOR_EACH_ALIAS (n, ref)
3394 {
3395 if (dump_file)
3396 fprintf (dump_file, " Setting points-to UID of [%s] as %d\n",
3629ff8a 3397 ref->referring->dump_asm_name (), uid);
0dbacfcf
ML
3398
3399 SET_DECL_PT_UID (ref->referring->decl, uid);
3400 set_alias_uids (ref->referring, uid);
3401 }
3402}
3403
3404/* Fixup points to analysis info. */
3405
3406void
3407sem_item_optimizer::fixup_points_to_sets (void)
3408{
3409 /* TODO: remove in GCC 9 and trigger PTA re-creation after IPA passes. */
0dbacfcf 3410 cgraph_node *cnode;
0dbacfcf
ML
3411
3412 FOR_EACH_DEFINED_FUNCTION (cnode)
3413 {
3414 tree name;
3415 unsigned i;
3416 function *fn = DECL_STRUCT_FUNCTION (cnode->decl);
cc614ac0
ML
3417 if (!gimple_in_ssa_p (fn))
3418 continue;
3419
0dbacfcf
ML
3420 FOR_EACH_SSA_NAME (i, name, fn)
3421 if (POINTER_TYPE_P (TREE_TYPE (name))
3422 && SSA_NAME_PTR_INFO (name))
3423 fixup_pt_set (&SSA_NAME_PTR_INFO (name)->pt);
3424 fixup_pt_set (&fn->gimple_df->escaped);
3425
956d615d 3426 /* The above gets us to 99% I guess, at least catching the
0dbacfcf
ML
3427 address compares. Below also gets us aliasing correct
3428 but as said we're giving leeway to the situation with
3429 readonly vars anyway, so ... */
3430 basic_block bb;
3431 FOR_EACH_BB_FN (bb, fn)
3432 for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
3433 gsi_next (&gsi))
3434 {
3435 gcall *call = dyn_cast<gcall *> (gsi_stmt (gsi));
3436 if (call)
3437 {
3438 fixup_pt_set (gimple_call_use_set (call));
3439 fixup_pt_set (gimple_call_clobber_set (call));
3440 }
3441 }
3442 }
3443
3444 unsigned i;
3445 symtab_pair *item;
3446 FOR_EACH_VEC_ELT (m_merged_variables, i, item)
3447 set_alias_uids (item->first, DECL_UID (item->first->decl));
3448}
3449
b84d4347
ML
3450/* Dump function prints all class members to a FILE with an INDENT. */
3451
3452void
3453congruence_class::dump (FILE *file, unsigned int indent) const
3454{
3455 FPRINTF_SPACES (file, indent, "class with id: %u, hash: %u, items: %u\n",
3456 id, members[0]->get_hash (), members.length ());
3457
3458 FPUTS_SPACES (file, indent + 2, "");
3459 for (unsigned i = 0; i < members.length (); i++)
464d0118 3460 fprintf (file, "%s ", members[i]->node->dump_asm_name ());
b84d4347
ML
3461
3462 fprintf (file, "\n");
3463}
3464
3465/* Returns true if there's a member that is used from another group. */
3466
3467bool
3468congruence_class::is_class_used (void)
3469{
3470 for (unsigned int i = 0; i < members.length (); i++)
a9fae4b4 3471 if (members[i]->referenced_by_count)
b84d4347
ML
3472 return true;
3473
3474 return false;
3475}
3476
b84d4347
ML
3477/* Generate pass summary for IPA ICF pass. */
3478
3479static void
3480ipa_icf_generate_summary (void)
3481{
3482 if (!optimizer)
3483 optimizer = new sem_item_optimizer ();
3484
e3e968e9 3485 optimizer->register_hooks ();
b84d4347
ML
3486 optimizer->parse_funcs_and_vars ();
3487}
3488
3489/* Write pass summary for IPA ICF pass. */
3490
3491static void
3492ipa_icf_write_summary (void)
3493{
3494 gcc_assert (optimizer);
3495
3496 optimizer->write_summary ();
3497}
3498
3499/* Read pass summary for IPA ICF pass. */
3500
3501static void
3502ipa_icf_read_summary (void)
3503{
3504 if (!optimizer)
3505 optimizer = new sem_item_optimizer ();
3506
3507 optimizer->read_summary ();
3508 optimizer->register_hooks ();
3509}
3510
956d615d 3511/* Semantic equality execution function. */
b84d4347
ML
3512
3513static unsigned int
3514ipa_icf_driver (void)
3515{
3516 gcc_assert (optimizer);
3517
bd31fe14 3518 bool merged_p = optimizer->execute ();
b84d4347
ML
3519
3520 delete optimizer;
9612a39a 3521 optimizer = NULL;
b84d4347 3522
bd31fe14 3523 return merged_p ? TODO_remove_functions : 0;
b84d4347
ML
3524}
3525
3526const pass_data pass_data_ipa_icf =
3527{
3528 IPA_PASS, /* type */
3529 "icf", /* name */
3530 OPTGROUP_IPA, /* optinfo_flags */
3531 TV_IPA_ICF, /* tv_id */
3532 0, /* properties_required */
3533 0, /* properties_provided */
3534 0, /* properties_destroyed */
3535 0, /* todo_flags_start */
3536 0, /* todo_flags_finish */
3537};
3538
3539class pass_ipa_icf : public ipa_opt_pass_d
3540{
3541public:
3542 pass_ipa_icf (gcc::context *ctxt)
3543 : ipa_opt_pass_d (pass_data_ipa_icf, ctxt,
3544 ipa_icf_generate_summary, /* generate_summary */
3545 ipa_icf_write_summary, /* write_summary */
3546 ipa_icf_read_summary, /* read_summary */
3547 NULL, /*
3548 write_optimization_summary */
3549 NULL, /*
3550 read_optimization_summary */
3551 NULL, /* stmt_fixup */
3552 0, /* function_transform_todo_flags_start */
3553 NULL, /* function_transform */
3554 NULL) /* variable_transform */
3555 {}
3556
3557 /* opt_pass methods: */
3558 virtual bool gate (function *)
3559 {
b16650ac 3560 return in_lto_p || flag_ipa_icf_variables || flag_ipa_icf_functions;
b84d4347
ML
3561 }
3562
3563 virtual unsigned int execute (function *)
3564 {
3565 return ipa_icf_driver();
3566 }
3567}; // class pass_ipa_icf
3568
3569} // ipa_icf namespace
3570
3571ipa_opt_pass_d *
3572make_pass_ipa_icf (gcc::context *ctxt)
3573{
3574 return new ipa_icf::pass_ipa_icf (ctxt);
3575}