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