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