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 : 1272988 : symbol_compare_collection::symbol_compare_collection (symtab_node *node)
107 : : {
108 : 1272988 : m_references.create (0);
109 : 1272988 : m_interposables.create (0);
110 : :
111 : 1272988 : ipa_ref *ref;
112 : :
113 : 2279595 : if (is_a <varpool_node *> (node) && DECL_VIRTUAL_P (node->decl))
114 : 1272988 : return;
115 : :
116 : 1626734 : for (unsigned i = 0; node->iterate_reference (i, ref); i++)
117 : : {
118 : 354076 : if (ref->address_matters_p ())
119 : 313099 : m_references.safe_push (ref->referred);
120 : :
121 : 354076 : if (ref->referred->get_availability () <= AVAIL_INTERPOSABLE)
122 : : {
123 : 288873 : if (ref->address_matters_p ())
124 : 287272 : m_references.safe_push (ref->referred);
125 : : else
126 : 1601 : m_interposables.safe_push (ref->referred);
127 : : }
128 : : }
129 : :
130 : 1272658 : if (is_a <cgraph_node *> (node))
131 : : {
132 : 266381 : cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
133 : :
134 : 544916 : for (cgraph_edge *e = cnode->callees; e; e = e->next_callee)
135 : 278535 : if (e->callee->get_availability () <= AVAIL_INTERPOSABLE)
136 : 81865 : 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 : 31123655 : sem_usage_pair::sem_usage_pair (sem_item *_item, unsigned int _index)
143 : 31123655 : : item (_item), index (_index)
144 : : {
145 : 31123655 : }
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 : 3329805 : sem_item::sem_item (sem_item_type _type, symtab_node *_node,
154 : 3329805 : bitmap_obstack *stack)
155 : 6659610 : : type (_type), node (_node), referenced_by_count (0), m_hash (-1),
156 : 3329805 : m_hash_set (false)
157 : : {
158 : 3329805 : decl = node->decl;
159 : 3329805 : setup (stack);
160 : 3329805 : }
161 : :
162 : : /* Add reference to a semantic TARGET. */
163 : :
164 : : void
165 : 3992494 : sem_item::add_reference (ref_map *refs,
166 : : sem_item *target)
167 : : {
168 : 3992494 : unsigned index = reference_count++;
169 : 3992494 : bool existed;
170 : :
171 : 3992494 : sem_usage_pair *pair = new sem_usage_pair (target, index);
172 : 3992494 : vec<sem_item *> &v = refs->get_or_insert (pair, &existed);
173 : 3992494 : if (existed)
174 : 1070888 : delete pair;
175 : :
176 : 3992494 : v.safe_push (this);
177 : 3992494 : bitmap_set_bit (target->usage_index_bitmap, index);
178 : 3992494 : refs_set.add (target->node);
179 : 3992494 : ++target->referenced_by_count;
180 : 3992494 : }
181 : :
182 : : /* Initialize internal data structures. Bitmap STACK is used for
183 : : bitmap memory allocation process. */
184 : :
185 : : void
186 : 3329805 : sem_item::setup (bitmap_obstack *stack)
187 : : {
188 : 3329805 : gcc_checking_assert (node);
189 : :
190 : 3329805 : reference_count = 0;
191 : 3329805 : tree_refs.create (0);
192 : 3329805 : usage_index_bitmap = BITMAP_ALLOC (stack);
193 : 3329805 : }
194 : :
195 : 3175951 : sem_item::~sem_item ()
196 : : {
197 : 3175951 : tree_refs.release ();
198 : :
199 : 3175951 : BITMAP_FREE (usage_index_bitmap);
200 : 3175951 : }
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 : 431585 : 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 : 431585 : gcc_checking_assert (TARGET_SUPPORTS_ALIASES);
224 : 431585 : return true;
225 : : #endif
226 : : }
227 : :
228 : 9332044 : void sem_item::set_hash (hashval_t hash)
229 : : {
230 : 9332044 : m_hash = hash;
231 : 9332044 : m_hash_set = true;
232 : 9332044 : }
233 : :
234 : : hash_map<const_tree, hashval_t> sem_item::m_type_hash_cache;
235 : :
236 : 1040611 : sem_function::sem_function (cgraph_node *node, bitmap_obstack *stack)
237 : 1040611 : : sem_item (FUNC, node, stack), memory_access_types (),
238 : 1040611 : m_alias_sets_hash (0), m_checker (NULL), m_compared_func (NULL)
239 : : {
240 : 1040611 : bb_sizes.create (0);
241 : 1040611 : bb_sorted.create (0);
242 : 1040611 : }
243 : :
244 : 2000640 : sem_function::~sem_function ()
245 : : {
246 : 7498218 : for (unsigned i = 0; i < bb_sorted.length (); i++)
247 : 6497898 : delete (bb_sorted[i]);
248 : :
249 : 1000320 : bb_sizes.release ();
250 : 1000320 : bb_sorted.release ();
251 : 2000640 : }
252 : :
253 : : /* Calculates hash value based on a BASIC_BLOCK. */
254 : :
255 : : hashval_t
256 : 6316995 : sem_function::get_bb_hash (const sem_bb *basic_block)
257 : : {
258 : 6316995 : inchash::hash hstate;
259 : :
260 : 6316995 : hstate.add_int (basic_block->nondbg_stmt_count);
261 : 6316995 : hstate.add_int (basic_block->edge_count);
262 : :
263 : 6316995 : return hstate.end ();
264 : : }
265 : :
266 : : /* References independent hash function. */
267 : :
268 : : hashval_t
269 : 10648634 : sem_function::get_hash (void)
270 : : {
271 : 10648634 : if (!m_hash_set)
272 : : {
273 : 964405 : inchash::hash hstate;
274 : 964405 : hstate.add_int (177454); /* Random number for function type. */
275 : :
276 : 964405 : hstate.add_int (arg_count);
277 : 964405 : hstate.add_int (cfg_checksum);
278 : 964405 : hstate.add_int (gcode_hash);
279 : :
280 : 14562800 : for (unsigned i = 0; i < bb_sorted.length (); i++)
281 : 6316995 : hstate.merge_hash (get_bb_hash (bb_sorted[i]));
282 : :
283 : 7281400 : for (unsigned i = 0; i < bb_sizes.length (); i++)
284 : 6316995 : hstate.add_int (bb_sizes[i]);
285 : :
286 : : /* Add common features of declaration itself. */
287 : 964405 : if (DECL_FUNCTION_SPECIFIC_TARGET (decl))
288 : 123673 : hstate.add_hwi
289 : 123673 : (cl_target_option_hash
290 : 123673 : (TREE_TARGET_OPTION (DECL_FUNCTION_SPECIFIC_TARGET (decl))));
291 : 964405 : if (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl))
292 : 129109 : hstate.add_hwi
293 : 129109 : (cl_optimization_hash
294 : 129109 : (TREE_OPTIMIZATION (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl))));
295 : 964405 : hstate.add_flag (DECL_CXX_CONSTRUCTOR_P (decl));
296 : 964405 : hstate.add_flag (DECL_CXX_DESTRUCTOR_P (decl));
297 : 964405 : hstate.add_flag (DECL_STATIC_CHAIN (decl));
298 : :
299 : 964405 : set_hash (hstate.end ());
300 : : }
301 : :
302 : 10648634 : 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 : 364797 : sem_item::compare_referenced_symbol_properties (symtab_node *used_by,
318 : : symtab_node *n1,
319 : : symtab_node *n2,
320 : : bool address)
321 : : {
322 : 364797 : 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 : 967657 : if ((!used_by || address || !is_a <cgraph_node *> (used_by)
336 : 244622 : || !opt_for_fn (used_by->decl, optimize_size))
337 : 360480 : && !opt_for_fn (n1->decl, optimize_size)
338 : 356613 : && n1->get_availability () > AVAIL_INTERPOSABLE
339 : 504395 : && (!DECL_UNINLINABLE (n1->decl) || !DECL_UNINLINABLE (n2->decl)))
340 : : {
341 : 97268 : if (DECL_DISREGARD_INLINE_LIMITS (n1->decl)
342 : 48634 : != DECL_DISREGARD_INLINE_LIMITS (n2->decl))
343 : 0 : return return_false_with_msg
344 : : ("DECL_DISREGARD_INLINE_LIMITS are different");
345 : :
346 : 48634 : if (DECL_DECLARED_INLINE_P (n1->decl)
347 : 48634 : != DECL_DECLARED_INLINE_P (n2->decl))
348 : 253 : return return_false_with_msg ("inline attributes are different");
349 : : }
350 : :
351 : 362302 : if (DECL_IS_OPERATOR_NEW_P (n1->decl)
352 : 362302 : != DECL_IS_OPERATOR_NEW_P (n2->decl))
353 : 0 : return return_false_with_msg ("operator new flags are different");
354 : :
355 : 362302 : if (DECL_IS_REPLACEABLE_OPERATOR (n1->decl)
356 : 362302 : != 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 : 364544 : if (is_a <varpool_node *> (n1))
364 : : {
365 : 4216 : 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 : 2653 : && (!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 : 1974 : 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 : 1974 : if (!attribute_list_equal (DECL_ATTRIBUTES (n1->decl),
383 : 1974 : DECL_ATTRIBUTES (n2->decl)))
384 : 0 : return return_false_with_msg ("different var decl attributes");
385 : 1974 : if (comp_type_attributes (TREE_TYPE (n1->decl),
386 : 1974 : 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 : 734035 : if (used_by && is_a <varpool_node *> (used_by)
393 : 369238 : && DECL_VIRTUAL_P (used_by->decl))
394 : : {
395 : 4958 : if (DECL_VIRTUAL_P (n1->decl) != DECL_VIRTUAL_P (n2->decl))
396 : 0 : return return_false_with_msg ("virtual flag mismatch");
397 : 4958 : if (DECL_VIRTUAL_P (n1->decl) && is_a <cgraph_node *> (n1)
398 : 8054 : && (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 : 5932638 : sem_item::hash_referenced_symbol_properties (symtab_node *ref,
408 : : inchash::hash &hstate,
409 : : bool address)
410 : : {
411 : 5932638 : if (is_a <cgraph_node *> (ref))
412 : : {
413 : 1657921 : if ((type != FUNC || address || !opt_for_fn (decl, optimize_size))
414 : 1892413 : && !opt_for_fn (ref->decl, optimize_size)
415 : 3821612 : && !DECL_UNINLINABLE (ref->decl))
416 : : {
417 : 1498041 : hstate.add_flag (DECL_DISREGARD_INLINE_LIMITS (ref->decl));
418 : 1498041 : hstate.add_flag (DECL_DECLARED_INLINE_P (ref->decl));
419 : : }
420 : 1934704 : hstate.add_flag (DECL_IS_OPERATOR_NEW_P (ref->decl));
421 : : }
422 : 3997934 : else if (is_a <varpool_node *> (ref))
423 : : {
424 : 3997934 : hstate.add_flag (DECL_VIRTUAL_P (ref->decl));
425 : 3997934 : if (address)
426 : 2953809 : hstate.add_int (DECL_ALIGN (ref->decl));
427 : : }
428 : 5932638 : }
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 : 506634 : 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 : 506634 : enum availability avail1, avail2;
441 : :
442 : 506634 : if (n1 == n2)
443 : : return true;
444 : :
445 : : /* Never match variable and function. */
446 : 749931 : if (is_a <varpool_node *> (n1) != is_a <varpool_node *> (n2))
447 : : return false;
448 : :
449 : 249977 : if (!compare_referenced_symbol_properties (node, n1, n2, address))
450 : : return false;
451 : 249418 : if (address && n1->equal_address_to (n2) == 1)
452 : : return true;
453 : 249418 : if (!address && n1->semantically_equivalent_p (n2))
454 : : return true;
455 : :
456 : 249417 : n1 = n1->ultimate_alias_target (&avail1);
457 : 249417 : n2 = n2->ultimate_alias_target (&avail2);
458 : :
459 : 36887 : if (avail1 > AVAIL_INTERPOSABLE && ignored_nodes.get (n1)
460 : 286304 : && avail2 > AVAIL_INTERPOSABLE && ignored_nodes.get (n2))
461 : : return true;
462 : :
463 : 212651 : 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 : 146061 : bool sem_function::compare_edge_flags (cgraph_edge *e1, cgraph_edge *e2)
470 : : {
471 : 146061 : if (e1->indirect_info && e2->indirect_info)
472 : : {
473 : 4529 : int e1_flags = e1->indirect_info->ecf_flags;
474 : 4529 : int e2_flags = e2->indirect_info->ecf_flags;
475 : :
476 : 4529 : if (e1_flags != e2_flags)
477 : 0 : return return_false_with_msg ("ICF flags are different");
478 : : }
479 : 141532 : 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 : 1431241 : sem_function::param_used_p (unsigned int i)
489 : : {
490 : 1431241 : if (ipa_node_params_sum == NULL)
491 : : return true;
492 : :
493 : 1431241 : ipa_node_params *parms_info = ipa_node_params_sum->get (get_node ());
494 : :
495 : 1431241 : if (!parms_info || vec_safe_length (parms_info->descriptors) <= i)
496 : : return true;
497 : :
498 : 1111778 : 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 : 1264732 : sem_function::compatible_parm_types_p (tree parm1, tree parm2)
507 : : {
508 : : /* Be sure that parameters are TBAA compatible. */
509 : 1264732 : if (!func_checker::compatible_types_p (parm1, parm2))
510 : 342 : return return_false_with_msg ("parameter type is not compatible");
511 : :
512 : 1264390 : if (POINTER_TYPE_P (parm1)
513 : 1264390 : && (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 : 1264390 : if (POINTER_TYPE_P (parm1)
518 : 114883 : && TREE_CODE (parm1) != TREE_CODE (parm2)
519 : 1264390 : && 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 : 1679053 : sem_function::equals_wpa (sem_item *item,
529 : : hash_map <symtab_node *, sem_item *> &ignored_nodes)
530 : : {
531 : 1679053 : gcc_assert (item->type == FUNC);
532 : 1679053 : cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
533 : 1679053 : cgraph_node *cnode2 = dyn_cast <cgraph_node *> (item->node);
534 : :
535 : 1679053 : m_compared_func = static_cast<sem_function *> (item);
536 : :
537 : 1679053 : if (cnode->thunk != cnode2->thunk)
538 : 0 : return return_false_with_msg ("thunk mismatch");
539 : 1679053 : if (cnode->former_thunk_p () != cnode2->former_thunk_p ())
540 : 4 : return return_false_with_msg ("former_thunk_p mismatch");
541 : :
542 : 1679049 : if ((cnode->thunk || cnode->former_thunk_p ())
543 : 1679049 : && 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 : 1679049 : if (DECL_FUNCTION_PERSONALITY (decl)
548 : 1679049 : != DECL_FUNCTION_PERSONALITY (item->decl))
549 : 0 : return return_false_with_msg ("function personalities are different");
550 : :
551 : 1679049 : if (DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl)
552 : 1679049 : != 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 : 1679049 : 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 : 1679049 : if (DECL_CXX_CONSTRUCTOR_P (decl) != DECL_CXX_CONSTRUCTOR_P (item->decl))
560 : 276 : return return_false_with_msg ("DECL_CXX_CONSTRUCTOR mismatch");
561 : :
562 : 1678773 : if (DECL_CXX_DESTRUCTOR_P (decl) != DECL_CXX_DESTRUCTOR_P (item->decl))
563 : 113 : 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 : 1678660 : if (flags_from_decl_or_type (decl) != flags_from_decl_or_type (item->decl))
570 : 114345 : 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 : 1564315 : if (DECL_CXX_CONSTRUCTOR_P (decl)
576 : 2527 : && opt_for_fn (decl, flag_devirtualize)
577 : 1566842 : && TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
578 : : {
579 : 2505 : if (TREE_CODE (TREE_TYPE (item->decl)) != METHOD_TYPE)
580 : 0 : return return_false_with_msg ("DECL_CXX_CONSTRUCTOR type mismatch");
581 : 2505 : else if (!func_checker::compatible_polymorphic_types_p
582 : 2505 : (TYPE_METHOD_BASETYPE (TREE_TYPE (decl)),
583 : 2505 : 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 : 1564315 : cl_target_option *tar1 = target_opts_for_fn (decl);
589 : 1564315 : cl_target_option *tar2 = target_opts_for_fn (item->decl);
590 : :
591 : 1564315 : 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 : 1564315 : cl_optimization *opt1 = opts_for_fn (decl);
603 : 1564315 : cl_optimization *opt2 = opts_for_fn (item->decl);
604 : :
605 : 1564315 : 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 : 1564315 : if (!func_checker::compatible_types_p
618 : 1564315 : (TREE_TYPE (TREE_TYPE (decl)),
619 : 1564315 : TREE_TYPE (TREE_TYPE (m_compared_func->decl))))
620 : 1031711 : return return_false_with_msg ("result types are different");
621 : :
622 : : /* Checking types of arguments. */
623 : 532604 : tree list1 = TYPE_ARG_TYPES (TREE_TYPE (decl)),
624 : 532604 : list2 = TYPE_ARG_TYPES (TREE_TYPE (m_compared_func->decl));
625 : 1682429 : for (unsigned i = 0; list1 && list2;
626 : 1149825 : list1 = TREE_CHAIN (list1), list2 = TREE_CHAIN (list2), i++)
627 : : {
628 : 1358518 : tree parm1 = TREE_VALUE (list1);
629 : 1358518 : tree parm2 = TREE_VALUE (list2);
630 : :
631 : : /* This guard is here for function pointer with attributes (pr59927.c). */
632 : 1358518 : 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 : 1358518 : if (!types_compatible_p (parm1, parm2))
638 : 208351 : return return_false_with_msg ("parameter types are not compatible");
639 : :
640 : 1150167 : if (!param_used_p (i))
641 : 48024 : continue;
642 : :
643 : : /* Perform additional checks for used parameters. */
644 : 1102143 : if (!compatible_parm_types_p (parm1, parm2))
645 : : return false;
646 : : }
647 : :
648 : 323911 : if (list1 || list2)
649 : 5 : return return_false_with_msg ("mismatched number of parameters");
650 : :
651 : 323906 : if (DECL_STATIC_CHAIN (decl) != DECL_STATIC_CHAIN (item->decl))
652 : 0 : return return_false_with_msg ("static chain mismatch");
653 : :
654 : 353898 : 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 : 323906 : if (comp_type_attributes (TREE_TYPE (decl),
660 : 323906 : TREE_TYPE (item->decl)) != 1)
661 : 163 : return return_false_with_msg ("different type attributes");
662 : 323743 : if (!attribute_list_equal (DECL_ATTRIBUTES (decl),
663 : 323743 : DECL_ATTRIBUTES (item->decl)))
664 : 1212 : 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 : 322531 : if (opt_for_fn (decl, flag_devirtualize)
669 : 322495 : && (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
670 : 301696 : || TREE_CODE (TREE_TYPE (item->decl)) == METHOD_TYPE)
671 : 20802 : && param_used_p (0)
672 : 337713 : && compare_polymorphic_p ())
673 : : {
674 : 11512 : if (TREE_CODE (TREE_TYPE (decl)) != TREE_CODE (TREE_TYPE (item->decl)))
675 : 80 : return return_false_with_msg ("METHOD_TYPE and FUNCTION_TYPE mismatch");
676 : 11432 : if (!func_checker::compatible_polymorphic_types_p
677 : 11432 : (TYPE_METHOD_BASETYPE (TREE_TYPE (decl)),
678 : 11432 : TYPE_METHOD_BASETYPE (TREE_TYPE (item->decl)), false))
679 : 0 : return return_false_with_msg ("THIS pointer ODR type mismatch");
680 : : }
681 : :
682 : 322451 : ipa_ref *ref = NULL, *ref2 = NULL;
683 : 351823 : for (unsigned i = 0; node->iterate_reference (i, ref); i++)
684 : : {
685 : 29515 : item->node->iterate_reference (i, ref2);
686 : :
687 : 29515 : if (ref->use != ref2->use)
688 : 0 : return return_false_with_msg ("reference use mismatch");
689 : :
690 : 29515 : if (!compare_symbol_references (ignored_nodes, ref->referred,
691 : : ref2->referred,
692 : 29515 : ref->address_matters_p ()))
693 : : return false;
694 : : }
695 : :
696 : 322308 : cgraph_edge *e1 = dyn_cast <cgraph_node *> (node)->callees;
697 : 322308 : cgraph_edge *e2 = dyn_cast <cgraph_node *> (item->node)->callees;
698 : :
699 : 463840 : while (e1 && e2)
700 : : {
701 : 354399 : if (!compare_symbol_references (ignored_nodes, e1->callee,
702 : 354399 : e2->callee, false))
703 : : return false;
704 : 141532 : if (!compare_edge_flags (e1, e2))
705 : : return false;
706 : :
707 : 141532 : e1 = e1->next_callee;
708 : 141532 : e2 = e2->next_callee;
709 : : }
710 : :
711 : 109441 : if (e1 || e2)
712 : 0 : return return_false_with_msg ("different number of calls");
713 : :
714 : 109441 : e1 = dyn_cast <cgraph_node *> (node)->indirect_calls;
715 : 109441 : e2 = dyn_cast <cgraph_node *> (item->node)->indirect_calls;
716 : :
717 : 113970 : while (e1 && e2)
718 : : {
719 : 4529 : if (!compare_edge_flags (e1, e2))
720 : : return false;
721 : :
722 : 4529 : e1 = e1->next_callee;
723 : 4529 : e2 = e2->next_callee;
724 : : }
725 : :
726 : 109441 : 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 : 2480207 : sem_item::update_hash_by_addr_refs (hash_map <symtab_node *,
742 : : sem_item *> &m_symtab_node_map)
743 : : {
744 : 2480207 : ipa_ref* ref;
745 : 2480207 : inchash::hash hstate (get_hash ());
746 : :
747 : 6868283 : for (unsigned i = 0; node->iterate_reference (i, ref); i++)
748 : : {
749 : 4388076 : hstate.add_int (ref->use);
750 : 4388076 : hash_referenced_symbol_properties (ref->referred, hstate,
751 : 4388076 : ref->use == IPA_REF_ADDR);
752 : 4388076 : if (ref->address_matters_p () || !m_symtab_node_map.get (ref->referred))
753 : 4228979 : hstate.add_int (ref->referred->ultimate_alias_target ()->order);
754 : : }
755 : :
756 : 2480207 : if (is_a <cgraph_node *> (node))
757 : : {
758 : 2537337 : for (cgraph_edge *e = dyn_cast <cgraph_node *> (node)->callers; e;
759 : 1544562 : e = e->next_caller)
760 : : {
761 : 1544562 : sem_item **result = m_symtab_node_map.get (e->callee);
762 : 1544562 : hash_referenced_symbol_properties (e->callee, hstate, false);
763 : 1544562 : if (!result)
764 : 0 : hstate.add_int (e->callee->ultimate_alias_target ()->order);
765 : : }
766 : : }
767 : :
768 : 2480207 : set_hash (hstate.end ());
769 : 2480207 : }
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 : 2480207 : sem_item::update_hash_by_local_refs (hash_map <symtab_node *,
777 : : sem_item *> &m_symtab_node_map)
778 : : {
779 : 2480207 : ipa_ref* ref;
780 : 2480207 : inchash::hash state (get_hash ());
781 : :
782 : 6868283 : for (unsigned j = 0; node->iterate_reference (j, ref); j++)
783 : : {
784 : 4388076 : sem_item **result = m_symtab_node_map.get (ref->referring);
785 : 4388076 : if (result)
786 : 4388076 : state.merge_hash ((*result)->get_hash ());
787 : : }
788 : :
789 : 2480207 : if (type == FUNC)
790 : : {
791 : 4769817 : for (cgraph_edge *e = dyn_cast <cgraph_node *> (node)->callees; e;
792 : 3777042 : e = e->next_callee)
793 : : {
794 : 3777042 : sem_item **result = m_symtab_node_map.get (e->caller);
795 : 3777042 : if (result)
796 : 3777042 : state.merge_hash ((*result)->get_hash ());
797 : : }
798 : : }
799 : :
800 : 2480207 : global_hash = state.end ();
801 : 2480207 : }
802 : :
803 : : /* Returns true if the item equals to ITEM given as argument. */
804 : :
805 : : bool
806 : 123874 : sem_function::equals (sem_item *item,
807 : : hash_map <symtab_node *, sem_item *> &)
808 : : {
809 : 123874 : gcc_assert (item->type == FUNC);
810 : 123874 : bool eq = equals_private (item);
811 : :
812 : 123874 : if (m_checker != NULL)
813 : : {
814 : 123874 : delete m_checker;
815 : 123874 : m_checker = NULL;
816 : : }
817 : :
818 : 123874 : 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 : 123874 : return eq;
826 : : }
827 : :
828 : : /* Processes function equality comparison. */
829 : :
830 : : bool
831 : 123874 : sem_function::equals_private (sem_item *item)
832 : : {
833 : 123874 : if (item->type != FUNC)
834 : : return false;
835 : :
836 : 123874 : basic_block bb1, bb2;
837 : 123874 : edge e1, e2;
838 : 123874 : edge_iterator ei1, ei2;
839 : 123874 : bool result = true;
840 : 123874 : tree arg1, arg2;
841 : :
842 : 123874 : m_compared_func = static_cast<sem_function *> (item);
843 : :
844 : 123874 : gcc_assert (decl != item->decl);
845 : :
846 : 247748 : if (bb_sorted.length () != m_compared_func->bb_sorted.length ()
847 : 123874 : || edge_count != m_compared_func->edge_count
848 : 247748 : || cfg_checksum != m_compared_func->cfg_checksum)
849 : 0 : return return_false ();
850 : :
851 : 247748 : m_checker = new func_checker (decl, m_compared_func->decl,
852 : : false,
853 : 247748 : opt_for_fn (m_compared_func->decl,
854 : : flag_strict_aliasing),
855 : : &refs_set,
856 : 123874 : &m_compared_func->refs_set);
857 : 123874 : arg1 = DECL_ARGUMENTS (decl);
858 : 123874 : arg2 = DECL_ARGUMENTS (m_compared_func->decl);
859 : 123874 : for (unsigned i = 0;
860 : 317673 : arg1 && arg2; arg1 = DECL_CHAIN (arg1), arg2 = DECL_CHAIN (arg2), i++)
861 : : {
862 : 194038 : if (!types_compatible_p (TREE_TYPE (arg1), TREE_TYPE (arg2)))
863 : 239 : return return_false_with_msg ("argument types are not compatible");
864 : 193799 : if (!param_used_p (i))
865 : 31210 : continue;
866 : : /* Perform additional checks for used parameters. */
867 : 162589 : if (!compatible_parm_types_p (TREE_TYPE (arg1), TREE_TYPE (arg2)))
868 : : return false;
869 : 162589 : if (!m_checker->compare_decl (arg1, arg2))
870 : 0 : return return_false ();
871 : : }
872 : 123635 : if (arg1 || arg2)
873 : 0 : return return_false_with_msg ("mismatched number of arguments");
874 : :
875 : 123635 : if (DECL_STATIC_CHAIN (decl) != DECL_STATIC_CHAIN (m_compared_func->decl))
876 : 0 : return return_false_with_msg ("static chain mismatch");
877 : :
878 : 247270 : if (!dyn_cast <cgraph_node *> (node)->has_gimple_body_p ())
879 : : return true;
880 : :
881 : : /* Fill-up label dictionary. */
882 : 1401492 : for (unsigned i = 0; i < bb_sorted.length (); ++i)
883 : : {
884 : 577111 : m_checker->parse_labels (bb_sorted[i]);
885 : 577111 : m_checker->parse_labels (m_compared_func->bb_sorted[i]);
886 : : }
887 : :
888 : : /* Checking all basic blocks. */
889 : 515489 : for (unsigned i = 0; i < bb_sorted.length (); ++i)
890 : 430783 : if(!m_checker->compare_bb (bb_sorted[i], m_compared_func->bb_sorted[i]))
891 : 38929 : return return_false ();
892 : :
893 : 84706 : auto_vec <int> bb_dict;
894 : :
895 : : /* Basic block edges check. */
896 : 946996 : for (unsigned i = 0; i < bb_sorted.length (); ++i)
897 : : {
898 : 388800 : bb1 = bb_sorted[i]->bb;
899 : 388800 : bb2 = m_compared_func->bb_sorted[i]->bb;
900 : :
901 : 388800 : ei2 = ei_start (bb2->preds);
902 : :
903 : 880524 : for (ei1 = ei_start (bb1->preds); ei_cond (ei1, &e1); ei_next (&ei1))
904 : : {
905 : 491732 : ei_cond (ei2, &e2);
906 : :
907 : 491732 : if (e1->flags != e2->flags)
908 : 0 : return return_false_with_msg ("flags comparison returns false");
909 : :
910 : 491732 : if (!bb_dict_test (&bb_dict, e1->src->index, e2->src->index))
911 : 8 : return return_false_with_msg ("edge comparison returns false");
912 : :
913 : 491724 : 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 : 491724 : if (!m_checker->compare_edge (e1, e2))
917 : 0 : return return_false_with_msg ("edge comparison returns false");
918 : :
919 : 491724 : ei_next (&ei2);
920 : : }
921 : : }
922 : :
923 : : /* Basic block PHI nodes comparison. */
924 : 473279 : for (unsigned i = 0; i < bb_sorted.length (); i++)
925 : 388573 : if (!compare_phi_node (bb_sorted[i]->bb, m_compared_func->bb_sorted[i]->bb))
926 : 33 : return return_false_with_msg ("PHI node comparison returns false");
927 : :
928 : : return result;
929 : 84706 : }
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 : 47503 : set_local (cgraph_node *node, void *data)
936 : : {
937 : 47503 : node->local = data != NULL;
938 : 47503 : 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 : 683 : set_addressable (varpool_node *node, void *)
946 : : {
947 : 683 : TREE_ADDRESSABLE (node->decl) = 1;
948 : 683 : return false;
949 : : }
950 : :
951 : : /* Clear DECL_RTL of NODE.
952 : : Helper for call_for_symbol_thunks_and_aliases. */
953 : :
954 : : static bool
955 : 25755 : clear_decl_rtl (symtab_node *node, void *)
956 : : {
957 : 25755 : SET_DECL_RTL (node->decl, NULL);
958 : 25755 : 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 : 16437 : redirect_all_callers (cgraph_node *n, cgraph_node *to)
966 : : {
967 : 16437 : int nredirected = 0;
968 : 16437 : ipa_ref *ref;
969 : 16437 : cgraph_edge *e = n->callers;
970 : :
971 : 16933 : 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 : 496 : if (!e->caller->thunk)
977 : : {
978 : 496 : struct cgraph_edge *nexte = e->next_caller;
979 : 496 : e->redirect_callee (to);
980 : 496 : e = nexte;
981 : 496 : nredirected++;
982 : : }
983 : : else
984 : 0 : e = e->next_callee;
985 : : }
986 : 16447 : 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 : 16437 : return nredirected;
1008 : : }
1009 : :
1010 : : /* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can
1011 : : be applied. */
1012 : :
1013 : : bool
1014 : 83834 : sem_function::merge (sem_item *alias_item)
1015 : : {
1016 : 83834 : gcc_assert (alias_item->type == FUNC);
1017 : :
1018 : 83834 : sem_function *alias_func = static_cast<sem_function *> (alias_item);
1019 : :
1020 : 83834 : cgraph_node *original = get_node ();
1021 : 83834 : cgraph_node *local_original = NULL;
1022 : 83834 : cgraph_node *alias = alias_func->get_node ();
1023 : :
1024 : 83834 : bool create_wrapper = false;
1025 : 83834 : bool create_alias = false;
1026 : 83834 : bool redirect_callers = false;
1027 : 83834 : bool remove = false;
1028 : :
1029 : 83834 : bool original_discardable = false;
1030 : 83834 : bool original_discarded = false;
1031 : :
1032 : 83834 : bool original_address_matters = original->address_matters_p ();
1033 : 83834 : bool alias_address_matters = alias->address_matters_p ();
1034 : :
1035 : 83834 : AUTO_DUMP_SCOPE ("merge",
1036 : : dump_user_location_t::from_function_decl (decl));
1037 : :
1038 : 83834 : 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 : 83727 : if (DECL_NO_INLINE_WARNING_P (original->decl)
1047 : 83727 : != DECL_NO_INLINE_WARNING_P (alias->decl))
1048 : : {
1049 : 412 : if (dump_enabled_p ())
1050 : 0 : dump_printf (MSG_MISSED_OPTIMIZATION,
1051 : : "Not unifying; DECL_NO_INLINE_WARNING mismatch.\n");
1052 : 412 : 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 : 83315 : if (((DECL_SECTION_NAME (original->decl) && !original->implicit_section)
1058 : 83315 : || (DECL_SECTION_NAME (alias->decl) && !alias->implicit_section))
1059 : 83315 : && 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 : 83315 : if (!original->in_same_comdat_group_p (alias)
1069 : 83315 : || original->comdat_local_p ())
1070 : : {
1071 : 12407 : 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 : 12407 : 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 : 70908 : 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 : 70908 : if (node->resolution != LDPR_UNKNOWN
1087 : 70908 : && !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 : 70908 : if ((original_address_matters && alias_address_matters)
1103 : 13498 : || (original_discardable
1104 : 0 : && (!DECL_COMDAT_GROUP (alias->decl)
1105 : 0 : || (DECL_COMDAT_GROUP (alias->decl)
1106 : 0 : != DECL_COMDAT_GROUP (original->decl))))
1107 : 13498 : || original_discarded
1108 : 13498 : || !sem_item::target_supports_symbol_aliases_p ()
1109 : 84406 : || 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 : 57410 : if (!sem_item::compare_referenced_symbol_properties (NULL, original, alias,
1117 : 57410 : 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 : 57403 : else if (DECL_COMDAT_GROUP (original->decl)
1129 : 0 : && DECL_COMDAT_GROUP (alias->decl)
1130 : 57403 : && (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 : 57403 : else if (DECL_STATIC_CHAIN (alias->decl)
1138 : 57403 : || 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 : 57399 : else if (stdarg_p (TREE_TYPE (alias->decl)))
1147 : : {
1148 : 1067 : if (dump_enabled_p ())
1149 : 0 : dump_printf (MSG_MISSED_OPTIMIZATION,
1150 : : "cannot create wrapper of stdarg function.\n");
1151 : : }
1152 : 56332 : else if (ipa_fn_summaries
1153 : 56332 : && ipa_size_summaries->get (alias) != NULL
1154 : 56322 : && 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 : 56321 : 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 : 57410 : redirect_callers
1175 : 57410 : = alias->get_availability () > AVAIL_INTERPOSABLE
1176 : 57410 : && original->get_availability () > AVAIL_INTERPOSABLE;
1177 : : /* TODO: We can redirect, but we need to produce alias of ORIGINAL
1178 : : with proper properties. */
1179 : 57410 : if (!sem_item::compare_referenced_symbol_properties (NULL, original, alias,
1180 : 57410 : alias->address_taken))
1181 : 7 : redirect_callers = false;
1182 : :
1183 : 57410 : 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 : 57388 : if (!original_discardable && !original->get_comdat_group ())
1199 : : {
1200 : 57387 : local_original
1201 : 57387 : = 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 : 57388 : if (original->comdat_local_p ())
1214 : 57388 : redirect_callers = false;
1215 : 57388 : 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 : 57387 : 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 : 57387 : if (!create_wrapper
1232 : 39111 : && !alias->call_for_symbol_and_aliases (cgraph_node::has_thunk_p,
1233 : : NULL, true)
1234 : 96498 : && !alias->can_remove_if_no_direct_calls_p ())
1235 : : {
1236 : 39111 : 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 : 39111 : return false;
1241 : : }
1242 : : }
1243 : : else
1244 : : create_alias = true;
1245 : :
1246 : 18276 : if (redirect_callers)
1247 : : {
1248 : 16427 : int nredirected = redirect_all_callers (alias, local_original);
1249 : :
1250 : 16427 : if (nredirected)
1251 : : {
1252 : 403 : alias->icf_merged = true;
1253 : 403 : local_original->icf_merged = true;
1254 : :
1255 : 403 : 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 : 16427 : if (alias->can_remove_if_no_direct_calls_p ()
1263 : 171 : && !DECL_VIRTUAL_P (alias->decl)
1264 : 16598 : && !alias->has_aliases_p ())
1265 : : {
1266 : : create_wrapper = false;
1267 : : remove = true;
1268 : : }
1269 : : gcc_assert (!create_alias);
1270 : : }
1271 : 15347 : else if (create_alias)
1272 : : {
1273 : 13498 : alias->icf_merged = true;
1274 : :
1275 : : /* Remove the function's body. */
1276 : 13498 : ipa_merge_profiles (original, alias);
1277 : 13498 : symtab->call_cgraph_removal_hooks (alias);
1278 : 13498 : alias->release_body (true);
1279 : 13498 : alias->reset ();
1280 : : /* Notice global symbol possibly produced RTL. */
1281 : 13498 : ((symtab_node *)alias)->call_for_symbol_and_aliases (clear_decl_rtl,
1282 : : NULL, true);
1283 : :
1284 : : /* Create the alias. */
1285 : 13498 : cgraph_node::create_alias (alias_func->decl, decl);
1286 : 13498 : alias->resolve_alias (original);
1287 : :
1288 : 13498 : original->call_for_symbol_thunks_and_aliases
1289 : 13498 : (set_local, (void *)(size_t) original->local_p (), true);
1290 : :
1291 : 13498 : if (dump_enabled_p ())
1292 : 20 : dump_printf (MSG_OPTIMIZED_LOCATIONS,
1293 : : "Unified; Function alias has been created.\n");
1294 : : }
1295 : 31774 : if (create_wrapper)
1296 : : {
1297 : 18105 : gcc_assert (!create_alias);
1298 : 18105 : alias->icf_merged = true;
1299 : 18105 : symtab->call_cgraph_removal_hooks (alias);
1300 : 18105 : local_original->icf_merged = true;
1301 : :
1302 : : /* FIXME update local_original counts. */
1303 : 18105 : ipa_merge_profiles (original, alias, true);
1304 : 18105 : alias->create_wrapper (local_original);
1305 : 18105 : symtab->call_cgraph_insertion_hooks (alias);
1306 : :
1307 : 18105 : 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 : 31774 : gcc_assert (alias->icf_merged || remove || redirect_callers);
1315 : 31774 : 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 : 31774 : 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 : 31774 : if (remove)
1330 : : {
1331 : 171 : ipa_merge_profiles (original, alias);
1332 : 171 : alias->release_body ();
1333 : 171 : alias->reset ();
1334 : 171 : alias->body_removed = true;
1335 : 171 : alias->icf_merged = true;
1336 : 171 : 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 : 1102497 : sem_function::init (ipa_icf_gimple::func_checker *checker)
1348 : : {
1349 : 1102497 : m_checker = checker;
1350 : 1102497 : if (in_lto_p)
1351 : 65302 : get_node ()->get_untransformed_body ();
1352 : :
1353 : 1102497 : tree fndecl = node->decl;
1354 : 1102497 : function *func = DECL_STRUCT_FUNCTION (fndecl);
1355 : :
1356 : 1102497 : gcc_assert (func);
1357 : 1102497 : gcc_assert (SSANAMES (func));
1358 : :
1359 : 1102497 : ssa_names_size = SSANAMES (func)->length ();
1360 : :
1361 : 1102497 : decl = fndecl;
1362 : 1102497 : region_tree = func->eh->region_tree;
1363 : :
1364 : : /* iterating all function arguments. */
1365 : 1102497 : arg_count = count_formal_params (fndecl);
1366 : :
1367 : 1102497 : edge_count = n_edges_for_fn (func);
1368 : 1102497 : cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
1369 : 1102497 : if (!cnode->thunk)
1370 : : {
1371 : 1102497 : cfg_checksum = coverage_compute_cfg_checksum (func);
1372 : :
1373 : 1102497 : inchash::hash hstate;
1374 : :
1375 : 1102497 : basic_block bb;
1376 : 7799174 : FOR_EACH_BB_FN (bb, func)
1377 : : {
1378 : 6696677 : unsigned nondbg_stmt_count = 0;
1379 : :
1380 : 6696677 : edge e;
1381 : 15630450 : for (edge_iterator ei = ei_start (bb->preds); ei_cond (ei, &e);
1382 : 8933773 : ei_next (&ei))
1383 : 8933773 : 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 : 6696677 : gphi_iterator si;
1390 : 7829686 : for (si = gsi_start_nonvirtual_phis (bb); !gsi_end_p (si);
1391 : 1133009 : gsi_next_nonvirtual_phi (&si))
1392 : : {
1393 : 1133009 : hstate.add_int (GIMPLE_PHI);
1394 : 1133009 : gphi *phi = si.phi ();
1395 : 1133009 : m_checker->hash_operand (gimple_phi_result (phi), hstate, 0,
1396 : : func_checker::OP_NORMAL);
1397 : 1133009 : hstate.add_int (gimple_phi_num_args (phi));
1398 : 3881061 : for (unsigned int i = 0; i < gimple_phi_num_args (phi); i++)
1399 : 2748052 : m_checker->hash_operand (gimple_phi_arg_def (phi, i),
1400 : : hstate, 0, func_checker::OP_NORMAL);
1401 : : }
1402 : :
1403 : 56266705 : for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
1404 : 42873351 : gsi_next (&gsi))
1405 : : {
1406 : 42873351 : gimple *stmt = gsi_stmt (gsi);
1407 : :
1408 : 42873351 : if (gimple_code (stmt) != GIMPLE_DEBUG
1409 : 42873351 : && gimple_code (stmt) != GIMPLE_PREDICT)
1410 : : {
1411 : 21057132 : hash_stmt (stmt, hstate);
1412 : 21057132 : nondbg_stmt_count++;
1413 : : }
1414 : : }
1415 : :
1416 : 6696677 : hstate.commit_flag ();
1417 : 6696677 : gcode_hash = hstate.end ();
1418 : 6696677 : bb_sizes.safe_push (nondbg_stmt_count);
1419 : :
1420 : : /* Inserting basic block to hash table. */
1421 : 6696677 : sem_bb *semantic_bb = new sem_bb (bb, nondbg_stmt_count,
1422 : 6696677 : EDGE_COUNT (bb->preds)
1423 : 20080909 : + EDGE_COUNT (bb->succs));
1424 : :
1425 : 6696677 : 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 : 1102497 : m_checker = NULL;
1435 : 1102497 : }
1436 : :
1437 : : /* Improve accumulated hash for HSTATE based on a gimple statement STMT. */
1438 : :
1439 : : void
1440 : 21057132 : sem_function::hash_stmt (gimple *stmt, inchash::hash &hstate)
1441 : : {
1442 : 21057132 : enum gimple_code code = gimple_code (stmt);
1443 : :
1444 : 21057132 : hstate.add_int (code);
1445 : :
1446 : 21057132 : switch (code)
1447 : : {
1448 : 21481 : case GIMPLE_SWITCH:
1449 : 21481 : m_checker->hash_operand (gimple_switch_index (as_a <gswitch *> (stmt)),
1450 : : hstate, 0, func_checker::OP_NORMAL);
1451 : 21481 : break;
1452 : 12990780 : case GIMPLE_ASSIGN:
1453 : 12990780 : hstate.add_int (gimple_assign_rhs_code (stmt));
1454 : : /* fall through */
1455 : 20558572 : case GIMPLE_CALL:
1456 : 20558572 : case GIMPLE_ASM:
1457 : 20558572 : case GIMPLE_COND:
1458 : 20558572 : case GIMPLE_GOTO:
1459 : 20558572 : case GIMPLE_RETURN:
1460 : 20558572 : {
1461 : 20558572 : func_checker::operand_access_type_map map (5);
1462 : 20558572 : func_checker::classify_operands (stmt, &map);
1463 : :
1464 : : /* All these statements are equivalent if their operands are. */
1465 : 82076984 : for (unsigned i = 0; i < gimple_num_ops (stmt); ++i)
1466 : : {
1467 : 61518412 : func_checker::operand_access_type
1468 : : access_type = func_checker::get_operand_access_type
1469 : 61518412 : (&map, gimple_op (stmt, i));
1470 : 61518412 : 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 : 61518412 : if (access_type == func_checker::OP_MEMORY
1476 : 8202927 : && lto_streaming_expected_p ()
1477 : 61832938 : && flag_strict_aliasing)
1478 : : {
1479 : 314058 : ao_ref ref;
1480 : :
1481 : 314058 : ao_ref_init (&ref, gimple_op (stmt, i));
1482 : 314058 : tree t = ao_ref_alias_ptr_type (&ref);
1483 : 314058 : if (!variably_modified_type_p (t, NULL_TREE))
1484 : 314030 : memory_access_types.safe_push (t);
1485 : 314058 : t = ao_ref_base_alias_ptr_type (&ref);
1486 : 314058 : if (!variably_modified_type_p (t, NULL_TREE))
1487 : 313661 : memory_access_types.safe_push (t);
1488 : : }
1489 : : }
1490 : : /* Consider nocf_check attribute in hash as it affects code
1491 : : generation. */
1492 : 20558572 : if (code == GIMPLE_CALL
1493 : 3963688 : && flag_cf_protection & CF_BRANCH)
1494 : 1785607 : hstate.add_flag (gimple_call_nocf_check_p (as_a <gcall *> (stmt)));
1495 : 20558572 : }
1496 : 20558572 : break;
1497 : : default:
1498 : : break;
1499 : : }
1500 : 21057132 : }
1501 : :
1502 : :
1503 : : /* Return true if polymorphic comparison must be processed. */
1504 : :
1505 : : bool
1506 : 71230 : sem_function::compare_polymorphic_p (void)
1507 : : {
1508 : 71230 : struct cgraph_edge *e;
1509 : :
1510 : 142460 : if (!opt_for_fn (get_node ()->decl, flag_devirtualize))
1511 : : return false;
1512 : 142460 : 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 : 158537 : for (e = get_node ()->callees; e; e = e->next_callee)
1517 : 76007 : if (e->callee->definition
1518 : 76007 : && 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 : 1053164 : sem_function::parse (cgraph_node *node, bitmap_obstack *stack,
1528 : : func_checker *checker)
1529 : : {
1530 : 1053164 : tree fndecl = node->decl;
1531 : 1053164 : function *func = DECL_STRUCT_FUNCTION (fndecl);
1532 : :
1533 : 1053164 : if (!func || (!node->has_gimple_body_p () && !node->thunk))
1534 : : return NULL;
1535 : :
1536 : 992666 : if (lookup_attribute_by_prefix ("omp ", DECL_ATTRIBUTES (node->decl)) != NULL)
1537 : : return NULL;
1538 : :
1539 : 971712 : if (lookup_attribute_by_prefix ("oacc ",
1540 : 971712 : DECL_ATTRIBUTES (node->decl)) != NULL)
1541 : : return NULL;
1542 : :
1543 : : /* PR ipa/70306. */
1544 : 971712 : if (DECL_STATIC_CONSTRUCTOR (node->decl)
1545 : 971712 : || DECL_STATIC_DESTRUCTOR (node->decl))
1546 : : return NULL;
1547 : :
1548 : 964410 : sem_function *f = new sem_function (node, stack);
1549 : 964410 : f->init (checker);
1550 : :
1551 : 964410 : 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 : 388573 : sem_function::compare_phi_node (basic_block bb1, basic_block bb2)
1559 : : {
1560 : 388573 : gphi_iterator si1, si2;
1561 : 388573 : gphi *phi1, *phi2;
1562 : 388573 : unsigned size1, size2, i;
1563 : 388573 : tree t1, t2;
1564 : 388573 : edge e1, e2;
1565 : :
1566 : 388573 : gcc_assert (bb1 != NULL);
1567 : 388573 : gcc_assert (bb2 != NULL);
1568 : :
1569 : 388573 : si2 = gsi_start_nonvirtual_phis (bb2);
1570 : 411188 : for (si1 = gsi_start_nonvirtual_phis (bb1); !gsi_end_p (si1);
1571 : 22615 : gsi_next_nonvirtual_phi (&si1))
1572 : : {
1573 : 22648 : if (gsi_end_p (si1) && gsi_end_p (si2))
1574 : : break;
1575 : :
1576 : 22648 : if (gsi_end_p (si1) || gsi_end_p (si2))
1577 : 0 : return return_false();
1578 : :
1579 : 22648 : phi1 = si1.phi ();
1580 : 22648 : phi2 = si2.phi ();
1581 : :
1582 : 22648 : tree phi_result1 = gimple_phi_result (phi1);
1583 : 22648 : tree phi_result2 = gimple_phi_result (phi2);
1584 : :
1585 : 22648 : 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 : 22647 : size1 = gimple_phi_num_args (phi1);
1590 : 22647 : size2 = gimple_phi_num_args (phi2);
1591 : :
1592 : 22647 : 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 : 73348 : for (i = 0; i < size1; ++i)
1598 : : {
1599 : 50733 : t1 = gimple_phi_arg (phi1, i)->def;
1600 : 50733 : t2 = gimple_phi_arg (phi2, i)->def;
1601 : :
1602 : 50733 : if (!m_checker->compare_operand (t1, t2, func_checker::OP_NORMAL))
1603 : 32 : return return_false ();
1604 : :
1605 : 50701 : e1 = gimple_phi_arg_edge (phi1, i);
1606 : 50701 : e2 = gimple_phi_arg_edge (phi2, i);
1607 : :
1608 : 50701 : if (!m_checker->compare_edge (e1, e2))
1609 : 0 : return return_false ();
1610 : : }
1611 : :
1612 : 22615 : 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 : 983456 : sem_function::bb_dict_test (vec<int> *bb_dict, int source, int target)
1623 : : {
1624 : 983456 : source++;
1625 : 983456 : target++;
1626 : :
1627 : 983456 : if (bb_dict->length () <= (unsigned)source)
1628 : 293821 : bb_dict->safe_grow_cleared (source + 1, true);
1629 : :
1630 : 983456 : if ((*bb_dict)[source] == 0)
1631 : : {
1632 : 311783 : (*bb_dict)[source] = target;
1633 : 311783 : return true;
1634 : : }
1635 : : else
1636 : 671673 : return (*bb_dict)[source] == target;
1637 : : }
1638 : :
1639 : 2289194 : sem_variable::sem_variable (varpool_node *node, bitmap_obstack *stack)
1640 : 2289194 : : sem_item (VAR, node, stack)
1641 : : {
1642 : 2289194 : gcc_checking_assert (node);
1643 : 2289194 : gcc_checking_assert (get_node ());
1644 : 2289194 : }
1645 : :
1646 : : /* Fast equality function based on knowledge known in WPA. */
1647 : :
1648 : : bool
1649 : 439407 : sem_variable::equals_wpa (sem_item *item,
1650 : : hash_map <symtab_node *, sem_item *> &ignored_nodes)
1651 : : {
1652 : 439407 : gcc_assert (item->type == VAR);
1653 : :
1654 : 623887 : if (node->num_references () != item->node->num_references ())
1655 : 0 : return return_false_with_msg ("different number of references");
1656 : :
1657 : 439407 : 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 : 439407 : if (DECL_VIRTUAL_P (decl) != DECL_VIRTUAL_P (item->decl))
1664 : 0 : return return_false_with_msg ("Virtual flag mismatch");
1665 : :
1666 : 439407 : if (DECL_SIZE (decl) != DECL_SIZE (item->decl)
1667 : 439407 : && ((!DECL_SIZE (decl) || !DECL_SIZE (item->decl))
1668 : 14168 : || !operand_equal_p (DECL_SIZE (decl),
1669 : 14168 : DECL_SIZE (item->decl), OEP_ONLY_CONST)))
1670 : 14168 : 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 : 831257 : if (((DECL_SECTION_NAME (decl) && !node->implicit_section)
1675 : 425238 : || (DECL_SECTION_NAME (item->decl) && !item->node->implicit_section))
1676 : 425240 : && DECL_SECTION_NAME (decl) != DECL_SECTION_NAME (item->decl))
1677 : 1 : return return_false_with_msg ("user section mismatch");
1678 : :
1679 : 425238 : if (DECL_IN_TEXT_SECTION (decl) != DECL_IN_TEXT_SECTION (item->decl))
1680 : 0 : return return_false_with_msg ("text section");
1681 : :
1682 : 425238 : if (TYPE_ADDR_SPACE (TREE_TYPE (decl))
1683 : 425238 : != TYPE_ADDR_SPACE (TREE_TYPE (item->decl)))
1684 : 0 : return return_false_with_msg ("address-space");
1685 : :
1686 : 425238 : ipa_ref *ref = NULL, *ref2 = NULL;
1687 : 547758 : for (unsigned i = 0; node->iterate_reference (i, ref); i++)
1688 : : {
1689 : 122720 : item->node->iterate_reference (i, ref2);
1690 : :
1691 : 122720 : if (ref->use != ref2->use)
1692 : 0 : return return_false_with_msg ("reference use mismatch");
1693 : :
1694 : 122720 : if (!compare_symbol_references (ignored_nodes,
1695 : : ref->referred, ref2->referred,
1696 : 122720 : 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 : 467327 : sem_variable::equals (sem_item *item,
1707 : : hash_map <symtab_node *, sem_item *> &)
1708 : : {
1709 : 467327 : gcc_assert (item->type == VAR);
1710 : 467327 : bool ret;
1711 : :
1712 : 467327 : if (DECL_INITIAL (decl) == error_mark_node && in_lto_p)
1713 : 140 : dyn_cast <varpool_node *>(node)->get_constructor ();
1714 : 467327 : 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 : 467327 : if (!func_checker::compatible_types_p (TREE_TYPE (decl),
1719 : 467327 : TREE_TYPE (item->decl)))
1720 : 46627 : return return_false_with_msg ("variables types are different");
1721 : :
1722 : 420700 : ret = sem_variable::equals (DECL_INITIAL (decl),
1723 : 420700 : DECL_INITIAL (item->node->decl));
1724 : 420700 : 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 : 1963138 : sem_variable::equals (tree t1, tree t2)
1737 : : {
1738 : 2344898 : if (!t1 || !t2)
1739 : 2070 : return return_with_debug (t1 == t2);
1740 : 2342828 : if (t1 == t2)
1741 : : return true;
1742 : 1095039 : tree_code tc1 = TREE_CODE (t1);
1743 : 1095039 : tree_code tc2 = TREE_CODE (t2);
1744 : :
1745 : 1095039 : if (tc1 != tc2)
1746 : 0 : return return_false_with_msg ("TREE_CODE mismatch");
1747 : :
1748 : 1095039 : switch (tc1)
1749 : : {
1750 : 415680 : case CONSTRUCTOR:
1751 : 415680 : {
1752 : 415680 : vec<constructor_elt, va_gc> *v1, *v2;
1753 : 415680 : unsigned HOST_WIDE_INT idx;
1754 : :
1755 : 415680 : enum tree_code typecode = TREE_CODE (TREE_TYPE (t1));
1756 : 415680 : if (typecode != TREE_CODE (TREE_TYPE (t2)))
1757 : 0 : return return_false_with_msg ("constructor type mismatch");
1758 : :
1759 : 415680 : if (typecode == ARRAY_TYPE)
1760 : : {
1761 : 166802 : HOST_WIDE_INT size_1 = int_size_in_bytes (TREE_TYPE (t1));
1762 : : /* For arrays, check that the sizes all match. */
1763 : 166802 : if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2))
1764 : 166802 : || size_1 == -1
1765 : 333604 : || size_1 != int_size_in_bytes (TREE_TYPE (t2)))
1766 : 0 : return return_false_with_msg ("constructor array size mismatch");
1767 : : }
1768 : 248878 : else if (!func_checker::compatible_types_p (TREE_TYPE (t1),
1769 : 248878 : TREE_TYPE (t2)))
1770 : 0 : return return_false_with_msg ("constructor type incompatible");
1771 : :
1772 : 415680 : v1 = CONSTRUCTOR_ELTS (t1);
1773 : 415680 : v2 = CONSTRUCTOR_ELTS (t2);
1774 : 1124582 : if (vec_safe_length (v1) != vec_safe_length (v2))
1775 : 0 : return return_false_with_msg ("constructor number of elts mismatch");
1776 : :
1777 : 1145262 : for (idx = 0; idx < vec_safe_length (v1); ++idx)
1778 : : {
1779 : 732172 : constructor_elt *c1 = &(*v1)[idx];
1780 : 732172 : constructor_elt *c2 = &(*v2)[idx];
1781 : :
1782 : : /* Check that each value is the same... */
1783 : 732172 : if (!sem_variable::equals (c1->value, c2->value))
1784 : : return false;
1785 : : /* ... and that they apply to the same fields! */
1786 : 732172 : 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 : 381004 : case ADDR_EXPR:
1807 : 381004 : case FDESC_EXPR:
1808 : 381004 : {
1809 : 381004 : tree op1 = TREE_OPERAND (t1, 0);
1810 : 381004 : tree op2 = TREE_OPERAND (t2, 0);
1811 : 381004 : 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 : 660 : case INTEGER_CST:
1827 : : /* Integer constants are the same only if the same width of type. */
1828 : 660 : if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2)))
1829 : 69 : 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 : 263641 : case STRING_CST:
1834 : 263641 : if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2)))
1835 : 0 : return return_false_with_msg ("STRING_CST mode mismatch");
1836 : 263641 : if (TREE_STRING_LENGTH (t1) != TREE_STRING_LENGTH (t2))
1837 : 0 : return return_false_with_msg ("STRING_CST length mismatch");
1838 : 263641 : if (memcmp (TREE_STRING_POINTER (t1), TREE_STRING_POINTER (t2),
1839 : 263641 : 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 : 10302 : case REAL_CST:
1853 : : /* Real constants are the same only if the same width of type. */
1854 : 10302 : if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2)))
1855 : 0 : return return_false_with_msg ("REAL_CST precision mismatch");
1856 : 10302 : 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 : 18323 : case ARRAY_REF:
1873 : 18323 : case ARRAY_RANGE_REF:
1874 : 18323 : {
1875 : 18323 : tree x1 = TREE_OPERAND (t1, 0);
1876 : 18323 : tree x2 = TREE_OPERAND (t2, 0);
1877 : 18323 : tree y1 = TREE_OPERAND (t1, 1);
1878 : 18323 : tree y2 = TREE_OPERAND (t2, 1);
1879 : :
1880 : 18323 : if (!sem_variable::equals (x1, x2) || !sem_variable::equals (y1, y2))
1881 : 0 : return false;
1882 : 18323 : if (!sem_variable::equals (array_ref_low_bound (t1),
1883 : : array_ref_low_bound (t2)))
1884 : : return false;
1885 : 18323 : if (!sem_variable::equals (array_ref_element_size (t1),
1886 : : array_ref_element_size (t2)))
1887 : : return false;
1888 : : return true;
1889 : : }
1890 : :
1891 : 49 : case COMPONENT_REF:
1892 : 49 : case POINTER_PLUS_EXPR:
1893 : 49 : case PLUS_EXPR:
1894 : 49 : case MINUS_EXPR:
1895 : 49 : case RANGE_EXPR:
1896 : 49 : {
1897 : 49 : tree x1 = TREE_OPERAND (t1, 0);
1898 : 49 : tree x2 = TREE_OPERAND (t2, 0);
1899 : 49 : tree y1 = TREE_OPERAND (t1, 1);
1900 : 49 : tree y2 = TREE_OPERAND (t2, 1);
1901 : :
1902 : 49 : return sem_variable::equals (x1, x2) && sem_variable::equals (y1, y2);
1903 : : }
1904 : :
1905 : 756 : CASE_CONVERT:
1906 : 756 : case VIEW_CONVERT_EXPR:
1907 : 756 : if (!func_checker::compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2)))
1908 : 0 : return return_false ();
1909 : 756 : 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 : 2333929 : sem_variable::parse (varpool_node *node, bitmap_obstack *stack,
1921 : : func_checker *checker)
1922 : : {
1923 : 2269719 : if (TREE_THIS_VOLATILE (node->decl) || DECL_HARD_REGISTER (node->decl)
1924 : 4603596 : || node->alias)
1925 : : return NULL;
1926 : :
1927 : 2269582 : sem_variable *v = new sem_variable (node, stack);
1928 : 2269582 : v->init (checker);
1929 : :
1930 : 2269582 : return v;
1931 : : }
1932 : :
1933 : : /* Semantic variable initialization function. */
1934 : :
1935 : : void
1936 : 2775054 : sem_variable::init (ipa_icf_gimple::func_checker *checker)
1937 : : {
1938 : 2775054 : 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 : 2775054 : if (!m_hash_set)
1944 : : {
1945 : 2269582 : gcc_assert (!node->lto_file_data);
1946 : 2269582 : inchash::hash hstate;
1947 : 2269582 : hstate.add_int (456346417);
1948 : 2269582 : checker->hash_operand (DECL_INITIAL (decl), hstate, 0);
1949 : 2269582 : set_hash (hstate.end ());
1950 : : }
1951 : 2775054 : }
1952 : :
1953 : : /* References independent hash function. */
1954 : :
1955 : : hashval_t
1956 : 8775798 : sem_variable::get_hash (void)
1957 : : {
1958 : 8775798 : gcc_checking_assert (m_hash_set);
1959 : 8775798 : 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 : 418087 : sem_variable::merge (sem_item *alias_item)
1967 : : {
1968 : 418087 : gcc_assert (alias_item->type == VAR);
1969 : :
1970 : 418087 : AUTO_DUMP_SCOPE ("merge",
1971 : : dump_user_location_t::from_function_decl (decl));
1972 : 418087 : 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 : 418087 : 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 : 418087 : sem_variable *alias_var = static_cast<sem_variable *> (alias_item);
1989 : :
1990 : 418087 : varpool_node *original = get_node ();
1991 : 418087 : varpool_node *alias = alias_var->get_node ();
1992 : 418087 : bool original_discardable = false;
1993 : :
1994 : 418087 : 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 : 418087 : if (original->can_be_discarded_p ()
2002 : 418087 : || (node->resolution != LDPR_UNKNOWN
2003 : 416466 : && !decl_binds_to_current_def_p (node->decl)))
2004 : : original_discardable = true;
2005 : :
2006 : 418087 : 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 : 418087 : if (DECL_IN_CONSTANT_POOL (alias->decl)
2014 : 418087 : || 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 : 820557 : if (((DECL_SECTION_NAME (original->decl) && !original->implicit_section)
2025 : 418084 : || (DECL_SECTION_NAME (alias->decl) && !alias->implicit_section))
2026 : 418084 : && 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 : 418084 : if (alias_address_matters && flag_merge_constants < 2)
2037 : : {
2038 : 405761 : if (dump_enabled_p ())
2039 : 1 : dump_printf (MSG_MISSED_OPTIMIZATION,
2040 : : "Not unifying; address of original may be compared.\n");
2041 : 405761 : return false;
2042 : : }
2043 : :
2044 : 12323 : if (DECL_ALIGN (original->decl) != DECL_ALIGN (alias->decl)
2045 : 12323 : && (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 : 12309 : 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 : 12309 : if (DECL_COMDAT_GROUP (original->decl) != DECL_COMDAT_GROUP (alias->decl))
2067 : : {
2068 : 84 : 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 : 84 : return false;
2074 : : }
2075 : :
2076 : 12225 : 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 : 12221 : gcc_assert (!original->alias);
2088 : 12221 : gcc_assert (!alias->alias);
2089 : :
2090 : 12221 : alias->analyzed = false;
2091 : :
2092 : 12221 : DECL_INITIAL (alias->decl) = NULL;
2093 : 12221 : ((symtab_node *)alias)->call_for_symbol_and_aliases (clear_decl_rtl,
2094 : : NULL, true);
2095 : 12221 : alias->remove_all_references ();
2096 : 12221 : if (TREE_ADDRESSABLE (alias->decl))
2097 : 395 : original->call_for_symbol_and_aliases (set_addressable, NULL, true);
2098 : :
2099 : 12221 : varpool_node::create_alias (alias_var->decl, decl);
2100 : 12221 : alias->resolve_alias (original);
2101 : :
2102 : 12221 : if (dump_enabled_p ())
2103 : 17 : dump_printf (MSG_OPTIMIZED_LOCATIONS,
2104 : : "Unified; Variable alias has been created.\n");
2105 : :
2106 : 12221 : 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 : 137484 : sem_item_optimizer::sem_item_optimizer ()
2124 : 137484 : : worklist (0), m_classes (0), m_classes_count (0), m_cgraph_node_hooks (NULL),
2125 : 137484 : m_varpool_node_hooks (NULL), m_merged_variables (), m_references ()
2126 : : {
2127 : 137484 : m_items.create (0);
2128 : 137484 : bitmap_obstack_initialize (&m_bmstack);
2129 : 137484 : }
2130 : :
2131 : 128583 : sem_item_optimizer::~sem_item_optimizer ()
2132 : : {
2133 : 2608790 : for (unsigned int i = 0; i < m_items.length (); i++)
2134 : 2480207 : delete m_items[i];
2135 : :
2136 : :
2137 : 2010171 : for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
2138 : 3891759 : it != m_classes.end (); ++it)
2139 : : {
2140 : 3859131 : for (unsigned int i = 0; i < (*it)->classes.length (); i++)
2141 : 3955086 : delete (*it)->classes[i];
2142 : :
2143 : 1881588 : (*it)->classes.release ();
2144 : 1881588 : free (*it);
2145 : : }
2146 : :
2147 : 128583 : m_items.release ();
2148 : :
2149 : 128583 : bitmap_obstack_release (&m_bmstack);
2150 : 128583 : m_merged_variables.release ();
2151 : 128583 : }
2152 : :
2153 : : /* Write IPA ICF summary for symbols. */
2154 : :
2155 : : void
2156 : 19421 : sem_item_optimizer::write_summary (void)
2157 : : {
2158 : 19421 : unsigned int count = 0;
2159 : :
2160 : 19421 : output_block *ob = create_output_block (LTO_section_ipa_icf);
2161 : 19421 : lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
2162 : 19421 : ob->symbol = NULL;
2163 : :
2164 : : /* Calculate number of symbols to be serialized. */
2165 : 19421 : for (lto_symtab_encoder_iterator lsei = lsei_start_in_partition (encoder);
2166 : 365433 : !lsei_end_p (lsei);
2167 : 346012 : lsei_next_in_partition (&lsei))
2168 : : {
2169 : 346012 : symtab_node *node = dyn_cast <symtab_node *> (lsei_node (lsei));
2170 : 346012 : if (!node)
2171 : 0 : continue;
2172 : :
2173 : 346012 : if (m_symtab_node_map.get (node))
2174 : 322283 : count++;
2175 : : }
2176 : :
2177 : 19421 : streamer_write_uhwi (ob, count);
2178 : :
2179 : : /* Process all of the symbols. */
2180 : 19421 : for (lto_symtab_encoder_iterator lsei = lsei_start_in_partition (encoder);
2181 : 365433 : !lsei_end_p (lsei);
2182 : 346012 : lsei_next_in_partition (&lsei))
2183 : : {
2184 : 346012 : symtab_node *node = dyn_cast <symtab_node *> (lsei_node (lsei));
2185 : 346012 : if (!node)
2186 : 0 : continue;
2187 : :
2188 : 346012 : sem_item **item = m_symtab_node_map.get (node);
2189 : :
2190 : 346012 : if (item && *item)
2191 : : {
2192 : 322283 : int node_ref = lto_symtab_encoder_encode (encoder, node);
2193 : 322283 : streamer_write_uhwi_stream (ob->main_stream, node_ref);
2194 : :
2195 : 322283 : streamer_write_uhwi (ob, (*item)->get_hash ());
2196 : :
2197 : 322283 : if ((*item)->type == FUNC)
2198 : : {
2199 : 90813 : sem_function *fn = static_cast<sem_function *> (*item);
2200 : 90813 : streamer_write_uhwi (ob, fn->memory_access_types.length ());
2201 : 963681 : for (unsigned i = 0; i < fn->memory_access_types.length (); i++)
2202 : 617669 : stream_write_tree (ob, fn->memory_access_types[i], true);
2203 : : }
2204 : : }
2205 : : }
2206 : :
2207 : 19421 : streamer_write_char_stream (ob->main_stream, 0);
2208 : 19421 : produce_asm (ob);
2209 : 19421 : destroy_output_block (ob);
2210 : 19421 : }
2211 : :
2212 : : /* Reads a section from LTO stream file FILE_DATA. Input block for DATA
2213 : : contains LEN bytes. */
2214 : :
2215 : : void
2216 : 10613 : sem_item_optimizer::read_section (lto_file_decl_data *file_data,
2217 : : const char *data, size_t len)
2218 : : {
2219 : 10613 : const lto_function_header *header
2220 : : = (const lto_function_header *) data;
2221 : 10613 : const int cfg_offset = sizeof (lto_function_header);
2222 : 10613 : const int main_offset = cfg_offset + header->cfg_size;
2223 : 10613 : const int string_offset = main_offset + header->main_size;
2224 : 10613 : data_in *data_in;
2225 : 10613 : unsigned int i;
2226 : 10613 : unsigned int count;
2227 : :
2228 : 10613 : lto_input_block ib_main ((const char *) data + main_offset, 0,
2229 : 10613 : header->main_size, file_data);
2230 : :
2231 : 10613 : data_in
2232 : 21226 : = lto_data_in_create (file_data, (const char *) data + string_offset,
2233 : 10613 : header->string_size, vNULL);
2234 : :
2235 : 10613 : count = streamer_read_uhwi (&ib_main);
2236 : :
2237 : 106426 : for (i = 0; i < count; i++)
2238 : : {
2239 : 95813 : unsigned int index;
2240 : 95813 : toplevel_node *node;
2241 : 95813 : lto_symtab_encoder_t encoder;
2242 : :
2243 : 95813 : index = streamer_read_uhwi (&ib_main);
2244 : 95813 : encoder = file_data->symtab_node_encoder;
2245 : 95813 : node = lto_symtab_encoder_deref (encoder, index);
2246 : :
2247 : 95813 : hashval_t hash = streamer_read_uhwi (&ib_main);
2248 : 95813 : if (symtab_node *snode = dyn_cast <symtab_node *> (node))
2249 : 95813 : gcc_assert (snode->definition);
2250 : :
2251 : 95813 : if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node))
2252 : : {
2253 : 76201 : sem_function *fn = new sem_function (cnode, &m_bmstack);
2254 : 76201 : unsigned count = streamer_read_uhwi (&ib_main);
2255 : 76201 : inchash::hash hstate (0);
2256 : 76201 : if (flag_incremental_link == INCREMENTAL_LINK_LTO)
2257 : 43 : fn->memory_access_types.reserve_exact (count);
2258 : 606014 : for (unsigned i = 0; i < count; i++)
2259 : : {
2260 : 529813 : tree type = stream_read_tree (&ib_main, data_in);
2261 : 529813 : hstate.add_int (get_deref_alias_set (type));
2262 : 529813 : if (flag_incremental_link == INCREMENTAL_LINK_LTO)
2263 : 146 : fn->memory_access_types.quick_push (type);
2264 : : }
2265 : 76201 : fn->m_alias_sets_hash = hstate.end ();
2266 : 76201 : fn->set_hash (hash);
2267 : 76201 : m_items.safe_push (fn);
2268 : : }
2269 : 115425 : else if (varpool_node *vnode = dyn_cast <varpool_node *> (node))
2270 : : {
2271 : 19612 : sem_variable *var = new sem_variable (vnode, &m_bmstack);
2272 : 19612 : var->set_hash (hash);
2273 : 19612 : m_items.safe_push (var);
2274 : : }
2275 : : }
2276 : :
2277 : 10613 : lto_free_section_data (file_data, LTO_section_ipa_icf, NULL, data,
2278 : : len);
2279 : 10613 : lto_data_in_delete (data_in);
2280 : 10613 : }
2281 : :
2282 : : /* Read IPA ICF summary for symbols. */
2283 : :
2284 : : void
2285 : 13167 : sem_item_optimizer::read_summary (void)
2286 : : {
2287 : 13167 : lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
2288 : 13167 : lto_file_decl_data *file_data;
2289 : 13167 : unsigned int j = 0;
2290 : :
2291 : 40541 : while ((file_data = file_data_vec[j++]))
2292 : : {
2293 : 14207 : size_t len;
2294 : 14207 : const char *data
2295 : 14207 : = lto_get_summary_section_data (file_data, LTO_section_ipa_icf, &len);
2296 : 14207 : if (data)
2297 : 10613 : read_section (file_data, data, len);
2298 : : }
2299 : 13167 : }
2300 : :
2301 : : /* Register callgraph and varpool hooks. */
2302 : :
2303 : : void
2304 : 137484 : sem_item_optimizer::register_hooks (void)
2305 : : {
2306 : 137484 : if (!m_cgraph_node_hooks)
2307 : 137484 : m_cgraph_node_hooks = symtab->add_cgraph_removal_hook
2308 : 137484 : (&sem_item_optimizer::cgraph_removal_hook, this);
2309 : :
2310 : 137484 : if (!m_varpool_node_hooks)
2311 : 137484 : m_varpool_node_hooks = symtab->add_varpool_removal_hook
2312 : 137484 : (&sem_item_optimizer::varpool_removal_hook, this);
2313 : 137484 : }
2314 : :
2315 : : /* Unregister callgraph and varpool hooks. */
2316 : :
2317 : : void
2318 : 128583 : sem_item_optimizer::unregister_hooks (void)
2319 : : {
2320 : 128583 : if (m_cgraph_node_hooks)
2321 : 128583 : symtab->remove_cgraph_removal_hook (m_cgraph_node_hooks);
2322 : :
2323 : 128583 : if (m_varpool_node_hooks)
2324 : 128583 : symtab->remove_varpool_removal_hook (m_varpool_node_hooks);
2325 : 128583 : }
2326 : :
2327 : : /* Adds a CLS to hashtable associated by hash value. */
2328 : :
2329 : : void
2330 : 31094 : sem_item_optimizer::add_class (congruence_class *cls)
2331 : : {
2332 : 31094 : gcc_assert (cls->members.length ());
2333 : :
2334 : 31094 : congruence_class_group *group
2335 : 31094 : = get_group_by_hash (cls->members[0]->get_hash (),
2336 : 31094 : cls->members[0]->type);
2337 : 31094 : group->classes.safe_push (cls);
2338 : 31094 : }
2339 : :
2340 : : /* Gets a congruence class group based on given HASH value and TYPE. */
2341 : :
2342 : : congruence_class_group *
2343 : 2511301 : sem_item_optimizer::get_group_by_hash (hashval_t hash, sem_item_type type)
2344 : : {
2345 : 2511301 : congruence_class_group *item = XNEW (congruence_class_group);
2346 : 2511301 : item->hash = hash;
2347 : 2511301 : item->type = type;
2348 : :
2349 : 2511301 : congruence_class_group **slot = m_classes.find_slot (item, INSERT);
2350 : :
2351 : 2511301 : if (*slot)
2352 : 629713 : free (item);
2353 : : else
2354 : : {
2355 : 1881588 : item->classes.create (1);
2356 : 1881588 : *slot = item;
2357 : : }
2358 : :
2359 : 2511301 : return *slot;
2360 : : }
2361 : :
2362 : : /* Callgraph removal hook called for a NODE with a custom DATA. */
2363 : :
2364 : : void
2365 : 11242 : sem_item_optimizer::cgraph_removal_hook (cgraph_node *node, void *data)
2366 : : {
2367 : 11242 : sem_item_optimizer *optimizer = (sem_item_optimizer *) data;
2368 : 11242 : optimizer->remove_symtab_node (node);
2369 : 11242 : }
2370 : :
2371 : : /* Varpool removal hook called for a NODE with a custom DATA. */
2372 : :
2373 : : void
2374 : 3386 : sem_item_optimizer::varpool_removal_hook (varpool_node *node, void *data)
2375 : : {
2376 : 3386 : sem_item_optimizer *optimizer = (sem_item_optimizer *) data;
2377 : 3386 : optimizer->remove_symtab_node (node);
2378 : 3386 : }
2379 : :
2380 : : /* Remove symtab NODE triggered by symtab removal hooks. */
2381 : :
2382 : : void
2383 : 14628 : sem_item_optimizer::remove_symtab_node (symtab_node *node)
2384 : : {
2385 : 14628 : gcc_assert (m_classes.is_empty ());
2386 : :
2387 : 14628 : m_removed_items_set.add (node);
2388 : 14628 : }
2389 : :
2390 : : void
2391 : 695744 : sem_item_optimizer::remove_item (sem_item *item)
2392 : : {
2393 : 695744 : if (m_symtab_node_map.get (item->node))
2394 : 672632 : m_symtab_node_map.remove (item->node);
2395 : 695744 : delete item;
2396 : 695744 : }
2397 : :
2398 : : /* Removes all callgraph and varpool nodes that are marked by symtab
2399 : : as deleted. */
2400 : :
2401 : : void
2402 : 128583 : sem_item_optimizer::filter_removed_items (void)
2403 : : {
2404 : 128583 : auto_vec <sem_item *> filtered;
2405 : :
2406 : 3304534 : for (unsigned int i = 0; i < m_items.length(); i++)
2407 : : {
2408 : 3175951 : sem_item *item = m_items[i];
2409 : :
2410 : 3175951 : if (m_removed_items_set.contains (item->node))
2411 : : {
2412 : 8835 : remove_item (item);
2413 : 8835 : continue;
2414 : : }
2415 : :
2416 : 3167116 : if (item->type == FUNC)
2417 : : {
2418 : 992784 : cgraph_node *cnode = static_cast <sem_function *>(item)->get_node ();
2419 : :
2420 : 992784 : if (in_lto_p && (cnode->alias || cnode->body_removed))
2421 : 9 : remove_item (item);
2422 : : else
2423 : 992775 : filtered.safe_push (item);
2424 : : }
2425 : : else /* VAR. */
2426 : : {
2427 : 2174332 : if (!flag_ipa_icf_variables)
2428 : 1 : remove_item (item);
2429 : : else
2430 : : {
2431 : : /* Filter out non-readonly variables. */
2432 : 2174331 : tree decl = item->decl;
2433 : 2174331 : varpool_node *vnode = static_cast <sem_variable *>(item)->get_node ();
2434 : 2174331 : if (!TREE_READONLY (decl) || vnode->body_removed)
2435 : 686899 : remove_item (item);
2436 : : else
2437 : 1487432 : filtered.safe_push (item);
2438 : : }
2439 : : }
2440 : : }
2441 : :
2442 : : /* Clean-up of released semantic items. */
2443 : :
2444 : 128583 : m_items.release ();
2445 : 2608790 : for (unsigned int i = 0; i < filtered.length(); i++)
2446 : 2480207 : m_items.safe_push (filtered[i]);
2447 : 128583 : }
2448 : :
2449 : : /* Optimizer entry point which returns true in case it processes
2450 : : a merge operation. True is returned if there's a merge operation
2451 : : processed. */
2452 : :
2453 : : bool
2454 : 128583 : sem_item_optimizer::execute (void)
2455 : : {
2456 : 128583 : filter_removed_items ();
2457 : 128583 : unregister_hooks ();
2458 : :
2459 : 128583 : build_graph ();
2460 : 128583 : update_hash_by_addr_refs ();
2461 : 128583 : update_hash_by_memory_access_type ();
2462 : 128583 : build_hash_based_classes ();
2463 : :
2464 : 128583 : if (dump_file)
2465 : 182 : fprintf (dump_file, "Dump after hash based groups\n");
2466 : 128583 : dump_cong_classes ();
2467 : :
2468 : 128583 : subdivide_classes_by_equality (true);
2469 : :
2470 : 128583 : if (dump_file)
2471 : 182 : fprintf (dump_file, "Dump after WPA based types groups\n");
2472 : :
2473 : 128583 : dump_cong_classes ();
2474 : :
2475 : 128583 : process_cong_reduction ();
2476 : 128583 : checking_verify_classes ();
2477 : :
2478 : 128583 : if (dump_file)
2479 : 182 : fprintf (dump_file, "Dump after callgraph-based congruence reduction\n");
2480 : :
2481 : 128583 : dump_cong_classes ();
2482 : :
2483 : 128583 : unsigned int loaded_symbols = parse_nonsingleton_classes ();
2484 : 128583 : subdivide_classes_by_equality ();
2485 : :
2486 : 128583 : if (dump_file)
2487 : 182 : fprintf (dump_file, "Dump after full equality comparison of groups\n");
2488 : :
2489 : 128583 : dump_cong_classes ();
2490 : :
2491 : 128583 : unsigned int prev_class_count = m_classes_count;
2492 : :
2493 : 128583 : process_cong_reduction ();
2494 : 128583 : dump_cong_classes ();
2495 : 128583 : checking_verify_classes ();
2496 : 128583 : bool merged_p = merge_classes (prev_class_count, loaded_symbols);
2497 : :
2498 : 128583 : if (dump_file && (dump_flags & TDF_DETAILS))
2499 : 20 : symtab->dump (dump_file);
2500 : :
2501 : 128583 : return merged_p;
2502 : : }
2503 : :
2504 : : /* Function responsible for visiting all potential functions and
2505 : : read-only variables that can be merged. */
2506 : :
2507 : : void
2508 : 124317 : sem_item_optimizer::parse_funcs_and_vars (void)
2509 : : {
2510 : 124317 : cgraph_node *cnode;
2511 : :
2512 : : /* Create dummy func_checker for hashing purpose. */
2513 : 124317 : func_checker checker;
2514 : :
2515 : 124317 : if (flag_ipa_icf_functions)
2516 : 1173972 : FOR_EACH_DEFINED_FUNCTION (cnode)
2517 : : {
2518 : 1053164 : sem_function *f = sem_function::parse (cnode, &m_bmstack, &checker);
2519 : 1053164 : if (f)
2520 : : {
2521 : 964410 : m_items.safe_push (f);
2522 : 964410 : m_symtab_node_map.put (cnode, f);
2523 : : }
2524 : : }
2525 : :
2526 : 124317 : varpool_node *vnode;
2527 : :
2528 : 124317 : if (flag_ipa_icf_variables)
2529 : 2458243 : FOR_EACH_DEFINED_VARIABLE (vnode)
2530 : : {
2531 : 2333929 : sem_variable *v = sem_variable::parse (vnode, &m_bmstack, &checker);
2532 : :
2533 : 2333929 : if (v)
2534 : : {
2535 : 2269582 : m_items.safe_push (v);
2536 : 2269582 : m_symtab_node_map.put (vnode, v);
2537 : : }
2538 : : }
2539 : 124317 : }
2540 : :
2541 : : /* Makes pairing between a congruence class CLS and semantic ITEM. */
2542 : :
2543 : : void
2544 : 4026897 : sem_item_optimizer::add_item_to_class (congruence_class *cls, sem_item *item)
2545 : : {
2546 : 4026897 : item->index_in_class = cls->members.length ();
2547 : 4026897 : cls->members.safe_push (item);
2548 : 4026897 : cls->referenced_by_count += item->referenced_by_count;
2549 : 4026897 : item->cls = cls;
2550 : 4026897 : }
2551 : :
2552 : : /* For each semantic item, append hash values of references. */
2553 : :
2554 : : void
2555 : 128583 : sem_item_optimizer::update_hash_by_addr_refs ()
2556 : : {
2557 : : /* First, append to hash sensitive references and class type if it need to
2558 : : be matched for ODR. */
2559 : 5209187 : for (unsigned i = 0; i < m_items.length (); i++)
2560 : : {
2561 : 2480207 : m_items[i]->update_hash_by_addr_refs (m_symtab_node_map);
2562 : 2480207 : if (m_items[i]->type == FUNC)
2563 : : {
2564 : 992775 : if (TREE_CODE (TREE_TYPE (m_items[i]->decl)) == METHOD_TYPE
2565 : 299731 : && contains_polymorphic_type_p
2566 : 299731 : (TYPE_METHOD_BASETYPE (TREE_TYPE (m_items[i]->decl)))
2567 : 1069869 : && (DECL_CXX_CONSTRUCTOR_P (m_items[i]->decl)
2568 : 66473 : || (static_cast<sem_function *> (m_items[i])->param_used_p (0)
2569 : 112096 : && static_cast<sem_function *> (m_items[i])
2570 : 56048 : ->compare_polymorphic_p ())))
2571 : : {
2572 : 49055 : tree class_type
2573 : 49055 : = TYPE_METHOD_BASETYPE (TREE_TYPE (m_items[i]->decl));
2574 : 49055 : inchash::hash hstate (m_items[i]->get_hash ());
2575 : :
2576 : : /* Hash ODR types by mangled name if it is defined.
2577 : : If not we know that type is anonymous of free_lang_data
2578 : : was not run and in that case type main variants are
2579 : : unique. */
2580 : 49055 : if (TYPE_NAME (class_type)
2581 : 49055 : && DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (class_type))
2582 : 49341 : && !type_in_anonymous_namespace_p
2583 : 286 : (class_type))
2584 : 282 : hstate.add_hwi
2585 : 282 : (IDENTIFIER_HASH_VALUE
2586 : : (DECL_ASSEMBLER_NAME (TYPE_NAME (class_type))));
2587 : : else
2588 : : {
2589 : 48773 : gcc_checking_assert
2590 : : (!in_lto_p
2591 : : || type_in_anonymous_namespace_p (class_type));
2592 : 48773 : hstate.add_hwi (TYPE_UID (TYPE_MAIN_VARIANT (class_type)));
2593 : : }
2594 : :
2595 : 49055 : m_items[i]->set_hash (hstate.end ());
2596 : : }
2597 : : }
2598 : : }
2599 : :
2600 : : /* Once all symbols have enhanced hash value, we can append
2601 : : hash values of symbols that are seen by IPA ICF and are
2602 : : references by a semantic item. Newly computed values
2603 : : are saved to global_hash member variable. */
2604 : 5209187 : for (unsigned i = 0; i < m_items.length (); i++)
2605 : 2480207 : m_items[i]->update_hash_by_local_refs (m_symtab_node_map);
2606 : :
2607 : : /* Global hash value replace current hash values. */
2608 : 2608790 : for (unsigned i = 0; i < m_items.length (); i++)
2609 : 2480207 : m_items[i]->set_hash (m_items[i]->global_hash);
2610 : 128583 : }
2611 : :
2612 : : void
2613 : 128583 : sem_item_optimizer::update_hash_by_memory_access_type ()
2614 : : {
2615 : 2608790 : for (unsigned i = 0; i < m_items.length (); i++)
2616 : : {
2617 : 2480207 : if (m_items[i]->type == FUNC)
2618 : : {
2619 : 992775 : sem_function *fn = static_cast<sem_function *> (m_items[i]);
2620 : 992775 : inchash::hash hstate (fn->get_hash ());
2621 : 992775 : hstate.add_int (fn->m_alias_sets_hash);
2622 : 992775 : fn->set_hash (hstate.end ());
2623 : : }
2624 : : }
2625 : 128583 : }
2626 : :
2627 : : /* Congruence classes are built by hash value. */
2628 : :
2629 : : void
2630 : 128583 : sem_item_optimizer::build_hash_based_classes (void)
2631 : : {
2632 : 2608790 : for (unsigned i = 0; i < m_items.length (); i++)
2633 : : {
2634 : 2480207 : sem_item *item = m_items[i];
2635 : :
2636 : 2480207 : congruence_class_group *group
2637 : 2480207 : = get_group_by_hash (item->get_hash (), item->type);
2638 : :
2639 : 2480207 : if (!group->classes.length ())
2640 : : {
2641 : 1881588 : m_classes_count++;
2642 : 1881588 : group->classes.safe_push (new congruence_class (class_id++));
2643 : : }
2644 : :
2645 : 2480207 : add_item_to_class (group->classes[0], item);
2646 : : }
2647 : 128583 : }
2648 : :
2649 : : /* Build references according to call graph. */
2650 : :
2651 : : void
2652 : 128583 : sem_item_optimizer::build_graph (void)
2653 : : {
2654 : 5209187 : for (unsigned i = 0; i < m_items.length (); i++)
2655 : : {
2656 : 2480207 : sem_item *item = m_items[i];
2657 : 2480207 : m_symtab_node_map.put (item->node, item);
2658 : :
2659 : : /* Initialize hash values if we are not in LTO mode. */
2660 : 2480207 : if (!in_lto_p)
2661 : 2407619 : item->get_hash ();
2662 : : }
2663 : :
2664 : 2608790 : for (unsigned i = 0; i < m_items.length (); i++)
2665 : : {
2666 : 2480207 : sem_item *item = m_items[i];
2667 : :
2668 : 2480207 : if (item->type == FUNC)
2669 : : {
2670 : 992775 : cgraph_node *cnode = dyn_cast <cgraph_node *> (item->node);
2671 : :
2672 : 992775 : cgraph_edge *e = cnode->callees;
2673 : 4769817 : while (e)
2674 : : {
2675 : 3777042 : sem_item **slot = m_symtab_node_map.get
2676 : 3777042 : (e->callee->ultimate_alias_target ());
2677 : 3777042 : if (slot)
2678 : 1659063 : item->add_reference (&m_references, *slot);
2679 : :
2680 : 3777042 : e = e->next_callee;
2681 : : }
2682 : : }
2683 : :
2684 : 6868283 : ipa_ref *ref = NULL;
2685 : 7847422 : for (unsigned i = 0; item->node->iterate_reference (i, ref); i++)
2686 : : {
2687 : 4388076 : sem_item **slot = m_symtab_node_map.get
2688 : 4388076 : (ref->referred->ultimate_alias_target ());
2689 : 4388076 : if (slot)
2690 : 2333431 : item->add_reference (&m_references, *slot);
2691 : : }
2692 : : }
2693 : 128583 : }
2694 : :
2695 : : /* Semantic items in classes having more than one element and initialized.
2696 : : In case of WPA, we load function body. */
2697 : :
2698 : : unsigned int
2699 : 128583 : sem_item_optimizer::parse_nonsingleton_classes (void)
2700 : : {
2701 : 128583 : unsigned int counter = 0;
2702 : :
2703 : : /* Create dummy func_checker for hashing purpose. */
2704 : 128583 : func_checker checker;
2705 : :
2706 : 2608790 : for (unsigned i = 0; i < m_items.length (); i++)
2707 : 3123766 : if (m_items[i]->cls->members.length () > 1)
2708 : : {
2709 : 643559 : m_items[i]->init (&checker);
2710 : 643559 : ++counter;
2711 : : }
2712 : :
2713 : 128583 : if (dump_file)
2714 : : {
2715 : 182 : float f = m_items.length () ? 100.0f * counter / m_items.length () : 0.0f;
2716 : 182 : fprintf (dump_file, "Init called for %u items (%.2f%%).\n", counter, f);
2717 : : }
2718 : :
2719 : 257166 : return counter;
2720 : 128583 : }
2721 : :
2722 : : /* Equality function for semantic items is used to subdivide existing
2723 : : classes. If IN_WPA, fast equality function is invoked. */
2724 : :
2725 : : void
2726 : 257166 : sem_item_optimizer::subdivide_classes_by_equality (bool in_wpa)
2727 : : {
2728 : 4020342 : for (hash_table <congruence_class_hash>::iterator it = m_classes.begin ();
2729 : 7783518 : it != m_classes.end (); ++it)
2730 : : {
2731 : 3763176 : unsigned int class_count = (*it)->classes.length ();
2732 : :
2733 : 7605947 : for (unsigned i = 0; i < class_count; i++)
2734 : : {
2735 : 3842771 : congruence_class *c = (*it)->classes[i];
2736 : :
2737 : 4105298 : if (c->members.length() > 1)
2738 : : {
2739 : 262527 : auto_vec <sem_item *> new_vector;
2740 : :
2741 : 262527 : sem_item *first = c->members[0];
2742 : 262527 : new_vector.safe_push (first);
2743 : :
2744 : 262527 : unsigned class_split_first = (*it)->classes.length ();
2745 : :
2746 : 1380170 : for (unsigned j = 1; j < c->members.length (); j++)
2747 : : {
2748 : 1117643 : sem_item *item = c->members[j];
2749 : :
2750 : 1117643 : bool equals
2751 : 1117643 : = in_wpa ? first->equals_wpa (item, m_symtab_node_map)
2752 : 1117643 : : first->equals (item, m_symtab_node_map);
2753 : :
2754 : 1117643 : if (equals)
2755 : 959981 : new_vector.safe_push (item);
2756 : : else
2757 : : {
2758 : 1672426 : bool integrated = false;
2759 : :
2760 : 1514764 : for (unsigned k = class_split_first;
2761 : 1672426 : k < (*it)->classes.length (); k++)
2762 : : {
2763 : 1592018 : sem_item *x = (*it)->classes[k]->members[0];
2764 : 1592018 : bool equals
2765 : 1592018 : = in_wpa ? x->equals_wpa (item, m_symtab_node_map)
2766 : 1592018 : : x->equals (item, m_symtab_node_map);
2767 : :
2768 : 1592018 : if (equals)
2769 : : {
2770 : 77254 : integrated = true;
2771 : 77254 : add_item_to_class ((*it)->classes[k], item);
2772 : :
2773 : 77254 : break;
2774 : : }
2775 : : }
2776 : :
2777 : 77254 : if (!integrated)
2778 : : {
2779 : 80408 : congruence_class *c
2780 : 80408 : = new congruence_class (class_id++);
2781 : 80408 : m_classes_count++;
2782 : 80408 : add_item_to_class (c, item);
2783 : :
2784 : 80408 : (*it)->classes.safe_push (c);
2785 : : }
2786 : : }
2787 : : }
2788 : :
2789 : : // We replace newly created new_vector for the class we've just
2790 : : // splitted.
2791 : 262527 : c->members.release ();
2792 : 262527 : c->members.create (new_vector.length ());
2793 : :
2794 : 1485035 : for (unsigned int j = 0; j < new_vector.length (); j++)
2795 : 1222508 : add_item_to_class (c, new_vector[j]);
2796 : 262527 : }
2797 : : }
2798 : : }
2799 : :
2800 : 257166 : checking_verify_classes ();
2801 : 257166 : }
2802 : :
2803 : : /* Subdivide classes by address references that members of the class
2804 : : reference. Example can be a pair of functions that have an address
2805 : : taken from a function. If these addresses are different the class
2806 : : is split. */
2807 : :
2808 : : unsigned
2809 : 257166 : sem_item_optimizer::subdivide_classes_by_sensitive_refs ()
2810 : : {
2811 : 257166 : typedef hash_map <symbol_compare_hash, vec <sem_item *> > subdivide_hash_map;
2812 : :
2813 : 257166 : unsigned newly_created_classes = 0;
2814 : :
2815 : 257166 : for (hash_table <congruence_class_hash>::iterator it = m_classes.begin ();
2816 : 7783518 : it != m_classes.end (); ++it)
2817 : : {
2818 : 3763176 : unsigned int class_count = (*it)->classes.length ();
2819 : 3763176 : auto_vec<congruence_class *> new_classes;
2820 : :
2821 : 7701902 : for (unsigned i = 0; i < class_count; i++)
2822 : : {
2823 : 3938726 : congruence_class *c = (*it)->classes[i];
2824 : :
2825 : 4190026 : if (c->members.length() > 1)
2826 : : {
2827 : 251300 : subdivide_hash_map split_map;
2828 : :
2829 : 1524288 : for (unsigned j = 0; j < c->members.length (); j++)
2830 : : {
2831 : 1272988 : sem_item *source_node = c->members[j];
2832 : :
2833 : 1272988 : symbol_compare_collection *collection
2834 : 1272988 : = new symbol_compare_collection (source_node->node);
2835 : :
2836 : 1272988 : bool existed;
2837 : 1272988 : vec <sem_item *> *slot
2838 : 1272988 : = &split_map.get_or_insert (collection, &existed);
2839 : 1272988 : gcc_checking_assert (slot);
2840 : :
2841 : 1272988 : slot->safe_push (source_node);
2842 : :
2843 : 1272988 : if (existed)
2844 : 2043376 : delete collection;
2845 : : }
2846 : :
2847 : : /* If the map contains more than one key, we have to split
2848 : : the map appropriately. */
2849 : 251300 : if (split_map.elements () != 1)
2850 : : {
2851 : 0 : bool first_class = true;
2852 : :
2853 : 0 : for (subdivide_hash_map::iterator it2 = split_map.begin ();
2854 : 0 : it2 != split_map.end (); ++it2)
2855 : : {
2856 : 0 : congruence_class *new_cls;
2857 : 0 : new_cls = new congruence_class (class_id++);
2858 : :
2859 : 0 : for (unsigned k = 0; k < (*it2).second.length (); k++)
2860 : 0 : add_item_to_class (new_cls, (*it2).second[k]);
2861 : :
2862 : 0 : worklist_push (new_cls);
2863 : 0 : newly_created_classes++;
2864 : :
2865 : 0 : if (first_class)
2866 : : {
2867 : 0 : (*it)->classes[i] = new_cls;
2868 : 0 : first_class = false;
2869 : : }
2870 : : else
2871 : : {
2872 : 0 : new_classes.safe_push (new_cls);
2873 : 0 : m_classes_count++;
2874 : : }
2875 : : }
2876 : : }
2877 : :
2878 : : /* Release memory. */
2879 : 502600 : for (subdivide_hash_map::iterator it2 = split_map.begin ();
2880 : 1005200 : it2 != split_map.end (); ++it2)
2881 : : {
2882 : 502600 : delete (*it2).first;
2883 : 251300 : (*it2).second.release ();
2884 : : }
2885 : 251300 : }
2886 : : }
2887 : :
2888 : 3763176 : for (unsigned i = 0; i < new_classes.length (); i++)
2889 : 0 : (*it)->classes.safe_push (new_classes[i]);
2890 : 3763176 : }
2891 : :
2892 : 257166 : return newly_created_classes;
2893 : : }
2894 : :
2895 : : /* Verify congruence classes, if checking is enabled. */
2896 : :
2897 : : void
2898 : 514332 : sem_item_optimizer::checking_verify_classes (void)
2899 : : {
2900 : 514332 : if (flag_checking)
2901 : 514300 : verify_classes ();
2902 : 514332 : }
2903 : :
2904 : : /* Verify congruence classes. */
2905 : :
2906 : : void
2907 : 514300 : sem_item_optimizer::verify_classes (void)
2908 : : {
2909 : 514300 : for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
2910 : 15566700 : it != m_classes.end (); ++it)
2911 : : {
2912 : 15387953 : for (unsigned int i = 0; i < (*it)->classes.length (); i++)
2913 : : {
2914 : 7861753 : congruence_class *cls = (*it)->classes[i];
2915 : :
2916 : 7861753 : gcc_assert (cls);
2917 : 7861753 : gcc_assert (cls->members.length () > 0);
2918 : :
2919 : 17782429 : for (unsigned int j = 0; j < cls->members.length (); j++)
2920 : : {
2921 : 9920676 : sem_item *item = cls->members[j];
2922 : :
2923 : 9920676 : gcc_assert (item);
2924 : 9920676 : gcc_assert (item->cls == cls);
2925 : : }
2926 : : }
2927 : : }
2928 : 514300 : }
2929 : :
2930 : : /* Disposes split map traverse function. CLS_PTR is pointer to congruence
2931 : : class, BSLOT is bitmap slot we want to release. DATA is mandatory,
2932 : : but unused argument. */
2933 : :
2934 : : bool
2935 : 151092 : sem_item_optimizer::release_split_map (congruence_class * const &,
2936 : : bitmap const &b, traverse_split_pair *)
2937 : : {
2938 : 151092 : bitmap bmp = b;
2939 : :
2940 : 151092 : BITMAP_FREE (bmp);
2941 : :
2942 : 151092 : return true;
2943 : : }
2944 : :
2945 : : /* Process split operation for a class given as pointer CLS_PTR,
2946 : : where bitmap B splits congruence class members. DATA is used
2947 : : as argument of split pair. */
2948 : :
2949 : : bool
2950 : 151092 : sem_item_optimizer::traverse_congruence_split (congruence_class * const &cls,
2951 : : bitmap const &b,
2952 : : traverse_split_pair *pair)
2953 : : {
2954 : 151092 : sem_item_optimizer *optimizer = pair->optimizer;
2955 : 151092 : const congruence_class *splitter_cls = pair->cls;
2956 : :
2957 : : /* If counted bits are greater than zero and less than the number of members
2958 : : a group will be splitted. */
2959 : 151092 : unsigned popcount = bitmap_count_bits (b);
2960 : :
2961 : 151092 : if (popcount > 0 && popcount < cls->members.length ())
2962 : : {
2963 : 15547 : auto_vec <congruence_class *, 2> newclasses;
2964 : 15547 : newclasses.quick_push (new congruence_class (class_id++));
2965 : 15547 : newclasses.quick_push (new congruence_class (class_id++));
2966 : :
2967 : 182067 : for (unsigned int i = 0; i < cls->members.length (); i++)
2968 : : {
2969 : 166520 : int target = bitmap_bit_p (b, i);
2970 : 166520 : congruence_class *tc = newclasses[target];
2971 : :
2972 : 166520 : add_item_to_class (tc, cls->members[i]);
2973 : : }
2974 : :
2975 : 15547 : if (flag_checking)
2976 : : {
2977 : 46641 : for (unsigned int i = 0; i < 2; i++)
2978 : 31094 : gcc_assert (newclasses[i]->members.length ());
2979 : : }
2980 : :
2981 : 15547 : if (splitter_cls == cls)
2982 : 6 : optimizer->splitter_class_removed = true;
2983 : :
2984 : : /* Remove old class from worklist if presented. */
2985 : 15547 : bool in_worklist = cls->in_worklist;
2986 : :
2987 : 15547 : if (in_worklist)
2988 : 10901 : cls->in_worklist = false;
2989 : :
2990 : 15547 : congruence_class_group g;
2991 : 15547 : g.hash = cls->members[0]->get_hash ();
2992 : 15547 : g.type = cls->members[0]->type;
2993 : :
2994 : 15547 : congruence_class_group *slot = optimizer->m_classes.find (&g);
2995 : :
2996 : 143412 : for (unsigned int i = 0; i < slot->classes.length (); i++)
2997 : 143412 : if (slot->classes[i] == cls)
2998 : : {
2999 : 15547 : slot->classes.ordered_remove (i);
3000 : 15547 : break;
3001 : : }
3002 : :
3003 : : /* New class will be inserted and integrated to work list. */
3004 : 46641 : for (unsigned int i = 0; i < 2; i++)
3005 : 31094 : optimizer->add_class (newclasses[i]);
3006 : :
3007 : : /* Two classes replace one, so that increment just by one. */
3008 : 15547 : optimizer->m_classes_count++;
3009 : :
3010 : : /* If OLD class was presented in the worklist, we remove the class
3011 : : and replace it will both newly created classes. */
3012 : 15547 : if (in_worklist)
3013 : 32703 : for (unsigned int i = 0; i < 2; i++)
3014 : 21802 : optimizer->worklist_push (newclasses[i]);
3015 : : else /* Just smaller class is inserted. */
3016 : : {
3017 : 4646 : unsigned int smaller_index
3018 : 9292 : = (newclasses[0]->members.length ()
3019 : 4646 : < newclasses[1]->members.length ()
3020 : 4646 : ? 0 : 1);
3021 : 4646 : optimizer->worklist_push (newclasses[smaller_index]);
3022 : : }
3023 : :
3024 : 15547 : if (dump_file && (dump_flags & TDF_DETAILS))
3025 : : {
3026 : 1 : fprintf (dump_file, " congruence class splitted:\n");
3027 : 1 : cls->dump (dump_file, 4);
3028 : :
3029 : 1 : fprintf (dump_file, " newly created groups:\n");
3030 : 3 : for (unsigned int i = 0; i < 2; i++)
3031 : 2 : newclasses[i]->dump (dump_file, 4);
3032 : : }
3033 : :
3034 : : /* Release class if not presented in work list. */
3035 : 15547 : if (!in_worklist)
3036 : 9292 : delete cls;
3037 : :
3038 : 15547 : return true;
3039 : 15547 : }
3040 : :
3041 : : return false;
3042 : : }
3043 : :
3044 : : /* Compare function for sorting pairs in do_congruence_step_f. */
3045 : :
3046 : : int
3047 : 1474300 : sem_item_optimizer::sort_congruence_split (const void *a_, const void *b_)
3048 : : {
3049 : 1474300 : const std::pair<congruence_class *, bitmap> *a
3050 : : = (const std::pair<congruence_class *, bitmap> *)a_;
3051 : 1474300 : const std::pair<congruence_class *, bitmap> *b
3052 : : = (const std::pair<congruence_class *, bitmap> *)b_;
3053 : 1474300 : if (a->first->id < b->first->id)
3054 : : return -1;
3055 : 695856 : else if (a->first->id > b->first->id)
3056 : 695856 : return 1;
3057 : : return 0;
3058 : : }
3059 : :
3060 : : /* Tests if a class CLS used as INDEXth splits any congruence classes.
3061 : : Bitmap stack BMSTACK is used for bitmap allocation. */
3062 : :
3063 : : bool
3064 : 5096797 : sem_item_optimizer::do_congruence_step_for_index (congruence_class *cls,
3065 : : unsigned int index)
3066 : : {
3067 : 5096797 : hash_map <congruence_class *, bitmap> split_map;
3068 : :
3069 : 32227958 : for (unsigned int i = 0; i < cls->members.length (); i++)
3070 : : {
3071 : 27131161 : sem_item *item = cls->members[i];
3072 : 27131161 : sem_usage_pair needle (item, index);
3073 : 27131161 : vec<sem_item *> *callers = m_references.get (&needle);
3074 : 27131161 : if (callers == NULL)
3075 : 21285027 : continue;
3076 : :
3077 : 13834051 : for (unsigned int j = 0; j < callers->length (); j++)
3078 : : {
3079 : 7987917 : sem_item *caller = (*callers)[j];
3080 : 7987917 : if (caller->cls->members.length () < 2)
3081 : 7488471 : continue;
3082 : 499446 : bitmap *slot = split_map.get (caller->cls);
3083 : 499446 : bitmap b;
3084 : :
3085 : 499446 : if(!slot)
3086 : : {
3087 : 151092 : b = BITMAP_ALLOC (&m_bmstack);
3088 : 151092 : split_map.put (caller->cls, b);
3089 : : }
3090 : : else
3091 : 348354 : b = *slot;
3092 : :
3093 : 499446 : gcc_checking_assert (caller->cls);
3094 : 499446 : gcc_checking_assert (caller->index_in_class
3095 : : < caller->cls->members.length ());
3096 : :
3097 : 499446 : bitmap_set_bit (b, caller->index_in_class);
3098 : : }
3099 : : }
3100 : :
3101 : 5096797 : auto_vec<std::pair<congruence_class *, bitmap> > to_split;
3102 : 5096797 : to_split.reserve_exact (split_map.elements ());
3103 : 5096797 : for (hash_map <congruence_class *, bitmap>::iterator i = split_map.begin ();
3104 : 5398981 : i != split_map.end (); ++i)
3105 : 151092 : to_split.safe_push (*i);
3106 : 5096797 : to_split.qsort (sort_congruence_split);
3107 : :
3108 : 5096797 : traverse_split_pair pair;
3109 : 5096797 : pair.optimizer = this;
3110 : 5096797 : pair.cls = cls;
3111 : :
3112 : 5096797 : splitter_class_removed = false;
3113 : 5096797 : bool r = false;
3114 : 5247889 : for (unsigned i = 0; i < to_split.length (); ++i)
3115 : 151092 : r |= traverse_congruence_split (to_split[i].first, to_split[i].second,
3116 : : &pair);
3117 : :
3118 : : /* Bitmap clean-up. */
3119 : 5096797 : split_map.traverse <traverse_split_pair *,
3120 : 5247889 : sem_item_optimizer::release_split_map> (NULL);
3121 : :
3122 : 5096797 : return r;
3123 : 5096797 : }
3124 : :
3125 : : /* Every usage of a congruence class CLS is a candidate that can split the
3126 : : collection of classes. Bitmap stack BMSTACK is used for bitmap
3127 : : allocation. */
3128 : :
3129 : : void
3130 : 2977724 : sem_item_optimizer::do_congruence_step (congruence_class *cls)
3131 : : {
3132 : 2977724 : bitmap_iterator bi;
3133 : 2977724 : unsigned int i;
3134 : :
3135 : 2977724 : bitmap usage = BITMAP_ALLOC (&m_bmstack);
3136 : :
3137 : 6906139 : for (unsigned int i = 0; i < cls->members.length (); i++)
3138 : 3928415 : bitmap_ior_into (usage, cls->members[i]->usage_index_bitmap);
3139 : :
3140 : 8074515 : EXECUTE_IF_SET_IN_BITMAP (usage, 0, i, bi)
3141 : : {
3142 : 5096797 : if (dump_file && (dump_flags & TDF_DETAILS))
3143 : 188 : fprintf (dump_file, " processing congruence step for class: %u "
3144 : : "(%u items, %u references), index: %u\n", cls->id,
3145 : : cls->referenced_by_count, cls->members.length (), i);
3146 : 5096797 : do_congruence_step_for_index (cls, i);
3147 : :
3148 : 5096797 : if (splitter_class_removed)
3149 : : break;
3150 : : }
3151 : :
3152 : 2977724 : BITMAP_FREE (usage);
3153 : 2977724 : }
3154 : :
3155 : : /* Adds a newly created congruence class CLS to worklist. */
3156 : :
3157 : : void
3158 : 2988625 : sem_item_optimizer::worklist_push (congruence_class *cls)
3159 : : {
3160 : : /* Return if the class CLS is already presented in work list. */
3161 : 2988625 : if (cls->in_worklist)
3162 : : return;
3163 : :
3164 : 2988625 : cls->in_worklist = true;
3165 : 2988625 : worklist.insert (cls->referenced_by_count, cls);
3166 : : }
3167 : :
3168 : : /* Pops a class from worklist. */
3169 : :
3170 : : congruence_class *
3171 : 3234890 : sem_item_optimizer::worklist_pop (void)
3172 : : {
3173 : 3234890 : congruence_class *cls;
3174 : :
3175 : 3245791 : while (!worklist.empty ())
3176 : : {
3177 : 2988625 : cls = worklist.extract_min ();
3178 : 2988625 : if (cls->in_worklist)
3179 : : {
3180 : 2977724 : cls->in_worklist = false;
3181 : :
3182 : 2977724 : return cls;
3183 : : }
3184 : : else
3185 : : {
3186 : : /* Work list item was already intended to be removed.
3187 : : The only reason for doing it is to split a class.
3188 : : Thus, the class CLS is deleted. */
3189 : 10901 : delete cls;
3190 : : }
3191 : : }
3192 : :
3193 : : return NULL;
3194 : : }
3195 : :
3196 : : /* Iterative congruence reduction function. */
3197 : :
3198 : : void
3199 : 257166 : sem_item_optimizer::process_cong_reduction (void)
3200 : : {
3201 : 257166 : for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
3202 : 7783518 : it != m_classes.end (); ++it)
3203 : 7686355 : for (unsigned i = 0; i < (*it)->classes.length (); i++)
3204 : 3923179 : if ((*it)->classes[i]->is_class_used ())
3205 : 2962177 : worklist_push ((*it)->classes[i]);
3206 : :
3207 : 257166 : if (dump_file)
3208 : 364 : fprintf (dump_file, "Worklist has been filled with: "
3209 : : HOST_SIZE_T_PRINT_UNSIGNED "\n",
3210 : 364 : (fmt_size_t) worklist.nodes ());
3211 : :
3212 : 257166 : if (dump_file && (dump_flags & TDF_DETAILS))
3213 : 40 : fprintf (dump_file, "Congruence class reduction\n");
3214 : :
3215 : : congruence_class *cls;
3216 : :
3217 : : /* Process complete congruence reduction. */
3218 : 3234890 : while ((cls = worklist_pop ()) != NULL)
3219 : 2977724 : do_congruence_step (cls);
3220 : :
3221 : : /* Subdivide newly created classes according to references. */
3222 : 257166 : unsigned new_classes = subdivide_classes_by_sensitive_refs ();
3223 : :
3224 : 257166 : if (dump_file)
3225 : 364 : fprintf (dump_file, "Address reference subdivision created: %u "
3226 : : "new classes.\n", new_classes);
3227 : 257166 : }
3228 : :
3229 : : /* Debug function prints all informations about congruence classes. */
3230 : :
3231 : : void
3232 : 642915 : sem_item_optimizer::dump_cong_classes (void)
3233 : : {
3234 : 642915 : if (!dump_file)
3235 : : return;
3236 : :
3237 : : /* Histogram calculation. */
3238 : 910 : unsigned int max_index = 0;
3239 : 910 : unsigned int single_element_classes = 0;
3240 : 1815 : unsigned int* histogram = XCNEWVEC (unsigned int, m_items.length () + 1);
3241 : :
3242 : 910 : for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
3243 : 5790 : it != m_classes.end (); ++it)
3244 : 4950 : for (unsigned i = 0; i < (*it)->classes.length (); i++)
3245 : : {
3246 : 2510 : unsigned int c = (*it)->classes[i]->members.length ();
3247 : 2510 : histogram[c]++;
3248 : :
3249 : 2510 : if (c > max_index)
3250 : : max_index = c;
3251 : :
3252 : 2510 : if (c == 1)
3253 : 2104 : ++single_element_classes;
3254 : : }
3255 : :
3256 : 1820 : fprintf (dump_file,
3257 : : "Congruence classes: " HOST_SIZE_T_PRINT_UNSIGNED " with total: "
3258 : : "%u items (in a non-singular class: %u)\n",
3259 : 910 : (fmt_size_t) m_classes.elements (),
3260 : 1815 : m_items.length (), m_items.length () - single_element_classes);
3261 : 910 : fprintf (dump_file,
3262 : : "Class size histogram [number of members]: number of classes\n");
3263 : 3088 : for (unsigned int i = 0; i <= max_index; i++)
3264 : 2178 : if (histogram[i])
3265 : 1183 : fprintf (dump_file, "%6u: %6u\n", i, histogram[i]);
3266 : :
3267 : 910 : if (dump_flags & TDF_DETAILS)
3268 : 100 : for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
3269 : 740 : it != m_classes.end (); ++it)
3270 : : {
3271 : 540 : fprintf (dump_file, " group: with %u classes:\n",
3272 : 270 : (*it)->classes.length ());
3273 : :
3274 : 587 : for (unsigned i = 0; i < (*it)->classes.length (); i++)
3275 : : {
3276 : 317 : (*it)->classes[i]->dump (dump_file, 4);
3277 : :
3278 : 634 : if (i < (*it)->classes.length () - 1)
3279 : 47 : fprintf (dump_file, " ");
3280 : : }
3281 : : }
3282 : :
3283 : 910 : free (histogram);
3284 : : }
3285 : :
3286 : : /* Sort pair of sem_items A and B by DECL_UID. */
3287 : :
3288 : : static int
3289 : 11092560 : sort_sem_items_by_decl_uid (const void *a, const void *b)
3290 : : {
3291 : 11092560 : const sem_item *i1 = *(const sem_item * const *)a;
3292 : 11092560 : const sem_item *i2 = *(const sem_item * const *)b;
3293 : :
3294 : 11092560 : int uid1 = DECL_UID (i1->decl);
3295 : 11092560 : int uid2 = DECL_UID (i2->decl);
3296 : 11092560 : return uid1 - uid2;
3297 : : }
3298 : :
3299 : : /* Sort pair of congruence_classes A and B by DECL_UID of the first member. */
3300 : :
3301 : : static int
3302 : 1530284 : sort_congruence_classes_by_decl_uid (const void *a, const void *b)
3303 : : {
3304 : 1530284 : const congruence_class *c1 = *(const congruence_class * const *)a;
3305 : 1530284 : const congruence_class *c2 = *(const congruence_class * const *)b;
3306 : :
3307 : 1530284 : int uid1 = DECL_UID (c1->members[0]->decl);
3308 : 1530284 : int uid2 = DECL_UID (c2->members[0]->decl);
3309 : 1530284 : return uid1 - uid2;
3310 : : }
3311 : :
3312 : : /* Sort pair of congruence_class_groups A and B by
3313 : : DECL_UID of the first member of a first group. */
3314 : :
3315 : : static int
3316 : 72760446 : sort_congruence_class_groups_by_decl_uid (const void *a, const void *b)
3317 : : {
3318 : 72760446 : const std::pair<congruence_class_group *, int> *g1
3319 : : = (const std::pair<congruence_class_group *, int> *) a;
3320 : 72760446 : const std::pair<congruence_class_group *, int> *g2
3321 : : = (const std::pair<congruence_class_group *, int> *) b;
3322 : 72760446 : return g1->second - g2->second;
3323 : : }
3324 : :
3325 : : /* After reduction is done, we can declare all items in a group
3326 : : to be equal. PREV_CLASS_COUNT is start number of classes
3327 : : before reduction. True is returned if there's a merge operation
3328 : : processed. LOADED_SYMBOLS is number of symbols that were loaded
3329 : : in WPA. */
3330 : :
3331 : : bool
3332 : 128583 : sem_item_optimizer::merge_classes (unsigned int prev_class_count,
3333 : : unsigned int loaded_symbols)
3334 : : {
3335 : 128583 : unsigned int item_count = m_items.length ();
3336 : 128583 : unsigned int class_count = m_classes_count;
3337 : 128583 : unsigned int equal_items = item_count - class_count;
3338 : :
3339 : 128583 : unsigned int non_singular_classes_count = 0;
3340 : 128583 : unsigned int non_singular_classes_sum = 0;
3341 : :
3342 : 128583 : bool merged_p = false;
3343 : :
3344 : : /* PR lto/78211
3345 : : Sort functions in congruence classes by DECL_UID and do the same
3346 : : for the classes to not to break -fcompare-debug. */
3347 : :
3348 : 128583 : for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
3349 : 3891759 : it != m_classes.end (); ++it)
3350 : : {
3351 : 3859131 : for (unsigned int i = 0; i < (*it)->classes.length (); i++)
3352 : : {
3353 : 1977543 : congruence_class *c = (*it)->classes[i];
3354 : 3955086 : c->members.qsort (sort_sem_items_by_decl_uid);
3355 : : }
3356 : :
3357 : 3763176 : (*it)->classes.qsort (sort_congruence_classes_by_decl_uid);
3358 : : }
3359 : :
3360 : 128583 : for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
3361 : 3891759 : it != m_classes.end (); ++it)
3362 : 3859131 : for (unsigned int i = 0; i < (*it)->classes.length (); i++)
3363 : : {
3364 : 1977543 : congruence_class *c = (*it)->classes[i];
3365 : 2104308 : if (c->members.length () > 1)
3366 : : {
3367 : 126765 : non_singular_classes_count++;
3368 : 126765 : non_singular_classes_sum += c->members.length ();
3369 : : }
3370 : : }
3371 : :
3372 : 128583 : auto_vec<std::pair<congruence_class_group *, int> > classes (
3373 : 128583 : m_classes.elements ());
3374 : 128583 : for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
3375 : 3891759 : it != m_classes.end (); ++it)
3376 : : {
3377 : 1881588 : int uid = DECL_UID ((*it)->classes[0]->members[0]->decl);
3378 : 1881588 : classes.quick_push (std::pair<congruence_class_group *, int> (*it, uid));
3379 : : }
3380 : :
3381 : 128583 : classes.qsort (sort_congruence_class_groups_by_decl_uid);
3382 : :
3383 : 128583 : if (dump_file)
3384 : : {
3385 : 182 : fprintf (dump_file, "\nItem count: %u\n", item_count);
3386 : 182 : fprintf (dump_file, "Congruent classes before: %u, after: %u\n",
3387 : : prev_class_count, class_count);
3388 : 544 : fprintf (dump_file, "Average class size before: %.2f, after: %.2f\n",
3389 : 181 : prev_class_count ? 1.0f * item_count / prev_class_count : 0.0f,
3390 : 181 : class_count ? 1.0f * item_count / class_count : 0.0f);
3391 : 234 : fprintf (dump_file, "Average non-singular class size: %.2f, count: %u\n",
3392 : 52 : non_singular_classes_count ? 1.0f * non_singular_classes_sum /
3393 : : non_singular_classes_count : 0.0f,
3394 : : non_singular_classes_count);
3395 : 182 : fprintf (dump_file, "Equal symbols: %u\n", equal_items);
3396 : 182 : unsigned total = equal_items + non_singular_classes_count;
3397 : 238 : fprintf (dump_file, "Totally needed symbols: %u"
3398 : : ", fraction of loaded symbols: %.2f%%\n\n", total,
3399 : 56 : loaded_symbols ? 100.0f * total / loaded_symbols : 0.0f);
3400 : : }
3401 : :
3402 : : unsigned int l;
3403 : : std::pair<congruence_class_group *, int> *it;
3404 : 3891759 : FOR_EACH_VEC_ELT (classes, l, it)
3405 : 3859131 : for (unsigned int i = 0; i < it->first->classes.length (); i++)
3406 : : {
3407 : 1977543 : congruence_class *c = it->first->classes[i];
3408 : :
3409 : 1977543 : if (c->members.length () == 1)
3410 : 1850778 : continue;
3411 : :
3412 : 126765 : sem_item *source = c->members[0];
3413 : 126765 : bool this_merged_p = false;
3414 : :
3415 : 126765 : if (DECL_NAME (source->decl)
3416 : 126765 : && MAIN_NAME_P (DECL_NAME (source->decl)))
3417 : : /* If merge via wrappers, picking main as the target can be
3418 : : problematic. */
3419 : 0 : source = c->members[1];
3420 : :
3421 : 756194 : for (unsigned int j = 0; j < c->members.length (); j++)
3422 : : {
3423 : 629429 : sem_item *alias = c->members[j];
3424 : :
3425 : 629429 : if (alias == source)
3426 : 127504 : continue;
3427 : :
3428 : 502664 : dump_user_location_t loc
3429 : 502664 : = dump_user_location_t::from_function_decl (source->decl);
3430 : 502664 : if (dump_enabled_p ())
3431 : : {
3432 : 89 : dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
3433 : : "Semantic equality hit:%s->%s\n",
3434 : 89 : source->node->dump_name (),
3435 : 89 : alias->node->dump_name ());
3436 : 89 : dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
3437 : : "Assembler symbol names:%s->%s\n",
3438 : 89 : source->node->dump_asm_name (),
3439 : 89 : alias->node->dump_asm_name ());
3440 : : }
3441 : :
3442 : 502664 : if (lookup_attribute ("no_icf", DECL_ATTRIBUTES (alias->decl))
3443 : 502664 : || lookup_attribute ("no_icf", DECL_ATTRIBUTES (source->decl)))
3444 : : {
3445 : 739 : if (dump_enabled_p ())
3446 : 1 : dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
3447 : : "Merge operation is skipped due to no_icf "
3448 : : "attribute.\n");
3449 : 739 : continue;
3450 : : }
3451 : :
3452 : 501925 : if (dump_file && (dump_flags & TDF_DETAILS))
3453 : : {
3454 : 15 : source->dump_to_file (dump_file);
3455 : 15 : alias->dump_to_file (dump_file);
3456 : : }
3457 : :
3458 : 501925 : if (dbg_cnt (merged_ipa_icf))
3459 : : {
3460 : 501921 : bool merged = source->merge (alias);
3461 : 501921 : this_merged_p |= merged;
3462 : :
3463 : 501921 : if (merged && alias->type == VAR)
3464 : : {
3465 : 12221 : symtab_pair p = symtab_pair (source->node, alias->node);
3466 : 12221 : m_merged_variables.safe_push (p);
3467 : : }
3468 : : }
3469 : : }
3470 : :
3471 : 126765 : merged_p |= this_merged_p;
3472 : 126765 : if (this_merged_p
3473 : 19043 : && source->type == FUNC
3474 : 15280 : && (!flag_wpa || flag_checking))
3475 : : {
3476 : : unsigned i;
3477 : : tree name;
3478 : 2066227 : FOR_EACH_SSA_NAME (i, name, DECL_STRUCT_FUNCTION (source->decl))
3479 : : {
3480 : : /* We need to either merge or reset SSA_NAME_*_INFO.
3481 : : For merging we don't preserve the mapping between
3482 : : original and alias SSA_NAMEs from successful equals
3483 : : calls. */
3484 : 68443 : if (POINTER_TYPE_P (TREE_TYPE (name)))
3485 : : {
3486 : 6760 : if (SSA_NAME_PTR_INFO (name))
3487 : : {
3488 : 4065 : gcc_checking_assert (!flag_wpa);
3489 : 4065 : SSA_NAME_PTR_INFO (name) = NULL;
3490 : : }
3491 : : }
3492 : 61683 : else if (SSA_NAME_RANGE_INFO (name))
3493 : : {
3494 : 4703 : gcc_checking_assert (!flag_wpa);
3495 : 4703 : SSA_NAME_RANGE_INFO (name) = NULL;
3496 : : }
3497 : : }
3498 : : }
3499 : : }
3500 : :
3501 : 128583 : if (!m_merged_variables.is_empty ())
3502 : 1866 : fixup_points_to_sets ();
3503 : :
3504 : 128583 : return merged_p;
3505 : 128583 : }
3506 : :
3507 : : /* Fixup points to set PT. */
3508 : :
3509 : : void
3510 : 1133230 : sem_item_optimizer::fixup_pt_set (struct pt_solution *pt)
3511 : : {
3512 : 1133230 : if (pt->vars == NULL)
3513 : 1133230 : return;
3514 : :
3515 : : unsigned i;
3516 : : symtab_pair *item;
3517 : 11143885 : FOR_EACH_VEC_ELT (m_merged_variables, i, item)
3518 : 10147882 : if (bitmap_bit_p (pt->vars, DECL_UID (item->second->decl)))
3519 : 8551 : bitmap_set_bit (pt->vars, DECL_UID (item->first->decl));
3520 : : }
3521 : :
3522 : : /* Set all points-to UIDs of aliases pointing to node N as UID. */
3523 : :
3524 : : static void
3525 : 187990 : set_alias_uids (symtab_node *n, int uid)
3526 : : {
3527 : 187990 : ipa_ref *ref;
3528 : 363759 : FOR_EACH_ALIAS (n, ref)
3529 : : {
3530 : 175769 : if (dump_file)
3531 : 19 : fprintf (dump_file, " Setting points-to UID of [%s] as %d\n",
3532 : 19 : ref->referring->dump_asm_name (), uid);
3533 : :
3534 : 175769 : SET_DECL_PT_UID (ref->referring->decl, uid);
3535 : 175769 : set_alias_uids (ref->referring, uid);
3536 : : }
3537 : 187990 : }
3538 : :
3539 : : /* Fixup points to analysis info. */
3540 : :
3541 : : void
3542 : 1866 : sem_item_optimizer::fixup_points_to_sets (void)
3543 : : {
3544 : : /* TODO: remove in GCC 9 and trigger PTA re-creation after IPA passes. */
3545 : 1866 : cgraph_node *cnode;
3546 : :
3547 : 61936 : FOR_EACH_DEFINED_FUNCTION (cnode)
3548 : : {
3549 : 60070 : tree name;
3550 : 60070 : unsigned i;
3551 : 60070 : function *fn = DECL_STRUCT_FUNCTION (cnode->decl);
3552 : 60070 : if (!gimple_in_ssa_p (fn))
3553 : 3333 : continue;
3554 : :
3555 : 2276730 : FOR_EACH_SSA_NAME (i, name, fn)
3556 : 4114293 : if (POINTER_TYPE_P (TREE_TYPE (name))
3557 : 2248005 : && SSA_NAME_PTR_INFO (name))
3558 : 336402 : fixup_pt_set (&SSA_NAME_PTR_INFO (name)->pt);
3559 : 56737 : fixup_pt_set (&fn->gimple_df->escaped);
3560 : 56737 : fixup_pt_set (&fn->gimple_df->escaped_return);
3561 : :
3562 : : /* The above gets us to 99% I guess, at least catching the
3563 : : address compares. Below also gets us aliasing correct
3564 : : but as said we're giving leeway to the situation with
3565 : : readonly vars anyway, so ... */
3566 : 56737 : basic_block bb;
3567 : 683979 : FOR_EACH_BB_FN (bb, fn)
3568 : 5024162 : for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
3569 : 3769678 : gsi_next (&gsi))
3570 : : {
3571 : 4111355 : gcall *call = dyn_cast<gcall *> (gsi_stmt (gsi));
3572 : 341677 : if (call)
3573 : : {
3574 : 341677 : fixup_pt_set (gimple_call_use_set (call));
3575 : 341677 : fixup_pt_set (gimple_call_clobber_set (call));
3576 : : }
3577 : : }
3578 : : }
3579 : :
3580 : : unsigned i;
3581 : : symtab_pair *item;
3582 : 14087 : FOR_EACH_VEC_ELT (m_merged_variables, i, item)
3583 : 12221 : set_alias_uids (item->first, DECL_UID (item->first->decl));
3584 : 1866 : }
3585 : :
3586 : : /* Dump function prints all class members to a FILE with an INDENT. */
3587 : :
3588 : : void
3589 : 320 : congruence_class::dump (FILE *file, unsigned int indent) const
3590 : : {
3591 : 640 : FPRINTF_SPACES (file, indent, "class with id: %u, hash: %u, items: %u\n",
3592 : 320 : id, members[0]->get_hash (), members.length ());
3593 : :
3594 : 320 : FPUTS_SPACES (file, indent + 2, "");
3595 : 741 : for (unsigned i = 0; i < members.length (); i++)
3596 : 421 : fprintf (file, "%s ", members[i]->node->dump_asm_name ());
3597 : :
3598 : 320 : fprintf (file, "\n");
3599 : 320 : }
3600 : :
3601 : : /* Returns true if there's a member that is used from another group. */
3602 : :
3603 : : bool
3604 : 3923179 : congruence_class::is_class_used (void)
3605 : : {
3606 : 4960734 : for (unsigned int i = 0; i < members.length (); i++)
3607 : 3999732 : if (members[i]->referenced_by_count)
3608 : : return true;
3609 : :
3610 : : return false;
3611 : : }
3612 : :
3613 : : /* Generate pass summary for IPA ICF pass. */
3614 : :
3615 : : static void
3616 : 124317 : ipa_icf_generate_summary (void)
3617 : : {
3618 : 124317 : if (!optimizer)
3619 : 124317 : optimizer = new sem_item_optimizer ();
3620 : :
3621 : 124317 : optimizer->register_hooks ();
3622 : 124317 : optimizer->parse_funcs_and_vars ();
3623 : 124317 : }
3624 : :
3625 : : /* Write pass summary for IPA ICF pass. */
3626 : :
3627 : : static void
3628 : 19421 : ipa_icf_write_summary (void)
3629 : : {
3630 : 19421 : gcc_assert (optimizer);
3631 : :
3632 : 19421 : optimizer->write_summary ();
3633 : 19421 : }
3634 : :
3635 : : /* Read pass summary for IPA ICF pass. */
3636 : :
3637 : : static void
3638 : 13167 : ipa_icf_read_summary (void)
3639 : : {
3640 : 13167 : if (!optimizer)
3641 : 13167 : optimizer = new sem_item_optimizer ();
3642 : :
3643 : 13167 : optimizer->read_summary ();
3644 : 13167 : optimizer->register_hooks ();
3645 : 13167 : }
3646 : :
3647 : : /* Semantic equality execution function. */
3648 : :
3649 : : static unsigned int
3650 : 128583 : ipa_icf_driver (void)
3651 : : {
3652 : 128583 : gcc_assert (optimizer);
3653 : :
3654 : 128583 : bool merged_p = optimizer->execute ();
3655 : :
3656 : 128583 : delete optimizer;
3657 : 128583 : optimizer = NULL;
3658 : :
3659 : 128583 : return merged_p ? TODO_remove_functions : 0;
3660 : : }
3661 : :
3662 : : const pass_data pass_data_ipa_icf =
3663 : : {
3664 : : IPA_PASS, /* type */
3665 : : "icf", /* name */
3666 : : OPTGROUP_IPA, /* optinfo_flags */
3667 : : TV_IPA_ICF, /* tv_id */
3668 : : 0, /* properties_required */
3669 : : 0, /* properties_provided */
3670 : : 0, /* properties_destroyed */
3671 : : 0, /* todo_flags_start */
3672 : : 0, /* todo_flags_finish */
3673 : : };
3674 : :
3675 : : class pass_ipa_icf : public ipa_opt_pass_d
3676 : : {
3677 : : public:
3678 : 289302 : pass_ipa_icf (gcc::context *ctxt)
3679 : : : ipa_opt_pass_d (pass_data_ipa_icf, ctxt,
3680 : : ipa_icf_generate_summary, /* generate_summary */
3681 : : ipa_icf_write_summary, /* write_summary */
3682 : : ipa_icf_read_summary, /* read_summary */
3683 : : NULL, /*
3684 : : write_optimization_summary */
3685 : : NULL, /*
3686 : : read_optimization_summary */
3687 : : NULL, /* stmt_fixup */
3688 : : 0, /* function_transform_todo_flags_start */
3689 : : NULL, /* function_transform */
3690 : 289302 : NULL) /* variable_transform */
3691 : 289302 : {}
3692 : :
3693 : : /* opt_pass methods: */
3694 : 593344 : bool gate (function *) final override
3695 : : {
3696 : 593344 : return in_lto_p || flag_ipa_icf_variables || flag_ipa_icf_functions;
3697 : : }
3698 : :
3699 : 128583 : unsigned int execute (function *) final override
3700 : : {
3701 : 128583 : return ipa_icf_driver();
3702 : : }
3703 : : }; // class pass_ipa_icf
3704 : :
3705 : : } // ipa_icf namespace
3706 : :
3707 : : ipa_opt_pass_d *
3708 : 289302 : make_pass_ipa_icf (gcc::context *ctxt)
3709 : : {
3710 : 289302 : return new ipa_icf::pass_ipa_icf (ctxt);
3711 : : }
3712 : :
3713 : : /* Reset all state within ipa-icf.cc so that we can rerun the compiler
3714 : : within the same process. For use by toplev::finalize. */
3715 : :
3716 : : void
3717 : 260333 : ipa_icf_cc_finalize (void)
3718 : : {
3719 : 260333 : ipa_icf::optimizer = NULL;
3720 : 260333 : }
|