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 5022474 : non_local_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
94 : {
95 5022474 : return !(node->only_called_directly_or_aliased_p ()
96 : /* i386 would need update to output thunk with local calling
97 : conventions. */
98 386823 : && !node->thunk
99 386823 : && node->definition
100 386821 : && !DECL_EXTERNAL (node->decl)
101 257272 : && !lookup_attribute ("noipa", DECL_ATTRIBUTES (node->decl))
102 256221 : && !node->externally_visible
103 256221 : && !node->used_from_other_partition
104 256221 : && !node->in_other_partition
105 256221 : && node->get_availability () >= AVAIL_AVAILABLE
106 256221 : && !DECL_STATIC_CONSTRUCTOR (node->decl)
107 256221 : && !DECL_STATIC_DESTRUCTOR (node->decl));
108 : }
109 :
110 : /* Return true when function can be marked local. */
111 :
112 : bool
113 4975176 : cgraph_node::local_p (void)
114 : {
115 4981157 : cgraph_node *n = ultimate_alias_target ();
116 :
117 4981157 : if (n->thunk)
118 5981 : return n->callees->callee->local_p ();
119 4975176 : return !n->call_for_symbol_thunks_and_aliases (non_local_p,
120 4975176 : NULL, true);
121 : }
122 :
123 : /* A helper for comdat_can_be_unshared_p. */
124 :
125 : static bool
126 2084 : comdat_can_be_unshared_p_1 (symtab_node *node)
127 : {
128 2084 : if (!node->externally_visible)
129 : return true;
130 1838 : if (node->address_can_be_compared_p ())
131 : {
132 : struct ipa_ref *ref;
133 :
134 1188 : for (unsigned int i = 0; node->iterate_referring (i, ref); i++)
135 620 : if (ref->address_matters_p ())
136 454 : return false;
137 : }
138 :
139 : /* If the symbol is used in some weird way, better to not touch it. */
140 1384 : if (node->force_output)
141 : return false;
142 :
143 : /* Explicit instantiations needs to be output when possibly
144 : used externally. */
145 1384 : 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 198 : && (!TREE_READONLY (node->decl)
154 195 : || 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 1587 : comdat_can_be_unshared_p (symtab_node *node)
170 : {
171 1587 : if (!comdat_can_be_unshared_p_1 (node))
172 : return false;
173 1078 : 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 497 : for (next = node->same_comdat_group;
181 843 : next != node; next = next->same_comdat_group)
182 497 : 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 8551532 : cgraph_externally_visible_p (struct cgraph_node *node,
192 : bool whole_program)
193 : {
194 8551581 : while (node->transparent_alias && node->definition)
195 49 : node = node->get_alias_target ();
196 8551532 : if (!node->definition)
197 : return false;
198 5086319 : if (!TREE_PUBLIC (node->decl)
199 5086319 : || DECL_EXTERNAL (node->decl))
200 : return false;
201 4271087 : 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 4271052 : if (fndecl_built_in_p (node->decl))
210 : return true;
211 :
212 : /* If linker counts on us, we must preserve the function. */
213 4260537 : if (node->used_from_object_file_p ())
214 : return true;
215 4252892 : if (DECL_PRESERVE_P (node->decl))
216 : return true;
217 4245270 : if (lookup_attribute ("externally_visible",
218 4245270 : DECL_ATTRIBUTES (node->decl)))
219 : return true;
220 4192683 : 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 4555178 : FOR_EACH_ALIAS (node, ref)
231 400011 : if (ref->referring->symver)
232 : return true;
233 :
234 4155167 : 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 4118283 : if (((in_lto_p || whole_program) && !flag_incremental_link)
241 31468 : && DECL_COMDAT (node->decl)
242 4119274 : && comdat_can_be_unshared_p (node))
243 : return false;
244 :
245 : /* When doing link time optimizations, hidden symbols become local. */
246 30477 : if ((in_lto_p && !flag_incremental_link)
247 30223 : && (DECL_VISIBILITY (node->decl) == VISIBILITY_HIDDEN
248 30221 : || 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 4117306 : && node->definition)
252 : ;
253 4117302 : 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 5856042 : varpool_node::externally_visible_p (void)
266 : {
267 5856050 : while (transparent_alias && definition)
268 8 : return get_alias_target ()->externally_visible_p ();
269 5856042 : if (DECL_EXTERNAL (decl))
270 : return true;
271 :
272 5837373 : if (!TREE_PUBLIC (decl))
273 : return false;
274 2952829 : if (ref_by_asm)
275 : return true;
276 :
277 : /* If linker counts on us, we must preserve the function. */
278 2952765 : 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 2952754 : if (DECL_THREAD_LOCAL_P (decl)
284 2958809 : && (DECL_TLS_MODEL (decl) != TLS_MODEL_EMULATED
285 6055 : && DECL_TLS_MODEL (decl) != TLS_MODEL_INITIAL_EXEC))
286 : return true;
287 :
288 2946833 : if (DECL_HARD_REGISTER (decl))
289 : return true;
290 2946660 : if (DECL_PRESERVE_P (decl))
291 : return true;
292 2945287 : if (lookup_attribute ("externally_visible",
293 2945287 : 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 2945420 : FOR_EACH_ALIAS (this, ref)
304 204 : if (ref->referring->symver)
305 : return true;
306 :
307 2945216 : 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 2933263 : if (((in_lto_p || flag_whole_program) && !flag_incremental_link)
316 6520 : && DECL_COMDAT (decl)
317 2933859 : && comdat_can_be_unshared_p (this))
318 : return false;
319 :
320 : /* When doing link time optimizations, hidden symbols become local. */
321 6393 : if (in_lto_p && !flag_incremental_link
322 6214 : && (DECL_VISIBILITY (decl) == VISIBILITY_HIDDEN
323 6213 : || 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 2933165 : && definition)
327 : ;
328 2933163 : 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 2982297 : can_replace_by_local_alias (symtab_node *node)
349 : {
350 : /* If aliases aren't supported, we can't do replacement. */
351 2982297 : 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 2982309 : while (node->transparent_alias && node->definition && !node->weakref)
357 12 : node = node->get_alias_target ();
358 2982297 : if (node->weakref)
359 : return false;
360 :
361 2982295 : return (node->get_availability () > AVAIL_INTERPOSABLE
362 2906010 : && !decl_binds_to_current_def_p (node->decl)
363 4935189 : && !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 258223 : can_replace_by_local_alias_in_vtable (symtab_node *node)
372 : {
373 258223 : if (is_a <varpool_node *> (node)
374 143982 : && !DECL_VIRTUAL_P (node->decl))
375 : return false;
376 173780 : 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 14405203 : update_visibility_by_resolution_info (symtab_node * node)
402 : {
403 14405203 : bool define;
404 :
405 14405203 : if (!node->externally_visible
406 7189957 : || (!DECL_WEAK (node->decl) && !DECL_ONE_ONLY (node->decl))
407 17231817 : || node->resolution == LDPR_UNKNOWN)
408 14404833 : 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 3597618 : localize_node (bool whole_program, symtab_node *node)
547 : {
548 3597618 : 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 3597618 : if (node->same_comdat_group
554 8988 : && (node->resolution == LDPR_PREVAILING_DEF_IRONLY
555 7583 : || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP))
556 : {
557 : symtab_node *next;
558 1705 : for (next = node->same_comdat_group;
559 3266 : next != node; next = next->same_comdat_group)
560 1783 : if (next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP
561 1705 : || next->resolution == LDPR_PREVAILING_DEF)
562 : break;
563 1561 : if (node != next)
564 : {
565 78 : if (!node->transparent_alias)
566 : {
567 78 : node->resolution = LDPR_PREVAILING_DEF_IRONLY;
568 78 : node->make_decl_local ();
569 78 : if (!flag_incremental_link)
570 78 : node->unique_name |= true;
571 78 : 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 3597540 : if (node->comdat_local_p ())
578 : return;
579 :
580 3590303 : if (node->same_comdat_group && TREE_PUBLIC (node->decl))
581 : {
582 2025 : for (symtab_node *next = node->same_comdat_group;
583 3698 : next != node; next = next->same_comdat_group)
584 : {
585 2025 : next->set_comdat_group (NULL);
586 2025 : if (!next->alias)
587 1813 : next->set_section (NULL);
588 2025 : if (!next->transparent_alias)
589 2025 : next->make_decl_local ();
590 2025 : next->unique_name
591 2025 : |= ((next->resolution == LDPR_PREVAILING_DEF_IRONLY
592 374 : || next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
593 1651 : && TREE_PUBLIC (next->decl)
594 2025 : && !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 1673 : node->dissolve_same_comdat_group_list ();
600 : }
601 :
602 3590303 : node->unique_name
603 7180606 : |= ((node->resolution == LDPR_PREVAILING_DEF_IRONLY
604 1826824 : || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
605 1763895 : && TREE_PUBLIC (node->decl)
606 3639543 : && !flag_incremental_link);
607 :
608 3590303 : if (TREE_PUBLIC (node->decl))
609 50179 : node->set_comdat_group (NULL);
610 3590303 : if (DECL_COMDAT (node->decl) && !node->alias)
611 5236 : node->set_section (NULL);
612 3590303 : if (!node->transparent_alias)
613 : {
614 3590303 : node->resolution = LDPR_PREVAILING_DEF_IRONLY;
615 3590303 : node->make_decl_local ();
616 : }
617 : }
618 :
619 : /* Decide on visibility of all symbols. */
620 :
621 : static unsigned int
622 460018 : function_and_variable_visibility (bool whole_program)
623 : {
624 460018 : struct cgraph_node *node;
625 460018 : varpool_node *vnode;
626 :
627 : /* All aliases should be processed at this point. */
628 460018 : gcc_checking_assert (!alias_pairs || !alias_pairs->length ());
629 :
630 460018 : if (TARGET_SUPPORTS_ALIASES)
631 : {
632 5546084 : FOR_EACH_DEFINED_FUNCTION (node)
633 : {
634 5086066 : if (node->get_availability () != AVAIL_INTERPOSABLE
635 113905 : || DECL_EXTERNAL (node->decl)
636 113905 : || node->has_aliases_p ()
637 5195548 : || lookup_attribute ("noipa", DECL_ATTRIBUTES (node->decl)))
638 5016257 : continue;
639 :
640 69809 : cgraph_node *alias = 0;
641 69809 : cgraph_edge *next_edge;
642 317513 : for (cgraph_edge *e = node->callees; e; e = next_edge)
643 : {
644 247704 : next_edge = e->next_callee;
645 : /* Recursive function calls usually can't be interposed. */
646 :
647 247704 : if (!e->recursive_p ())
648 246765 : 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 9011550 : FOR_EACH_FUNCTION (node)
669 : {
670 8551532 : int flags = flags_from_decl_or_type (node->decl);
671 :
672 : /* Optimize away PURE and CONST constructors and destructors. */
673 8551532 : if (node->analyzed
674 5086329 : && (DECL_STATIC_CONSTRUCTOR (node->decl)
675 5048085 : || DECL_STATIC_DESTRUCTOR (node->decl))
676 38868 : && (flags & (ECF_CONST | ECF_PURE))
677 23 : && !(flags & ECF_LOOPING_CONST_OR_PURE)
678 8551532 : && 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 8551532 : if (DECL_EXTERNAL (node->decl) || !node->definition)
688 : {
689 3617608 : node->force_output = 0;
690 3617608 : 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 8551532 : 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 8551532 : if (node->same_comdat_group && DECL_EXTERNAL (node->decl) && !in_lto_p)
707 : {
708 24 : if (flag_checking)
709 : {
710 30 : for (symtab_node *n = node->same_comdat_group;
711 54 : n != node;
712 30 : 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 30 : gcc_assert (DECL_EXTERNAL (n->decl));
716 : }
717 24 : node->dissolve_same_comdat_group_list ();
718 : }
719 8551532 : 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 8551532 : if (cgraph_externally_visible_p (node, whole_program))
725 : {
726 4233106 : gcc_assert (!node->inlined_to);
727 4233106 : node->externally_visible = true;
728 : }
729 : else
730 : {
731 4318426 : node->externally_visible = false;
732 4318426 : node->forced_by_abi = false;
733 : }
734 8551532 : if (!node->externally_visible
735 4318426 : && node->definition && !node->weakref
736 9404738 : && !DECL_EXTERNAL (node->decl))
737 700806 : localize_node (whole_program, node);
738 :
739 8551532 : 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 8551532 : update_visibility_by_resolution_info (node);
761 8551532 : if (node->weakref)
762 230 : optimize_weakref (node);
763 : }
764 5546347 : FOR_EACH_DEFINED_FUNCTION (node)
765 : {
766 5086329 : if (!node->local)
767 4939396 : 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 5086329 : if (node->callers
777 5086329 : && 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 6901470 : FOR_EACH_VARIABLE (vnode)
800 : {
801 : /* weak flag makes no sense on local variables. */
802 6441452 : 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 6441452 : if (DECL_COMMON (vnode->decl)
820 6441452 : && (!(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 6441452 : if (vnode->weakref)
830 74 : optimize_weakref (vnode);
831 : }
832 6313689 : FOR_EACH_DEFINED_VARIABLE (vnode)
833 : {
834 5853671 : if (!vnode->definition)
835 0 : continue;
836 5853671 : if (vnode->externally_visible_p ())
837 2956851 : vnode->externally_visible = true;
838 : else
839 : {
840 2896820 : vnode->externally_visible = false;
841 2896820 : vnode->forced_by_abi = false;
842 : }
843 5853671 : if (lookup_attribute ("no_reorder",
844 5853671 : DECL_ATTRIBUTES (vnode->decl)))
845 4 : vnode->no_reorder = 1;
846 :
847 5853671 : if (!vnode->externally_visible
848 2896820 : && !vnode->transparent_alias
849 8750483 : && !DECL_EXTERNAL (vnode->decl))
850 2896812 : localize_node (whole_program, vnode);
851 :
852 5853671 : update_visibility_by_resolution_info (vnode);
853 :
854 : /* Update virtual tables to point to local aliases where possible. */
855 5853671 : if (DECL_VIRTUAL_P (vnode->decl)
856 5853671 : && !DECL_EXTERNAL (vnode->decl))
857 : {
858 : int i;
859 : struct ipa_ref *ref;
860 302141 : bool found = false;
861 :
862 : /* See if there is something to update. */
863 302141 : for (i = 0; vnode->iterate_reference (i, ref); i++)
864 258218 : if (ref->use == IPA_REF_ADDR
865 258218 : && can_replace_by_local_alias_in_vtable (ref->referred))
866 : {
867 : found = true;
868 : break;
869 : }
870 43926 : 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 460018 : if (symtab->state >= IPA_SSA)
884 : {
885 3393492 : FOR_EACH_VARIABLE (vnode)
886 : {
887 3163429 : 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 3163429 : if (DECL_THREAD_LOCAL_P (decl)
892 4568 : && !lookup_attribute ("tls_model", DECL_ATTRIBUTES (decl))
893 6330919 : && vnode->ref_list.referring.length ())
894 : {
895 4061 : enum tls_model new_model = decl_default_tls_model (decl);
896 4061 : STATIC_ASSERT (TLS_MODEL_GLOBAL_DYNAMIC < TLS_MODEL_LOCAL_DYNAMIC);
897 4061 : 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 4061 : if (new_model >= decl_tls_model (decl))
901 4061 : set_decl_tls_model (decl, new_model);
902 : }
903 : }
904 : }
905 :
906 460018 : 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 460018 : symtab->function_flags_ready = true;
925 460018 : 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 230063 : whole_program_function_and_variable_visibility (void)
950 : {
951 230063 : function_and_variable_visibility (flag_whole_program);
952 230063 : if (optimize || in_lto_p)
953 151656 : ipa_discover_variable_flags ();
954 230063 : 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 285722 : 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 285722 : NULL) /* variable_transform */
988 285722 : {}
989 :
990 : /* opt_pass methods: */
991 :
992 563719 : bool gate (function *) final override
993 : {
994 : /* Do not re-run on ltrans stage. */
995 563719 : return !flag_ltrans;
996 : }
997 230063 : unsigned int execute (function *) final override
998 : {
999 230063 : 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 285722 : make_pass_ipa_whole_program_visibility (gcc::context *ctxt)
1008 : {
1009 285722 : 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 285722 : pass_ipa_function_and_variable_visibility (gcc::context *ctxt)
1016 : : simple_ipa_opt_pass (pass_data_ipa_function_and_variable_visibility,
1017 571444 : ctxt)
1018 : {}
1019 :
1020 : /* opt_pass methods: */
1021 229955 : unsigned int execute (function *) final override
1022 : {
1023 459813 : 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 285722 : make_pass_ipa_function_and_variable_visibility (gcc::context *ctxt)
1030 : {
1031 285722 : return new pass_ipa_function_and_variable_visibility (ctxt);
1032 : }
|