Line data Source code
1 : /* IPA visibility pass
2 : Copyright (C) 2003-2026 Free Software Foundation, Inc.
3 :
4 : This file is part of GCC.
5 :
6 : GCC is free software; you can redistribute it and/or modify it under
7 : the terms of the GNU General Public License as published by the Free
8 : Software Foundation; either version 3, or (at your option) any later
9 : version.
10 :
11 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with GCC; see the file COPYING3. If not see
18 : <http://www.gnu.org/licenses/>. */
19 :
20 : /* This file implements two related passes:
21 :
22 : - pass_data_ipa_function_and_variable_visibility run just after
23 : symbol table, references and callgraph are built
24 :
25 : - pass_data_ipa_function_and_variable_visibility run as first
26 : proper IPA pass (that is after early optimization, or, (with LTO)
27 : as a first pass done at link-time.
28 :
29 : Purpose of both passes is to set correctly visibility properties
30 : of all symbols. This includes:
31 :
32 : - Symbol privatization:
33 :
34 : Some symbols that are declared public by frontend may be
35 : turned local (either by -fwhole-program flag, by linker plugin feedback
36 : or by other reasons)
37 :
38 : - Discovery of local functions:
39 :
40 : A local function is one whose calls can occur only in the current
41 : compilation unit and all its calls are explicit, so we can change
42 : its calling convention. We simply mark all static functions whose
43 : address is not taken as local.
44 :
45 : externally_visible flag is set for symbols that cannot be privatized.
46 : For privatized symbols we clear TREE_PUBLIC flag and dismantle comdat
47 : group.
48 :
49 : - Dismantling of comdat groups:
50 :
51 : Comdat group represent a section that may be replaced by linker by
52 : a different copy of the same section from other unit.
53 : If we have resolution information (from linker plugin) and we know that
54 : a given comdat gorup is prevailing, we can dismantle it and turn symbols
55 : into normal symbols. If the resolution information says that the
56 : section was previaled by copy from non-LTO code, we can also dismantle
57 : it and turn all symbols into external.
58 :
59 : - Local aliases:
60 :
61 : Some symbols can be interposed by dynamic linker. Refering to these
62 : symbols is expensive, since it needs to be overwritable by the dynamic
63 : linker. In some cases we know that the interposition does not change
64 : semantic and we can always refer to a local copy (as in the case of
65 : inline function). In this case we produce a local alias and redirect
66 : calls to it.
67 :
68 : TODO: This should be done for references, too.
69 :
70 : - Removal of static ocnstructors and destructors that have no side effects.
71 :
72 : - Regularization of several oddities introduced by frontends that may
73 : be impractical later in the optimization queue. */
74 :
75 : #include "config.h"
76 : #include "system.h"
77 : #include "coretypes.h"
78 : #include "tm.h"
79 : #include "function.h"
80 : #include "tree.h"
81 : #include "gimple-expr.h"
82 : #include "tree-pass.h"
83 : #include "cgraph.h"
84 : #include "calls.h"
85 : #include "varasm.h"
86 : #include "ipa-utils.h"
87 : #include "stringpool.h"
88 : #include "attribs.h"
89 :
90 : /* Return true when NODE cannot be local. Worker for cgraph_local_node_p. */
91 :
92 : static bool
93 5026243 : non_local_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
94 : {
95 5026243 : return !(node->only_called_directly_or_aliased_p ()
96 : /* i386 would need update to output thunk with local calling
97 : conventions. */
98 504678 : && !node->thunk
99 504678 : && node->definition
100 504676 : && !DECL_EXTERNAL (node->decl)
101 258173 : && !lookup_attribute ("noipa", DECL_ATTRIBUTES (node->decl))
102 257091 : && !node->externally_visible
103 257091 : && !node->used_from_other_partition
104 257091 : && !node->in_other_partition
105 257091 : && node->get_availability () >= AVAIL_AVAILABLE
106 257091 : && !DECL_STATIC_CONSTRUCTOR (node->decl)
107 257091 : && !DECL_STATIC_DESTRUCTOR (node->decl));
108 : }
109 :
110 : /* Return true when function can be marked local. */
111 :
112 : bool
113 4979218 : cgraph_node::local_p (void)
114 : {
115 4985199 : cgraph_node *n = ultimate_alias_target ();
116 :
117 4985199 : if (n->thunk)
118 5981 : return n->callees->callee->local_p ();
119 4979218 : return !n->call_for_symbol_thunks_and_aliases (non_local_p,
120 4979218 : NULL, true);
121 : }
122 :
123 : /* A helper for comdat_can_be_unshared_p. */
124 :
125 : static bool
126 2085 : comdat_can_be_unshared_p_1 (symtab_node *node)
127 : {
128 2085 : if (!node->externally_visible)
129 : return true;
130 1852 : if (node->address_can_be_compared_p ())
131 : {
132 : struct ipa_ref *ref;
133 :
134 1171 : for (unsigned int i = 0; node->iterate_referring (i, ref); i++)
135 635 : if (ref->address_matters_p ())
136 466 : return false;
137 : }
138 :
139 : /* If the symbol is used in some weird way, better to not touch it. */
140 1386 : if (node->force_output)
141 : return false;
142 :
143 : /* Explicit instantiations needs to be output when possibly
144 : used externally. */
145 1386 : if (node->forced_by_abi
146 58 : && TREE_PUBLIC (node->decl)
147 58 : && (node->resolution != LDPR_PREVAILING_DEF_IRONLY
148 58 : && !flag_whole_program))
149 : return false;
150 :
151 : /* Non-readonly and volatile variables cannot be duplicated. */
152 : if (is_a <varpool_node *> (node)
153 202 : && (!TREE_READONLY (node->decl)
154 199 : || TREE_THIS_VOLATILE (node->decl)))
155 : return false;
156 : return true;
157 : }
158 :
159 : /* COMDAT functions must be shared only if they have address taken,
160 : otherwise we can produce our own private implementation with
161 : -fwhole-program.
162 : Return true when turning COMDAT function static cannot lead to wrong
163 : code when the resulting object links with a library defining same COMDAT.
164 :
165 : Virtual functions do have their addresses taken from the vtables,
166 : but in C++ there is no way to compare their addresses for equality. */
167 :
168 : static bool
169 1569 : comdat_can_be_unshared_p (symtab_node *node)
170 : {
171 1569 : if (!comdat_can_be_unshared_p_1 (node))
172 : return false;
173 1048 : if (node->same_comdat_group)
174 : {
175 : symtab_node *next;
176 :
177 : /* If more than one function is in the same COMDAT group, it must
178 : be shared even if just one function in the comdat group has
179 : address taken. */
180 516 : for (next = node->same_comdat_group;
181 874 : next != node; next = next->same_comdat_group)
182 516 : if (!comdat_can_be_unshared_p_1 (next))
183 : return false;
184 : }
185 : return true;
186 : }
187 :
188 : /* Return true when function NODE should be considered externally visible. */
189 :
190 : static bool
191 8567244 : cgraph_externally_visible_p (struct cgraph_node *node,
192 : bool whole_program)
193 : {
194 8567293 : while (node->transparent_alias && node->definition)
195 49 : node = node->get_alias_target ();
196 8567244 : if (!node->definition)
197 : return false;
198 5093361 : if (!TREE_PUBLIC (node->decl)
199 5093361 : || DECL_EXTERNAL (node->decl))
200 : return false;
201 4154910 : if (node->ref_by_asm)
202 : return true;
203 :
204 : /* Do not try to localize built-in functions yet. One of problems is that we
205 : end up mangling their asm for WHOPR that makes it impossible to call them
206 : using the implicit built-in declarations anymore. Similarly this enables
207 : us to remove them as unreachable before actual calls may appear during
208 : expansion or folding. */
209 4154875 : if (fndecl_built_in_p (node->decl))
210 : return true;
211 :
212 : /* If linker counts on us, we must preserve the function. */
213 4144349 : if (node->used_from_object_file_p ())
214 : return true;
215 4136661 : if (DECL_PRESERVE_P (node->decl))
216 : return true;
217 4129015 : if (lookup_attribute ("externally_visible",
218 4129015 : DECL_ATTRIBUTES (node->decl)))
219 : return true;
220 4076176 : if (lookup_attribute ("noipa", DECL_ATTRIBUTES (node->decl)))
221 : return true;
222 : if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
223 : && lookup_attribute ("dllexport",
224 : DECL_ATTRIBUTES (node->decl)))
225 : return true;
226 :
227 : /* Limitation of gas requires us to output targets of symver aliases as
228 : global symbols. This is binutils PR 25295. */
229 : ipa_ref *ref;
230 4425994 : FOR_EACH_ALIAS (node, ref)
231 388347 : if (ref->referring->symver)
232 : return true;
233 :
234 4037647 : if (node->resolution == LDPR_PREVAILING_DEF_IRONLY)
235 : return false;
236 : /* When doing LTO or whole program, we can bring COMDAT functions static.
237 : This improves code quality and we know we will duplicate them at most twice
238 : (in the case that we are not using plugin and link with object file
239 : implementing same COMDAT) */
240 4000735 : if (((in_lto_p || whole_program) && !flag_incremental_link)
241 31492 : && DECL_COMDAT (node->decl)
242 4001692 : && comdat_can_be_unshared_p (node))
243 : return false;
244 :
245 : /* When doing link time optimizations, hidden symbols become local. */
246 30535 : if ((in_lto_p && !flag_incremental_link)
247 30281 : && (DECL_VISIBILITY (node->decl) == VISIBILITY_HIDDEN
248 30279 : || DECL_VISIBILITY (node->decl) == VISIBILITY_INTERNAL)
249 : /* Be sure that node is defined in IR file, not in other object
250 : file. In that case we don't set used_from_other_object_file. */
251 3999792 : && node->definition)
252 : ;
253 3999788 : else if (!whole_program)
254 : return true;
255 :
256 290 : if (MAIN_NAME_P (DECL_NAME (node->decl)))
257 : return true;
258 :
259 : return false;
260 : }
261 :
262 : /* Return true when variable should be considered externally visible. */
263 :
264 : bool
265 5865760 : varpool_node::externally_visible_p (void)
266 : {
267 5865768 : while (transparent_alias && definition)
268 8 : return get_alias_target ()->externally_visible_p ();
269 5865760 : if (DECL_EXTERNAL (decl))
270 : return true;
271 :
272 5847068 : if (!TREE_PUBLIC (decl))
273 : return false;
274 2954121 : if (ref_by_asm)
275 : return true;
276 :
277 : /* If linker counts on us, we must preserve the function. */
278 2954057 : if (used_from_object_file_p ())
279 : return true;
280 :
281 : /* Bringing TLS variables local may cause dynamic linker failures
282 : on limits of static TLS vars. */
283 2954046 : if (DECL_THREAD_LOCAL_P (decl)
284 2960105 : && (DECL_TLS_MODEL (decl) != TLS_MODEL_EMULATED
285 6059 : && DECL_TLS_MODEL (decl) != TLS_MODEL_INITIAL_EXEC))
286 : return true;
287 :
288 2948121 : if (DECL_HARD_REGISTER (decl))
289 : return true;
290 2947948 : if (DECL_PRESERVE_P (decl))
291 : return true;
292 2946575 : if (lookup_attribute ("externally_visible",
293 2946575 : DECL_ATTRIBUTES (decl)))
294 : return true;
295 : if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
296 : && lookup_attribute ("dllexport",
297 : DECL_ATTRIBUTES (decl)))
298 : return true;
299 :
300 : /* Limitation of gas requires us to output targets of symver aliases as
301 : global symbols. This is binutils PR 25295. */
302 : ipa_ref *ref;
303 2946708 : FOR_EACH_ALIAS (this, ref)
304 204 : if (ref->referring->symver)
305 : return true;
306 :
307 2946504 : if (resolution == LDPR_PREVAILING_DEF_IRONLY)
308 : return false;
309 :
310 : /* As a special case, the COMDAT virtual tables can be unshared.
311 : In LTO mode turn vtables into static variables. The variable is readonly,
312 : so this does not enable more optimization, but referring static var
313 : is faster for dynamic linking. Also this match logic hidding vtables
314 : from LTO symbol tables. */
315 2934507 : if (((in_lto_p || flag_whole_program) && !flag_incremental_link)
316 6564 : && DECL_COMDAT (decl)
317 2935119 : && comdat_can_be_unshared_p (this))
318 : return false;
319 :
320 : /* When doing link time optimizations, hidden symbols become local. */
321 6433 : if (in_lto_p && !flag_incremental_link
322 6254 : && (DECL_VISIBILITY (decl) == VISIBILITY_HIDDEN
323 6253 : || DECL_VISIBILITY (decl) == VISIBILITY_INTERNAL)
324 : /* Be sure that node is defined in IR file, not in other object
325 : file. In that case we don't set used_from_other_object_file. */
326 2934405 : && definition)
327 : ;
328 2934403 : else if (!flag_whole_program)
329 : return true;
330 :
331 : /* Do not attempt to privatize COMDATS by default.
332 : This would break linking with C++ libraries sharing
333 : inline definitions.
334 :
335 : FIXME: We can do so for readonly vars with no address taken and
336 : possibly also for vtables since no direct pointer comparsion is done.
337 : It might be interesting to do so to reduce linking overhead. */
338 240 : if (DECL_COMDAT (decl) || DECL_WEAK (decl))
339 : return true;
340 : return false;
341 : }
342 :
343 : /* Return true if reference to NODE can be replaced by a local alias.
344 : Local aliases save dynamic linking overhead and enable more optimizations.
345 : */
346 :
347 : static bool
348 2980322 : can_replace_by_local_alias (symtab_node *node)
349 : {
350 : /* If aliases aren't supported, we can't do replacement. */
351 2980322 : if (!TARGET_SUPPORTS_ALIASES)
352 : return false;
353 :
354 : /* Weakrefs have a reason to be non-local. Be sure we do not replace
355 : them. */
356 2980334 : while (node->transparent_alias && node->definition && !node->weakref)
357 12 : node = node->get_alias_target ();
358 2980322 : if (node->weakref)
359 : return false;
360 :
361 2980320 : return (node->get_availability () > AVAIL_INTERPOSABLE
362 2903104 : && !decl_binds_to_current_def_p (node->decl)
363 4924621 : && !node->can_be_discarded_p ());
364 : }
365 :
366 : /* Return true if we can replace reference to NODE by local alias
367 : within a virtual table. Generally we can replace function pointers
368 : and virtual table pointers. */
369 :
370 : static bool
371 256447 : can_replace_by_local_alias_in_vtable (symtab_node *node)
372 : {
373 256447 : if (is_a <varpool_node *> (node)
374 143585 : && !DECL_VIRTUAL_P (node->decl))
375 : return false;
376 172421 : return can_replace_by_local_alias (node);
377 : }
378 :
379 : /* walk_tree callback that rewrites initializer references. */
380 :
381 : static tree
382 25 : update_vtable_references (tree *tp, int *walk_subtrees,
383 : void *data ATTRIBUTE_UNUSED)
384 : {
385 25 : if (VAR_OR_FUNCTION_DECL_P (*tp))
386 : {
387 5 : if (can_replace_by_local_alias_in_vtable (symtab_node::get (*tp)))
388 4 : *tp = symtab_node::get (*tp)->noninterposable_alias ()->decl;
389 5 : *walk_subtrees = 0;
390 : }
391 20 : else if (IS_TYPE_OR_DECL_P (*tp))
392 0 : *walk_subtrees = 0;
393 25 : return NULL;
394 : }
395 :
396 : /* In LTO we can remove COMDAT groups and weak symbols.
397 : Either turn them into normal symbols or external symbol depending on
398 : resolution info. */
399 :
400 : static void
401 14430626 : update_visibility_by_resolution_info (symtab_node * node)
402 : {
403 14430626 : bool define;
404 :
405 14430626 : if (!node->externally_visible
406 7075046 : || (!DECL_WEAK (node->decl) && !DECL_ONE_ONLY (node->decl))
407 17131685 : || node->resolution == LDPR_UNKNOWN)
408 14430256 : return;
409 :
410 740 : define = (node->resolution == LDPR_PREVAILING_DEF_IRONLY
411 : || node->resolution == LDPR_PREVAILING_DEF
412 370 : || node->resolution == LDPR_UNDEF
413 370 : || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP);
414 :
415 : /* The linker decisions ought to agree in the whole group. */
416 370 : if (node->same_comdat_group)
417 108 : for (symtab_node *next = node->same_comdat_group;
418 176 : next != node; next = next->same_comdat_group)
419 : {
420 108 : if (!next->externally_visible || next->transparent_alias)
421 4 : continue;
422 :
423 104 : bool same_def
424 104 : = define == (next->resolution == LDPR_PREVAILING_DEF_IRONLY
425 : || next->resolution == LDPR_PREVAILING_DEF
426 : || next->resolution == LDPR_UNDEF
427 104 : || next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP);
428 104 : gcc_assert (in_lto_p || same_def);
429 104 : if (!same_def)
430 : return;
431 : }
432 :
433 370 : if (node->same_comdat_group)
434 108 : for (symtab_node *next = node->same_comdat_group;
435 176 : next != node; next = next->same_comdat_group)
436 : {
437 : /* During incremental linking we need to keep symbol weak for future
438 : linking. We can still drop definition if we know non-LTO world
439 : prevails. */
440 108 : if (!flag_incremental_link)
441 : {
442 8 : DECL_WEAK (next->decl) = false;
443 8 : next->set_comdat_group (NULL);
444 : }
445 108 : if (!define)
446 : {
447 0 : if (next->externally_visible)
448 0 : DECL_EXTERNAL (next->decl) = true;
449 0 : next->set_comdat_group (NULL);
450 : }
451 : }
452 :
453 : /* During incremental linking we need to keep symbol weak for future
454 : linking. We can still drop definition if we know non-LTO world prevails. */
455 370 : if (!flag_incremental_link)
456 : {
457 217 : DECL_WEAK (node->decl) = false;
458 217 : node->set_comdat_group (NULL);
459 217 : node->dissolve_same_comdat_group_list ();
460 : }
461 370 : if (!define)
462 : {
463 0 : DECL_EXTERNAL (node->decl) = true;
464 0 : node->set_comdat_group (NULL);
465 0 : node->dissolve_same_comdat_group_list ();
466 : }
467 : }
468 :
469 : /* Try to get rid of weakref. */
470 :
471 : static void
472 320 : optimize_weakref (symtab_node *node)
473 : {
474 320 : bool strip_weakref = false;
475 320 : bool static_alias = false;
476 :
477 320 : gcc_assert (node->weakref);
478 :
479 : /* Weakrefs with no target defined cannot be optimized. */
480 320 : if (!node->analyzed)
481 : return;
482 47 : symtab_node *target = node->get_alias_target ();
483 :
484 : /* Weakrefs to weakrefs can be optimized only if target can be. */
485 47 : if (target->weakref)
486 16 : optimize_weakref (target);
487 47 : if (target->weakref)
488 : return;
489 :
490 : /* If we have definition of weakref's target and we know it binds locally,
491 : we can turn weakref to static alias. */
492 31 : if (TARGET_SUPPORTS_ALIASES
493 31 : && target->definition && decl_binds_to_current_def_p (target->decl))
494 : strip_weakref = static_alias = true;
495 : /* Otherwise we can turn weakref into transparent alias. This transformation
496 : may break asm statements which directly refers to symbol name and expect
497 : GNU as to translate it via .weakref directive. So do not optimize when
498 : DECL_PRESERVED is set and .weakref is supported. */
499 2 : else if ((!DECL_PRESERVE_P (target->decl)
500 0 : || IDENTIFIER_TRANSPARENT_ALIAS (DECL_ASSEMBLER_NAME (node->decl)))
501 2 : && !DECL_WEAK (target->decl)
502 0 : && !DECL_EXTERNAL (target->decl)
503 2 : && ((target->definition && !target->can_be_discarded_p ())
504 0 : || target->resolution != LDPR_UNDEF))
505 : strip_weakref = true;
506 2 : if (!strip_weakref)
507 2 : return;
508 29 : node->weakref = false;
509 29 : IDENTIFIER_TRANSPARENT_ALIAS (DECL_ASSEMBLER_NAME (node->decl)) = 0;
510 29 : TREE_CHAIN (DECL_ASSEMBLER_NAME (node->decl)) = NULL_TREE;
511 29 : DECL_ATTRIBUTES (node->decl) = remove_attribute ("weakref",
512 29 : DECL_ATTRIBUTES
513 : (node->decl));
514 :
515 29 : if (dump_file)
516 0 : fprintf (dump_file, "Optimizing weakref %s %s\n",
517 : node->dump_name (),
518 : static_alias ? "as static alias" : "as transparent alias");
519 :
520 29 : if (static_alias)
521 : {
522 : /* make_decl_local will shortcircuit if it doesn't see TREE_PUBLIC.
523 : be sure it really clears the WEAK flag. */
524 29 : TREE_PUBLIC (node->decl) = true;
525 29 : node->make_decl_local ();
526 29 : node->forced_by_abi = false;
527 29 : node->resolution = LDPR_PREVAILING_DEF_IRONLY;
528 29 : node->externally_visible = false;
529 29 : gcc_assert (!DECL_WEAK (node->decl));
530 29 : node->transparent_alias = false;
531 : }
532 : else
533 : {
534 0 : symtab->change_decl_assembler_name
535 0 : (node->decl, DECL_ASSEMBLER_NAME (node->get_alias_target ()->decl));
536 0 : node->transparent_alias = true;
537 0 : node->copy_visibility_from (target);
538 : }
539 29 : gcc_assert (node->alias);
540 : }
541 :
542 : /* NODE is an externally visible definition, which we've discovered is
543 : not needed externally. Make it local to this compilation. */
544 :
545 : static void
546 3612172 : localize_node (bool whole_program, symtab_node *node)
547 : {
548 3612172 : gcc_assert (whole_program || in_lto_p || !TREE_PUBLIC (node->decl));
549 :
550 : /* It is possible that one comdat group contains both hidden and non-hidden
551 : symbols. In this case we can privatize all hidden symbol but we need
552 : to keep non-hidden exported. */
553 3612172 : if (node->same_comdat_group
554 9029 : && (node->resolution == LDPR_PREVAILING_DEF_IRONLY
555 7625 : || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP))
556 : {
557 : symtab_node *next;
558 1708 : for (next = node->same_comdat_group;
559 3272 : next != node; next = next->same_comdat_group)
560 1789 : if (next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP
561 1708 : || next->resolution == LDPR_PREVAILING_DEF)
562 : break;
563 1564 : if (node != next)
564 : {
565 81 : if (!node->transparent_alias)
566 : {
567 81 : node->resolution = LDPR_PREVAILING_DEF_IRONLY;
568 81 : node->make_decl_local ();
569 81 : if (!flag_incremental_link)
570 81 : node->unique_name |= true;
571 81 : return;
572 : }
573 : }
574 : }
575 : /* For similar reason do not privatize whole comdat when seeing comdat
576 : local. Wait for non-comdat symbol to be privatized first. */
577 3612091 : if (node->comdat_local_p ())
578 : return;
579 :
580 3604824 : if (node->same_comdat_group && TREE_PUBLIC (node->decl))
581 : {
582 2039 : for (symtab_node *next = node->same_comdat_group;
583 3720 : next != node; next = next->same_comdat_group)
584 : {
585 2039 : next->set_comdat_group (NULL);
586 2039 : if (!next->alias)
587 1820 : next->set_section (NULL);
588 2039 : if (!next->transparent_alias)
589 2039 : next->make_decl_local ();
590 2039 : next->unique_name
591 2039 : |= ((next->resolution == LDPR_PREVAILING_DEF_IRONLY
592 386 : || next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
593 1653 : && TREE_PUBLIC (next->decl)
594 2039 : && !flag_incremental_link);
595 : }
596 :
597 : /* Now everything's localized, the grouping has no meaning, and
598 : will cause crashes if we keep it around. */
599 1681 : node->dissolve_same_comdat_group_list ();
600 : }
601 :
602 3604824 : node->unique_name
603 7209648 : |= ((node->resolution == LDPR_PREVAILING_DEF_IRONLY
604 1835500 : || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
605 1769712 : && TREE_PUBLIC (node->decl)
606 3654108 : && !flag_incremental_link);
607 :
608 3604824 : if (TREE_PUBLIC (node->decl))
609 50218 : node->set_comdat_group (NULL);
610 3604824 : if (DECL_COMDAT (node->decl) && !node->alias)
611 5227 : node->set_section (NULL);
612 3604824 : if (!node->transparent_alias)
613 : {
614 3604824 : node->resolution = LDPR_PREVAILING_DEF_IRONLY;
615 3604824 : node->make_decl_local ();
616 : }
617 : }
618 :
619 : /* Decide on visibility of all symbols. */
620 :
621 : static unsigned int
622 463971 : function_and_variable_visibility (bool whole_program)
623 : {
624 463971 : struct cgraph_node *node;
625 463971 : varpool_node *vnode;
626 :
627 : /* All aliases should be processed at this point. */
628 463971 : gcc_checking_assert (!alias_pairs || !alias_pairs->length ());
629 :
630 463971 : if (TARGET_SUPPORTS_ALIASES)
631 : {
632 5557079 : FOR_EACH_DEFINED_FUNCTION (node)
633 : {
634 5093108 : if (node->get_availability () != AVAIL_INTERPOSABLE
635 114976 : || DECL_EXTERNAL (node->decl)
636 114976 : || node->has_aliases_p ()
637 5203661 : || lookup_attribute ("noipa", DECL_ATTRIBUTES (node->decl)))
638 5023288 : continue;
639 :
640 69820 : cgraph_node *alias = 0;
641 69820 : cgraph_edge *next_edge;
642 317345 : for (cgraph_edge *e = node->callees; e; e = next_edge)
643 : {
644 247525 : next_edge = e->next_callee;
645 : /* Recursive function calls usually can't be interposed. */
646 :
647 247525 : if (!e->recursive_p ())
648 246586 : continue;
649 :
650 939 : if (!alias)
651 : {
652 263 : alias
653 263 : = dyn_cast<cgraph_node *> (node->noninterposable_alias ());
654 263 : gcc_assert (alias && alias != node);
655 : }
656 :
657 939 : e->redirect_callee (alias);
658 939 : if (gimple_has_body_p (e->caller->decl))
659 : {
660 939 : push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
661 939 : cgraph_edge::redirect_call_stmt_to_callee (e);
662 939 : pop_cfun ();
663 : }
664 : }
665 : }
666 : }
667 :
668 9031215 : FOR_EACH_FUNCTION (node)
669 : {
670 8567244 : int flags = flags_from_decl_or_type (node->decl);
671 :
672 : /* Optimize away PURE and CONST constructors and destructors. */
673 8567244 : if (node->analyzed
674 5093371 : && (DECL_STATIC_CONSTRUCTOR (node->decl)
675 5054183 : || DECL_STATIC_DESTRUCTOR (node->decl))
676 39819 : && (flags & (ECF_CONST | ECF_PURE))
677 23 : && !(flags & ECF_LOOPING_CONST_OR_PURE)
678 8567244 : && opt_for_fn (node->decl, optimize))
679 : {
680 0 : DECL_STATIC_CONSTRUCTOR (node->decl) = 0;
681 0 : DECL_STATIC_DESTRUCTOR (node->decl) = 0;
682 : }
683 :
684 : /* Frontends and alias code marks nodes as needed before parsing
685 : is finished. We may end up marking as node external nodes
686 : where this flag is meaningless strip it. */
687 8567244 : if (DECL_EXTERNAL (node->decl) || !node->definition)
688 : {
689 3743388 : node->force_output = 0;
690 3743388 : node->forced_by_abi = 0;
691 : }
692 :
693 : /* C++ FE on lack of COMDAT support create local COMDAT functions
694 : (that ought to be shared but cannot due to object format
695 : limitations). It is necessary to keep the flag to make rest of C++ FE
696 : happy. Clear the flag here to avoid confusion in middle-end. */
697 8567244 : if (DECL_COMDAT (node->decl) && !TREE_PUBLIC (node->decl))
698 29 : DECL_COMDAT (node->decl) = 0;
699 :
700 : /* For external decls stop tracking same_comdat_group. It doesn't matter
701 : what comdat group they are in when they won't be emitted in this TU.
702 :
703 : An exception is LTO where we may end up with both external
704 : and non-external declarations in the same comdat group in
705 : the case declarations was not merged. */
706 8567244 : if (node->same_comdat_group && DECL_EXTERNAL (node->decl) && !in_lto_p)
707 : {
708 4149 : if (flag_checking)
709 : {
710 4207 : for (symtab_node *n = node->same_comdat_group;
711 8356 : n != node;
712 4207 : n = n->same_comdat_group)
713 : /* If at least one of same comdat group functions is external,
714 : all of them have to be, otherwise it is a front-end bug. */
715 4207 : gcc_assert (DECL_EXTERNAL (n->decl));
716 : }
717 4149 : node->dissolve_same_comdat_group_list ();
718 : }
719 8567244 : gcc_assert ((!DECL_WEAK (node->decl)
720 : && !DECL_COMDAT (node->decl))
721 : || TREE_PUBLIC (node->decl)
722 : || node->weakref
723 : || DECL_EXTERNAL (node->decl));
724 8567244 : if (cgraph_externally_visible_p (node, whole_program))
725 : {
726 4116935 : gcc_assert (!node->inlined_to);
727 4116935 : node->externally_visible = true;
728 : }
729 : else
730 : {
731 4450309 : node->externally_visible = false;
732 4450309 : node->forced_by_abi = false;
733 : }
734 8567244 : if (!node->externally_visible
735 4450309 : && node->definition && !node->weakref
736 9543663 : && !DECL_EXTERNAL (node->decl))
737 706909 : localize_node (whole_program, node);
738 :
739 8567244 : if (node->thunk
740 5942 : && TREE_PUBLIC (node->decl))
741 : {
742 5807 : struct cgraph_node *decl_node = node;
743 :
744 5807 : decl_node = decl_node->callees->callee->function_symbol ();
745 :
746 : /* Thunks have the same visibility as function they are attached to.
747 : Make sure the C++ front end set this up properly. */
748 5807 : if (DECL_ONE_ONLY (decl_node->decl))
749 : {
750 4655 : gcc_checking_assert (DECL_COMDAT (node->decl)
751 : == DECL_COMDAT (decl_node->decl));
752 4655 : gcc_checking_assert (node->in_same_comdat_group_p (decl_node));
753 4655 : gcc_checking_assert (node->same_comdat_group);
754 : }
755 5807 : node->forced_by_abi = decl_node->forced_by_abi;
756 5807 : if (DECL_EXTERNAL (decl_node->decl))
757 2 : DECL_EXTERNAL (node->decl) = 1;
758 : }
759 :
760 8567244 : update_visibility_by_resolution_info (node);
761 8567244 : if (node->weakref)
762 230 : optimize_weakref (node);
763 : }
764 5557342 : FOR_EACH_DEFINED_FUNCTION (node)
765 : {
766 5093371 : if (!node->local)
767 4943995 : node->local |= node->local_p ();
768 :
769 : /* If we know that function cannot be overwritten by a
770 : different semantics and moreover its section cannot be
771 : discarded, replace all direct calls by calls to an
772 : noninterposable alias. This make dynamic linking cheaper and
773 : enable more optimization.
774 :
775 : TODO: We can also update virtual tables. */
776 5093371 : if (node->callers
777 5093371 : && can_replace_by_local_alias (node))
778 : {
779 98 : cgraph_node *alias = dyn_cast<cgraph_node *>
780 98 : (node->noninterposable_alias ());
781 :
782 98 : if (alias && alias != node)
783 : {
784 227 : while (node->callers)
785 : {
786 130 : struct cgraph_edge *e = node->callers;
787 :
788 130 : e->redirect_callee (alias);
789 130 : if (gimple_has_body_p (e->caller->decl))
790 : {
791 127 : push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
792 127 : cgraph_edge::redirect_call_stmt_to_callee (e);
793 127 : pop_cfun ();
794 : }
795 : }
796 : }
797 : }
798 : }
799 6915630 : FOR_EACH_VARIABLE (vnode)
800 : {
801 : /* weak flag makes no sense on local variables. */
802 6451659 : gcc_assert (!DECL_WEAK (vnode->decl)
803 : || vnode->weakref
804 : || TREE_PUBLIC (vnode->decl)
805 : || DECL_EXTERNAL (vnode->decl));
806 : /* In several cases declarations cannot be common:
807 :
808 : - when declaration has initializer
809 : - when it is in weak
810 : - when it has specific section
811 : - when it resides in non-generic address space.
812 : - if declaration is local, it will get into .local common section
813 : so common flag is not needed. Frontends still produce these in
814 : certain cases, such as for:
815 :
816 : static int a __attribute__ ((common))
817 :
818 : Canonicalize things here and clear the redundant flag. */
819 6451659 : if (DECL_COMMON (vnode->decl)
820 6451659 : && (!(TREE_PUBLIC (vnode->decl)
821 47 : || DECL_EXTERNAL (vnode->decl))
822 26320 : || (DECL_INITIAL (vnode->decl)
823 23465 : && DECL_INITIAL (vnode->decl) != error_mark_node)
824 2855 : || DECL_WEAK (vnode->decl)
825 2852 : || DECL_SECTION_NAME (vnode->decl) != NULL
826 2847 : || ! (ADDR_SPACE_GENERIC_P
827 : (TYPE_ADDR_SPACE (TREE_TYPE (vnode->decl))))))
828 23520 : DECL_COMMON (vnode->decl) = 0;
829 6451659 : if (vnode->weakref)
830 74 : optimize_weakref (vnode);
831 : }
832 6327353 : FOR_EACH_DEFINED_VARIABLE (vnode)
833 : {
834 5863382 : if (!vnode->definition)
835 0 : continue;
836 5863382 : if (vnode->externally_visible_p ())
837 2958111 : vnode->externally_visible = true;
838 : else
839 : {
840 2905271 : vnode->externally_visible = false;
841 2905271 : vnode->forced_by_abi = false;
842 : }
843 5863382 : if (lookup_attribute ("no_reorder",
844 5863382 : DECL_ATTRIBUTES (vnode->decl)))
845 4 : vnode->no_reorder = 1;
846 :
847 5863382 : if (!vnode->externally_visible
848 2905271 : && !vnode->transparent_alias
849 8768645 : && !DECL_EXTERNAL (vnode->decl))
850 2905263 : localize_node (whole_program, vnode);
851 :
852 5863382 : update_visibility_by_resolution_info (vnode);
853 :
854 : /* Update virtual tables to point to local aliases where possible. */
855 5863382 : if (DECL_VIRTUAL_P (vnode->decl)
856 5863382 : && !DECL_EXTERNAL (vnode->decl))
857 : {
858 : int i;
859 : struct ipa_ref *ref;
860 299958 : bool found = false;
861 :
862 : /* See if there is something to update. */
863 299958 : for (i = 0; vnode->iterate_reference (i, ref); i++)
864 256442 : if (ref->use == IPA_REF_ADDR
865 256442 : && can_replace_by_local_alias_in_vtable (ref->referred))
866 : {
867 : found = true;
868 : break;
869 : }
870 43519 : if (found)
871 : {
872 3 : hash_set<tree> visited_nodes;
873 :
874 3 : vnode->get_constructor ();
875 3 : walk_tree (&DECL_INITIAL (vnode->decl),
876 : update_vtable_references, NULL, &visited_nodes);
877 3 : vnode->remove_all_references ();
878 3 : record_references_in_initializer (vnode->decl, false);
879 3 : }
880 : }
881 : }
882 :
883 463971 : if (symtab->state >= IPA_SSA)
884 : {
885 3400736 : FOR_EACH_VARIABLE (vnode)
886 : {
887 3168696 : tree decl = vnode->decl;
888 :
889 : /* Upgrade TLS access model based on optimized visibility status,
890 : unless it was specified explicitly or no references remain. */
891 3168696 : if (DECL_THREAD_LOCAL_P (decl)
892 4562 : && !lookup_attribute ("tls_model", DECL_ATTRIBUTES (decl))
893 6341441 : && vnode->ref_list.referring.length ())
894 : {
895 4049 : enum tls_model new_model = decl_default_tls_model (decl);
896 4049 : STATIC_ASSERT (TLS_MODEL_GLOBAL_DYNAMIC < TLS_MODEL_LOCAL_DYNAMIC);
897 4049 : STATIC_ASSERT (TLS_MODEL_INITIAL_EXEC < TLS_MODEL_LOCAL_EXEC);
898 : /* We'd prefer to assert that recomputed model is not weaker than
899 : what the front-end assigned, but cannot: see PR 107353. */
900 4049 : if (new_model >= decl_tls_model (decl))
901 4049 : set_decl_tls_model (decl, new_model);
902 : }
903 : }
904 : }
905 :
906 463971 : if (dump_file)
907 : {
908 136 : fprintf (dump_file, "\nMarking local functions:");
909 319 : FOR_EACH_DEFINED_FUNCTION (node)
910 183 : if (node->local)
911 1 : fprintf (dump_file, " %s", node->dump_name ());
912 136 : fprintf (dump_file, "\n\n");
913 136 : fprintf (dump_file, "\nMarking externally visible functions:");
914 319 : FOR_EACH_DEFINED_FUNCTION (node)
915 183 : if (node->externally_visible)
916 176 : fprintf (dump_file, " %s", node->dump_name ());
917 136 : fprintf (dump_file, "\n\n");
918 136 : fprintf (dump_file, "\nMarking externally visible variables:");
919 228 : FOR_EACH_DEFINED_VARIABLE (vnode)
920 92 : if (vnode->externally_visible)
921 60 : fprintf (dump_file, " %s", vnode->dump_name ());
922 136 : fprintf (dump_file, "\n\n");
923 : }
924 463971 : symtab->function_flags_ready = true;
925 463971 : return 0;
926 : }
927 :
928 : /* Local function pass handling visibilities. This happens before LTO streaming
929 : so in particular -fwhole-program should be ignored at this level. */
930 :
931 : namespace {
932 :
933 : const pass_data pass_data_ipa_function_and_variable_visibility =
934 : {
935 : SIMPLE_IPA_PASS, /* type */
936 : "visibility", /* name */
937 : OPTGROUP_NONE, /* optinfo_flags */
938 : TV_CGRAPHOPT, /* tv_id */
939 : 0, /* properties_required */
940 : 0, /* properties_provided */
941 : 0, /* properties_destroyed */
942 : 0, /* todo_flags_start */
943 : ( TODO_remove_functions | TODO_dump_symtab ), /* todo_flags_finish */
944 : };
945 :
946 : /* Bring functions local at LTO time with -fwhole-program. */
947 :
948 : static unsigned int
949 232040 : whole_program_function_and_variable_visibility (void)
950 : {
951 232040 : function_and_variable_visibility (flag_whole_program);
952 232040 : if (optimize || in_lto_p)
953 152453 : ipa_discover_variable_flags ();
954 232040 : return 0;
955 : }
956 :
957 : } // anon namespace
958 :
959 : namespace {
960 :
961 : const pass_data pass_data_ipa_whole_program_visibility =
962 : {
963 : IPA_PASS, /* type */
964 : "whole-program", /* name */
965 : OPTGROUP_NONE, /* optinfo_flags */
966 : TV_CGRAPHOPT, /* tv_id */
967 : 0, /* properties_required */
968 : 0, /* properties_provided */
969 : 0, /* properties_destroyed */
970 : 0, /* todo_flags_start */
971 : ( TODO_remove_functions | TODO_dump_symtab ), /* todo_flags_finish */
972 : };
973 :
974 : class pass_ipa_whole_program_visibility : public ipa_opt_pass_d
975 : {
976 : public:
977 288047 : pass_ipa_whole_program_visibility (gcc::context *ctxt)
978 : : ipa_opt_pass_d (pass_data_ipa_whole_program_visibility, ctxt,
979 : NULL, /* generate_summary */
980 : NULL, /* write_summary */
981 : NULL, /* read_summary */
982 : NULL, /* write_optimization_summary */
983 : NULL, /* read_optimization_summary */
984 : NULL, /* stmt_fixup */
985 : 0, /* function_transform_todo_flags_start */
986 : NULL, /* function_transform */
987 288047 : NULL) /* variable_transform */
988 288047 : {}
989 :
990 : /* opt_pass methods: */
991 :
992 568068 : bool gate (function *) final override
993 : {
994 : /* Do not re-run on ltrans stage. */
995 568068 : return !flag_ltrans;
996 : }
997 232040 : unsigned int execute (function *) final override
998 : {
999 232040 : return whole_program_function_and_variable_visibility ();
1000 : }
1001 :
1002 : }; // class pass_ipa_whole_program_visibility
1003 :
1004 : } // anon namespace
1005 :
1006 : ipa_opt_pass_d *
1007 288047 : make_pass_ipa_whole_program_visibility (gcc::context *ctxt)
1008 : {
1009 288047 : return new pass_ipa_whole_program_visibility (ctxt);
1010 : }
1011 :
1012 : class pass_ipa_function_and_variable_visibility : public simple_ipa_opt_pass
1013 : {
1014 : public:
1015 288047 : pass_ipa_function_and_variable_visibility (gcc::context *ctxt)
1016 : : simple_ipa_opt_pass (pass_data_ipa_function_and_variable_visibility,
1017 576094 : ctxt)
1018 : {}
1019 :
1020 : /* opt_pass methods: */
1021 231931 : unsigned int execute (function *) final override
1022 : {
1023 463765 : return function_and_variable_visibility (flag_whole_program && !flag_lto);
1024 : }
1025 :
1026 : }; // class pass_ipa_function_and_variable_visibility
1027 :
1028 : simple_ipa_opt_pass *
1029 288047 : make_pass_ipa_function_and_variable_visibility (gcc::context *ctxt)
1030 : {
1031 288047 : return new pass_ipa_function_and_variable_visibility (ctxt);
1032 : }
|