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