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