Branch data Line data Source code
1 : : /* IPA visibility pass
2 : : Copyright (C) 2003-2025 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 : 4893991 : non_local_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
94 : : {
95 : 4893991 : return !(node->only_called_directly_or_aliased_p ()
96 : : /* i386 would need update to output thunk with local calling
97 : : conventions. */
98 : 468921 : && !node->thunk
99 : 468921 : && node->definition
100 : 468919 : && !DECL_EXTERNAL (node->decl)
101 : 251993 : && !lookup_attribute ("noipa", DECL_ATTRIBUTES (node->decl))
102 : : && !node->externally_visible
103 : : && !node->used_from_other_partition
104 : 251185 : && !node->in_other_partition
105 : 251185 : && node->get_availability () >= AVAIL_AVAILABLE
106 : 251185 : && !DECL_STATIC_CONSTRUCTOR (node->decl)
107 : 251185 : && !DECL_STATIC_DESTRUCTOR (node->decl));
108 : : }
109 : :
110 : : /* Return true when function can be marked local. */
111 : :
112 : : bool
113 : 4849761 : cgraph_node::local_p (void)
114 : : {
115 : 4855735 : cgraph_node *n = ultimate_alias_target ();
116 : :
117 : 4855735 : if (n->thunk)
118 : 5974 : return n->callees->callee->local_p ();
119 : 4849761 : return !n->call_for_symbol_thunks_and_aliases (non_local_p,
120 : 4849761 : NULL, true);
121 : : }
122 : :
123 : : /* A helper for comdat_can_be_unshared_p. */
124 : :
125 : : static bool
126 : 1952 : comdat_can_be_unshared_p_1 (symtab_node *node)
127 : : {
128 : 1952 : if (!node->externally_visible)
129 : : return true;
130 : 1741 : if (node->address_can_be_compared_p ())
131 : : {
132 : : struct ipa_ref *ref;
133 : :
134 : 1102 : for (unsigned int i = 0; node->iterate_referring (i, ref); i++)
135 : 570 : if (ref->address_matters_p ())
136 : 404 : return false;
137 : : }
138 : :
139 : : /* If the symbol is used in some weird way, better to not touch it. */
140 : 1337 : if (node->force_output)
141 : : return false;
142 : :
143 : : /* Explicit instantiations needs to be output when possibly
144 : : used externally. */
145 : 1337 : 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 : 1468 : comdat_can_be_unshared_p (symtab_node *node)
170 : : {
171 : 1468 : if (!comdat_can_be_unshared_p_1 (node))
172 : : return false;
173 : 1009 : 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 : 484 : for (next = node->same_comdat_group;
181 : 822 : next != node; next = next->same_comdat_group)
182 : 484 : 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 : 8372187 : cgraph_externally_visible_p (struct cgraph_node *node,
192 : : bool whole_program)
193 : : {
194 : 8372236 : while (node->transparent_alias && node->definition)
195 : 49 : node = node->get_alias_target ();
196 : 8372187 : if (!node->definition)
197 : : return false;
198 : 4956445 : if (!TREE_PUBLIC (node->decl)
199 : 4956445 : || DECL_EXTERNAL (node->decl))
200 : : return false;
201 : :
202 : : /* Do not try to localize built-in functions yet. One of problems is that we
203 : : end up mangling their asm for WHOPR that makes it impossible to call them
204 : : using the implicit built-in declarations anymore. Similarly this enables
205 : : us to remove them as unreachable before actual calls may appear during
206 : : expansion or folding. */
207 : 4069227 : if (fndecl_built_in_p (node->decl))
208 : : return true;
209 : :
210 : : /* If linker counts on us, we must preserve the function. */
211 : 4058885 : if (node->used_from_object_file_p ())
212 : : return true;
213 : 4050468 : if (DECL_PRESERVE_P (node->decl))
214 : : return true;
215 : 4043043 : if (lookup_attribute ("externally_visible",
216 : 4043043 : DECL_ATTRIBUTES (node->decl)))
217 : : return true;
218 : 3991205 : if (lookup_attribute ("noipa", DECL_ATTRIBUTES (node->decl)))
219 : : return true;
220 : : if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
221 : : && lookup_attribute ("dllexport",
222 : : DECL_ATTRIBUTES (node->decl)))
223 : : return true;
224 : :
225 : : /* Limitation of gas requires us to output targets of symver aliases as
226 : : global symbols. This is binutils PR 25295. */
227 : : ipa_ref *ref;
228 : 4368717 : FOR_EACH_ALIAS (node, ref)
229 : 412948 : if (ref->referring->symver)
230 : : return true;
231 : :
232 : 3955769 : if (node->resolution == LDPR_PREVAILING_DEF_IRONLY)
233 : : return false;
234 : : /* When doing LTO or whole program, we can bring COMDAT functions static.
235 : : This improves code quality and we know we will duplicate them at most twice
236 : : (in the case that we are not using plugin and link with object file
237 : : implementing same COMDAT) */
238 : 3919641 : if (((in_lto_p || whole_program) && !flag_incremental_link)
239 : 30958 : && DECL_COMDAT (node->decl)
240 : 3920566 : && comdat_can_be_unshared_p (node))
241 : : return false;
242 : :
243 : : /* When doing link time optimizations, hidden symbols become local. */
244 : 30034 : if ((in_lto_p && !flag_incremental_link)
245 : 29783 : && (DECL_VISIBILITY (node->decl) == VISIBILITY_HIDDEN
246 : 29781 : || DECL_VISIBILITY (node->decl) == VISIBILITY_INTERNAL)
247 : : /* Be sure that node is defined in IR file, not in other object
248 : : file. In that case we don't set used_from_other_object_file. */
249 : 3918730 : && node->definition)
250 : : ;
251 : 3918726 : else if (!whole_program)
252 : : return true;
253 : :
254 : 286 : if (MAIN_NAME_P (DECL_NAME (node->decl)))
255 : : return true;
256 : :
257 : : return false;
258 : : }
259 : :
260 : : /* Return true when variable should be considered externally visible. */
261 : :
262 : : bool
263 : 5809539 : varpool_node::externally_visible_p (void)
264 : : {
265 : 5809547 : while (transparent_alias && definition)
266 : 8 : return get_alias_target ()->externally_visible_p ();
267 : 5809539 : if (DECL_EXTERNAL (decl))
268 : : return true;
269 : :
270 : 5791490 : if (!TREE_PUBLIC (decl))
271 : : return false;
272 : :
273 : : /* If linker counts on us, we must preserve the function. */
274 : 2931350 : if (used_from_object_file_p ())
275 : : return true;
276 : :
277 : : /* Bringing TLS variables local may cause dynamic linker failures
278 : : on limits of static TLS vars. */
279 : 2931339 : if (DECL_THREAD_LOCAL_P (decl)
280 : 2937014 : && (DECL_TLS_MODEL (decl) != TLS_MODEL_EMULATED
281 : 5675 : && DECL_TLS_MODEL (decl) != TLS_MODEL_INITIAL_EXEC))
282 : : return true;
283 : :
284 : 2925811 : if (DECL_HARD_REGISTER (decl))
285 : : return true;
286 : 2925638 : if (DECL_PRESERVE_P (decl))
287 : : return true;
288 : 2924288 : if (lookup_attribute ("externally_visible",
289 : 2924288 : DECL_ATTRIBUTES (decl)))
290 : : return true;
291 : : if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
292 : : && lookup_attribute ("dllexport",
293 : : DECL_ATTRIBUTES (decl)))
294 : : return true;
295 : :
296 : : /* Limitation of gas requires us to output targets of symver aliases as
297 : : global symbols. This is binutils PR 25295. */
298 : : ipa_ref *ref;
299 : 2924425 : FOR_EACH_ALIAS (this, ref)
300 : 208 : if (ref->referring->symver)
301 : : return true;
302 : :
303 : 2924217 : if (resolution == LDPR_PREVAILING_DEF_IRONLY)
304 : : return false;
305 : :
306 : : /* As a special case, the COMDAT virtual tables can be unshared.
307 : : In LTO mode turn vtables into static variables. The variable is readonly,
308 : : so this does not enable more optimization, but referring static var
309 : : is faster for dynamic linking. Also this match logic hidding vtables
310 : : from LTO symbol tables. */
311 : 2912730 : if (((in_lto_p || flag_whole_program) && !flag_incremental_link)
312 : 6319 : && DECL_COMDAT (decl)
313 : 2913273 : && comdat_can_be_unshared_p (this))
314 : : return false;
315 : :
316 : : /* When doing link time optimizations, hidden symbols become local. */
317 : 6197 : if (in_lto_p && !flag_incremental_link
318 : 6022 : && (DECL_VISIBILITY (decl) == VISIBILITY_HIDDEN
319 : 6021 : || DECL_VISIBILITY (decl) == VISIBILITY_INTERNAL)
320 : : /* Be sure that node is defined in IR file, not in other object
321 : : file. In that case we don't set used_from_other_object_file. */
322 : 2912635 : && definition)
323 : : ;
324 : 2912633 : else if (!flag_whole_program)
325 : : return true;
326 : :
327 : : /* Do not attempt to privatize COMDATS by default.
328 : : This would break linking with C++ libraries sharing
329 : : inline definitions.
330 : :
331 : : FIXME: We can do so for readonly vars with no address taken and
332 : : possibly also for vtables since no direct pointer comparsion is done.
333 : : It might be interesting to do so to reduce linking overhead. */
334 : 234 : if (DECL_COMDAT (decl) || DECL_WEAK (decl))
335 : : return true;
336 : : return false;
337 : : }
338 : :
339 : : /* Return true if reference to NODE can be replaced by a local alias.
340 : : Local aliases save dynamic linking overhead and enable more optimizations.
341 : : */
342 : :
343 : : static bool
344 : 2834304 : can_replace_by_local_alias (symtab_node *node)
345 : : {
346 : : /* If aliases aren't supported, we can't do replacement. */
347 : 2834304 : if (!TARGET_SUPPORTS_ALIASES)
348 : : return false;
349 : :
350 : : /* Weakrefs have a reason to be non-local. Be sure we do not replace
351 : : them. */
352 : 2834316 : while (node->transparent_alias && node->definition && !node->weakref)
353 : 12 : node = node->get_alias_target ();
354 : 2834304 : if (node->weakref)
355 : : return false;
356 : :
357 : 2834302 : return (node->get_availability () > AVAIL_INTERPOSABLE
358 : 2760873 : && !decl_binds_to_current_def_p (node->decl)
359 : 4672808 : && !node->can_be_discarded_p ());
360 : : }
361 : :
362 : : /* Return true if we can replace reference to NODE by local alias
363 : : within a virtual table. Generally we can replace function pointers
364 : : and virtual table pointers. */
365 : :
366 : : static bool
367 : 250083 : can_replace_by_local_alias_in_vtable (symtab_node *node)
368 : : {
369 : 250083 : if (is_a <varpool_node *> (node)
370 : 140632 : && !DECL_VIRTUAL_P (node->decl))
371 : : return false;
372 : 167850 : return can_replace_by_local_alias (node);
373 : : }
374 : :
375 : : /* walk_tree callback that rewrites initializer references. */
376 : :
377 : : static tree
378 : 25 : update_vtable_references (tree *tp, int *walk_subtrees,
379 : : void *data ATTRIBUTE_UNUSED)
380 : : {
381 : 25 : if (VAR_OR_FUNCTION_DECL_P (*tp))
382 : : {
383 : 5 : if (can_replace_by_local_alias_in_vtable (symtab_node::get (*tp)))
384 : 4 : *tp = symtab_node::get (*tp)->noninterposable_alias ()->decl;
385 : 5 : *walk_subtrees = 0;
386 : : }
387 : 20 : else if (IS_TYPE_OR_DECL_P (*tp))
388 : 0 : *walk_subtrees = 0;
389 : 25 : return NULL;
390 : : }
391 : :
392 : : /* In LTO we can remove COMDAT groups and weak symbols.
393 : : Either turn them into normal symbols or external symbol depending on
394 : : resolution info. */
395 : :
396 : : static void
397 : 14179589 : update_visibility_by_resolution_info (symtab_node * node)
398 : : {
399 : 14179589 : bool define;
400 : :
401 : 14179589 : if (!node->externally_visible
402 : 6967526 : || (!DECL_WEAK (node->decl) && !DECL_ONE_ONLY (node->decl))
403 : 16825589 : || node->resolution == LDPR_UNKNOWN)
404 : 14179222 : return;
405 : :
406 : 734 : define = (node->resolution == LDPR_PREVAILING_DEF_IRONLY
407 : : || node->resolution == LDPR_PREVAILING_DEF
408 : 367 : || node->resolution == LDPR_UNDEF
409 : 367 : || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP);
410 : :
411 : : /* The linker decisions ought to agree in the whole group. */
412 : 367 : if (node->same_comdat_group)
413 : 108 : for (symtab_node *next = node->same_comdat_group;
414 : 176 : next != node; next = next->same_comdat_group)
415 : : {
416 : 108 : if (!next->externally_visible || next->transparent_alias)
417 : 4 : continue;
418 : :
419 : 104 : bool same_def
420 : 104 : = define == (next->resolution == LDPR_PREVAILING_DEF_IRONLY
421 : : || next->resolution == LDPR_PREVAILING_DEF
422 : : || next->resolution == LDPR_UNDEF
423 : 104 : || next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP);
424 : 104 : gcc_assert (in_lto_p || same_def);
425 : 104 : if (!same_def)
426 : : return;
427 : : }
428 : :
429 : 367 : if (node->same_comdat_group)
430 : 108 : for (symtab_node *next = node->same_comdat_group;
431 : 176 : next != node; next = next->same_comdat_group)
432 : : {
433 : : /* During incremental linking we need to keep symbol weak for future
434 : : linking. We can still drop definition if we know non-LTO world
435 : : prevails. */
436 : 108 : if (!flag_incremental_link)
437 : : {
438 : 8 : DECL_WEAK (next->decl) = false;
439 : 8 : next->set_comdat_group (NULL);
440 : : }
441 : 108 : if (!define)
442 : : {
443 : 0 : if (next->externally_visible)
444 : 0 : DECL_EXTERNAL (next->decl) = true;
445 : 0 : next->set_comdat_group (NULL);
446 : : }
447 : : }
448 : :
449 : : /* During incremental linking we need to keep symbol weak for future
450 : : linking. We can still drop definition if we know non-LTO world prevails. */
451 : 367 : if (!flag_incremental_link)
452 : : {
453 : 217 : DECL_WEAK (node->decl) = false;
454 : 217 : node->set_comdat_group (NULL);
455 : 217 : node->dissolve_same_comdat_group_list ();
456 : : }
457 : 367 : if (!define)
458 : : {
459 : 0 : DECL_EXTERNAL (node->decl) = true;
460 : 0 : node->set_comdat_group (NULL);
461 : 0 : node->dissolve_same_comdat_group_list ();
462 : : }
463 : : }
464 : :
465 : : /* Try to get rid of weakref. */
466 : :
467 : : static void
468 : 320 : optimize_weakref (symtab_node *node)
469 : : {
470 : 320 : bool strip_weakref = false;
471 : 320 : bool static_alias = false;
472 : :
473 : 320 : gcc_assert (node->weakref);
474 : :
475 : : /* Weakrefs with no target defined cannot be optimized. */
476 : 320 : if (!node->analyzed)
477 : : return;
478 : 47 : symtab_node *target = node->get_alias_target ();
479 : :
480 : : /* Weakrefs to weakrefs can be optimized only if target can be. */
481 : 47 : if (target->weakref)
482 : 16 : optimize_weakref (target);
483 : 47 : if (target->weakref)
484 : : return;
485 : :
486 : : /* If we have definition of weakref's target and we know it binds locally,
487 : : we can turn weakref to static alias. */
488 : 31 : if (TARGET_SUPPORTS_ALIASES
489 : 31 : && target->definition && decl_binds_to_current_def_p (target->decl))
490 : : strip_weakref = static_alias = true;
491 : : /* Otherwise we can turn weakref into transparent alias. This transformation
492 : : may break asm statements which directly refers to symbol name and expect
493 : : GNU as to translate it via .weakref directive. So do not optimize when
494 : : DECL_PRESERVED is set and .weakref is supported. */
495 : 2 : else if ((!DECL_PRESERVE_P (target->decl)
496 : 0 : || IDENTIFIER_TRANSPARENT_ALIAS (DECL_ASSEMBLER_NAME (node->decl)))
497 : 2 : && !DECL_WEAK (target->decl)
498 : 0 : && !DECL_EXTERNAL (target->decl)
499 : 2 : && ((target->definition && !target->can_be_discarded_p ())
500 : 0 : || target->resolution != LDPR_UNDEF))
501 : : strip_weakref = true;
502 : 2 : if (!strip_weakref)
503 : 2 : return;
504 : 29 : node->weakref = false;
505 : 29 : IDENTIFIER_TRANSPARENT_ALIAS (DECL_ASSEMBLER_NAME (node->decl)) = 0;
506 : 29 : TREE_CHAIN (DECL_ASSEMBLER_NAME (node->decl)) = NULL_TREE;
507 : 29 : DECL_ATTRIBUTES (node->decl) = remove_attribute ("weakref",
508 : 29 : DECL_ATTRIBUTES
509 : : (node->decl));
510 : :
511 : 29 : if (dump_file)
512 : 0 : fprintf (dump_file, "Optimizing weakref %s %s\n",
513 : : node->dump_name (),
514 : : static_alias ? "as static alias" : "as transparent alias");
515 : :
516 : 29 : if (static_alias)
517 : : {
518 : : /* make_decl_local will shortcircuit if it doesn't see TREE_PUBLIC.
519 : : be sure it really clears the WEAK flag. */
520 : 29 : TREE_PUBLIC (node->decl) = true;
521 : 29 : node->make_decl_local ();
522 : 29 : node->forced_by_abi = false;
523 : 29 : node->resolution = LDPR_PREVAILING_DEF_IRONLY;
524 : 29 : node->externally_visible = false;
525 : 29 : gcc_assert (!DECL_WEAK (node->decl));
526 : 29 : node->transparent_alias = false;
527 : : }
528 : : else
529 : : {
530 : 0 : symtab->change_decl_assembler_name
531 : 0 : (node->decl, DECL_ASSEMBLER_NAME (node->get_alias_target ()->decl));
532 : 0 : node->transparent_alias = true;
533 : 0 : node->copy_visibility_from (target);
534 : : }
535 : 29 : gcc_assert (node->alias);
536 : : }
537 : :
538 : : /* NODE is an externally visible definition, which we've discovered is
539 : : not needed externally. Make it local to this compilation. */
540 : :
541 : : static void
542 : 3559018 : localize_node (bool whole_program, symtab_node *node)
543 : : {
544 : 3559018 : gcc_assert (whole_program || in_lto_p || !TREE_PUBLIC (node->decl));
545 : :
546 : : /* It is possible that one comdat group contains both hidden and non-hidden
547 : : symbols. In this case we can privatize all hidden symbol but we need
548 : : to keep non-hidden exported. */
549 : 3559018 : if (node->same_comdat_group
550 : 9428 : && (node->resolution == LDPR_PREVAILING_DEF_IRONLY
551 : 7938 : || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP))
552 : : {
553 : : symtab_node *next;
554 : 1785 : for (next = node->same_comdat_group;
555 : 3431 : next != node; next = next->same_comdat_group)
556 : 1863 : if (next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP
557 : 1785 : || next->resolution == LDPR_PREVAILING_DEF)
558 : : break;
559 : 1646 : if (node != next)
560 : : {
561 : 78 : if (!node->transparent_alias)
562 : : {
563 : 78 : node->resolution = LDPR_PREVAILING_DEF_IRONLY;
564 : 78 : node->make_decl_local ();
565 : 78 : if (!flag_incremental_link)
566 : 78 : node->unique_name |= true;
567 : 78 : return;
568 : : }
569 : : }
570 : : }
571 : : /* For similar reason do not privatize whole comdat when seeing comdat
572 : : local. Wait for non-comdat symbol to be privatized first. */
573 : 3558940 : if (node->comdat_local_p ())
574 : : return;
575 : :
576 : 3551340 : if (node->same_comdat_group && TREE_PUBLIC (node->decl))
577 : : {
578 : 2097 : for (symtab_node *next = node->same_comdat_group;
579 : 3847 : next != node; next = next->same_comdat_group)
580 : : {
581 : 2097 : next->set_comdat_group (NULL);
582 : 2097 : if (!next->alias)
583 : 1890 : next->set_section (NULL);
584 : 2097 : if (!next->transparent_alias)
585 : 2097 : next->make_decl_local ();
586 : 2097 : next->unique_name
587 : 2097 : |= ((next->resolution == LDPR_PREVAILING_DEF_IRONLY
588 : 365 : || next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
589 : 1732 : && TREE_PUBLIC (next->decl)
590 : 2097 : && !flag_incremental_link);
591 : : }
592 : :
593 : : /* Now everything's localized, the grouping has no meaning, and
594 : : will cause crashes if we keep it around. */
595 : 1750 : node->dissolve_same_comdat_group_list ();
596 : : }
597 : :
598 : 3551340 : node->unique_name
599 : 7102680 : |= ((node->resolution == LDPR_PREVAILING_DEF_IRONLY
600 : 1805868 : || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
601 : 1745874 : && TREE_PUBLIC (node->decl)
602 : 3599344 : && !flag_incremental_link);
603 : :
604 : 3551340 : if (TREE_PUBLIC (node->decl))
605 : 48880 : node->set_comdat_group (NULL);
606 : 3551340 : if (DECL_COMDAT (node->decl) && !node->alias)
607 : 5047 : node->set_section (NULL);
608 : 3551340 : if (!node->transparent_alias)
609 : : {
610 : 3551340 : node->resolution = LDPR_PREVAILING_DEF_IRONLY;
611 : 3551340 : node->make_decl_local ();
612 : : }
613 : : }
614 : :
615 : : /* Decide on visibility of all symbols. */
616 : :
617 : : static unsigned int
618 : 454244 : function_and_variable_visibility (bool whole_program)
619 : : {
620 : 454244 : struct cgraph_node *node;
621 : 454244 : varpool_node *vnode;
622 : :
623 : : /* All aliases should be processed at this point. */
624 : 454244 : gcc_checking_assert (!alias_pairs || !alias_pairs->length ());
625 : :
626 : 454244 : if (TARGET_SUPPORTS_ALIASES)
627 : : {
628 : 5410428 : FOR_EACH_DEFINED_FUNCTION (node)
629 : : {
630 : 4956184 : if (node->get_availability () != AVAIL_INTERPOSABLE
631 : 109890 : || DECL_EXTERNAL (node->decl)
632 : 109890 : || node->has_aliases_p ()
633 : 5061766 : || lookup_attribute ("noipa", DECL_ATTRIBUTES (node->decl)))
634 : 4887635 : continue;
635 : :
636 : 68549 : cgraph_node *alias = 0;
637 : 68549 : cgraph_edge *next_edge;
638 : 312193 : for (cgraph_edge *e = node->callees; e; e = next_edge)
639 : : {
640 : 243644 : next_edge = e->next_callee;
641 : : /* Recursive function calls usually can't be interposed. */
642 : :
643 : 243644 : if (!e->recursive_p ())
644 : 242697 : continue;
645 : :
646 : 947 : if (!alias)
647 : : {
648 : 271 : alias
649 : 271 : = dyn_cast<cgraph_node *> (node->noninterposable_alias ());
650 : 271 : gcc_assert (alias && alias != node);
651 : : }
652 : :
653 : 947 : e->redirect_callee (alias);
654 : 947 : if (gimple_has_body_p (e->caller->decl))
655 : : {
656 : 947 : push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
657 : 947 : cgraph_edge::redirect_call_stmt_to_callee (e);
658 : 947 : pop_cfun ();
659 : : }
660 : : }
661 : : }
662 : : }
663 : :
664 : 17652862 : FOR_EACH_FUNCTION (node)
665 : : {
666 : 8372187 : int flags = flags_from_decl_or_type (node->decl);
667 : :
668 : : /* Optimize away PURE and CONST constructors and destructors. */
669 : 8372187 : if (node->analyzed
670 : 4956455 : && (DECL_STATIC_CONSTRUCTOR (node->decl)
671 : 4917703 : || DECL_STATIC_DESTRUCTOR (node->decl))
672 : 39326 : && (flags & (ECF_CONST | ECF_PURE))
673 : 23 : && !(flags & ECF_LOOPING_CONST_OR_PURE)
674 : 8372187 : && opt_for_fn (node->decl, optimize))
675 : : {
676 : 0 : DECL_STATIC_CONSTRUCTOR (node->decl) = 0;
677 : 0 : DECL_STATIC_DESTRUCTOR (node->decl) = 0;
678 : : }
679 : :
680 : : /* Frontends and alias code marks nodes as needed before parsing
681 : : is finished. We may end up marking as node external nodes
682 : : where this flag is meaningless strip it. */
683 : 8372187 : if (DECL_EXTERNAL (node->decl) || !node->definition)
684 : : {
685 : 3653025 : node->force_output = 0;
686 : 3653025 : node->forced_by_abi = 0;
687 : : }
688 : :
689 : : /* C++ FE on lack of COMDAT support create local COMDAT functions
690 : : (that ought to be shared but cannot due to object format
691 : : limitations). It is necessary to keep the flag to make rest of C++ FE
692 : : happy. Clear the flag here to avoid confusion in middle-end. */
693 : 8372187 : if (DECL_COMDAT (node->decl) && !TREE_PUBLIC (node->decl))
694 : 29 : DECL_COMDAT (node->decl) = 0;
695 : :
696 : : /* For external decls stop tracking same_comdat_group. It doesn't matter
697 : : what comdat group they are in when they won't be emitted in this TU.
698 : :
699 : : An exception is LTO where we may end up with both external
700 : : and non-external declarations in the same comdat group in
701 : : the case declarations was not merged. */
702 : 8372187 : if (node->same_comdat_group && DECL_EXTERNAL (node->decl) && !in_lto_p)
703 : : {
704 : 24 : if (flag_checking)
705 : : {
706 : 30 : for (symtab_node *n = node->same_comdat_group;
707 : 54 : n != node;
708 : 30 : n = n->same_comdat_group)
709 : : /* If at least one of same comdat group functions is external,
710 : : all of them have to be, otherwise it is a front-end bug. */
711 : 30 : gcc_assert (DECL_EXTERNAL (n->decl));
712 : : }
713 : 24 : node->dissolve_same_comdat_group_list ();
714 : : }
715 : 8372187 : gcc_assert ((!DECL_WEAK (node->decl)
716 : : && !DECL_COMDAT (node->decl))
717 : : || TREE_PUBLIC (node->decl)
718 : : || node->weakref
719 : : || DECL_EXTERNAL (node->decl));
720 : 8372187 : if (cgraph_externally_visible_p (node, whole_program))
721 : : {
722 : 4032070 : gcc_assert (!node->inlined_to);
723 : 4032070 : node->externally_visible = true;
724 : : }
725 : : else
726 : : {
727 : 4340117 : node->externally_visible = false;
728 : 4340117 : node->forced_by_abi = false;
729 : : }
730 : 8372187 : if (!node->externally_visible
731 : 8372187 : && node->definition && !node->weakref
732 : 8372187 : && !DECL_EXTERNAL (node->decl))
733 : 687080 : localize_node (whole_program, node);
734 : :
735 : 8372187 : if (node->thunk
736 : 5935 : && TREE_PUBLIC (node->decl))
737 : : {
738 : 5792 : struct cgraph_node *decl_node = node;
739 : :
740 : 5792 : decl_node = decl_node->callees->callee->function_symbol ();
741 : :
742 : : /* Thunks have the same visibility as function they are attached to.
743 : : Make sure the C++ front end set this up properly. */
744 : 5792 : if (DECL_ONE_ONLY (decl_node->decl))
745 : : {
746 : 4641 : gcc_checking_assert (DECL_COMDAT (node->decl)
747 : : == DECL_COMDAT (decl_node->decl));
748 : 4641 : gcc_checking_assert (node->in_same_comdat_group_p (decl_node));
749 : 4641 : gcc_checking_assert (node->same_comdat_group);
750 : : }
751 : 5792 : node->forced_by_abi = decl_node->forced_by_abi;
752 : 5792 : if (DECL_EXTERNAL (decl_node->decl))
753 : 2 : DECL_EXTERNAL (node->decl) = 1;
754 : : }
755 : :
756 : 8372187 : update_visibility_by_resolution_info (node);
757 : 8372187 : if (node->weakref)
758 : 230 : optimize_weakref (node);
759 : : }
760 : 5410699 : FOR_EACH_DEFINED_FUNCTION (node)
761 : : {
762 : 4956455 : if (!node->local)
763 : 4814711 : node->local |= node->local_p ();
764 : :
765 : : /* If we know that function cannot be overwritten by a
766 : : different semantics and moreover its section cannot be
767 : : discarded, replace all direct calls by calls to an
768 : : noninterposable alias. This make dynamic linking cheaper and
769 : : enable more optimization.
770 : :
771 : : TODO: We can also update virtual tables. */
772 : 4956455 : if (node->callers
773 : 4956455 : && can_replace_by_local_alias (node))
774 : : {
775 : 96 : cgraph_node *alias = dyn_cast<cgraph_node *>
776 : 96 : (node->noninterposable_alias ());
777 : :
778 : 96 : if (alias && alias != node)
779 : : {
780 : 223 : while (node->callers)
781 : : {
782 : 128 : struct cgraph_edge *e = node->callers;
783 : :
784 : 128 : e->redirect_callee (alias);
785 : 128 : if (gimple_has_body_p (e->caller->decl))
786 : : {
787 : 125 : push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
788 : 125 : cgraph_edge::redirect_call_stmt_to_callee (e);
789 : 125 : pop_cfun ();
790 : : }
791 : : }
792 : : }
793 : : }
794 : : }
795 : 13694694 : FOR_EACH_VARIABLE (vnode)
796 : : {
797 : : /* weak flag makes no sense on local variables. */
798 : 6393103 : gcc_assert (!DECL_WEAK (vnode->decl)
799 : : || vnode->weakref
800 : : || TREE_PUBLIC (vnode->decl)
801 : : || DECL_EXTERNAL (vnode->decl));
802 : : /* In several cases declarations cannot be common:
803 : :
804 : : - when declaration has initializer
805 : : - when it is in weak
806 : : - when it has specific section
807 : : - when it resides in non-generic address space.
808 : : - if declaration is local, it will get into .local common section
809 : : so common flag is not needed. Frontends still produce these in
810 : : certain cases, such as for:
811 : :
812 : : static int a __attribute__ ((common))
813 : :
814 : : Canonicalize things here and clear the redundant flag. */
815 : 6393103 : if (DECL_COMMON (vnode->decl)
816 : 6393103 : && (!(TREE_PUBLIC (vnode->decl)
817 : 47 : || DECL_EXTERNAL (vnode->decl))
818 : 26360 : || (DECL_INITIAL (vnode->decl)
819 : 23465 : && DECL_INITIAL (vnode->decl) != error_mark_node)
820 : 2895 : || DECL_WEAK (vnode->decl)
821 : 2892 : || DECL_SECTION_NAME (vnode->decl) != NULL
822 : 2887 : || ! (ADDR_SPACE_GENERIC_P
823 : : (TYPE_ADDR_SPACE (TREE_TYPE (vnode->decl))))))
824 : 23520 : DECL_COMMON (vnode->decl) = 0;
825 : 6393103 : if (vnode->weakref)
826 : 74 : optimize_weakref (vnode);
827 : : }
828 : 6261646 : FOR_EACH_DEFINED_VARIABLE (vnode)
829 : : {
830 : 5807402 : if (!vnode->definition)
831 : 0 : continue;
832 : 5807402 : if (vnode->externally_visible_p ())
833 : 2935456 : vnode->externally_visible = true;
834 : : else
835 : : {
836 : 2871946 : vnode->externally_visible = false;
837 : 2871946 : vnode->forced_by_abi = false;
838 : : }
839 : 5807402 : if (lookup_attribute ("no_reorder",
840 : 5807402 : DECL_ATTRIBUTES (vnode->decl)))
841 : 4 : vnode->no_reorder = 1;
842 : :
843 : 5807402 : if (!vnode->externally_visible
844 : 5807402 : && !vnode->transparent_alias
845 : 5807402 : && !DECL_EXTERNAL (vnode->decl))
846 : 2871938 : localize_node (whole_program, vnode);
847 : :
848 : 5807402 : update_visibility_by_resolution_info (vnode);
849 : :
850 : : /* Update virtual tables to point to local aliases where possible. */
851 : 5807402 : if (DECL_VIRTUAL_P (vnode->decl)
852 : 5807402 : && !DECL_EXTERNAL (vnode->decl))
853 : : {
854 : : int i;
855 : : struct ipa_ref *ref;
856 : 292402 : bool found = false;
857 : :
858 : : /* See if there is something to update. */
859 : 292402 : for (i = 0; vnode->iterate_reference (i, ref); i++)
860 : 250078 : if (ref->use == IPA_REF_ADDR
861 : 250078 : && can_replace_by_local_alias_in_vtable (ref->referred))
862 : : {
863 : : found = true;
864 : : break;
865 : : }
866 : 42327 : if (found)
867 : : {
868 : 3 : hash_set<tree> visited_nodes;
869 : :
870 : 3 : vnode->get_constructor ();
871 : 3 : walk_tree (&DECL_INITIAL (vnode->decl),
872 : : update_vtable_references, NULL, &visited_nodes);
873 : 3 : vnode->remove_all_references ();
874 : 3 : record_references_in_initializer (vnode->decl, false);
875 : 3 : }
876 : : }
877 : : }
878 : :
879 : 454244 : if (symtab->state >= IPA_SSA)
880 : : {
881 : 3593533 : FOR_EACH_VARIABLE (vnode)
882 : : {
883 : 3139827 : tree decl = vnode->decl;
884 : :
885 : : /* Upgrade TLS access model based on optimized visibility status,
886 : : unless it was specified explicitly or no references remain. */
887 : 3139827 : if (DECL_THREAD_LOCAL_P (decl)
888 : 4214 : && !lookup_attribute ("tls_model", DECL_ATTRIBUTES (decl))
889 : 6283379 : && vnode->ref_list.referring.length ())
890 : : {
891 : 3725 : enum tls_model new_model = decl_default_tls_model (decl);
892 : 3725 : STATIC_ASSERT (TLS_MODEL_GLOBAL_DYNAMIC < TLS_MODEL_LOCAL_DYNAMIC);
893 : 3725 : STATIC_ASSERT (TLS_MODEL_INITIAL_EXEC < TLS_MODEL_LOCAL_EXEC);
894 : : /* We'd prefer to assert that recomputed model is not weaker than
895 : : what the front-end assigned, but cannot: see PR 107353. */
896 : 3725 : if (new_model >= decl_tls_model (decl))
897 : 3725 : set_decl_tls_model (decl, new_model);
898 : : }
899 : : }
900 : : }
901 : :
902 : 454244 : if (dump_file)
903 : : {
904 : 117 : fprintf (dump_file, "\nMarking local functions:");
905 : 277 : FOR_EACH_DEFINED_FUNCTION (node)
906 : 160 : if (node->local)
907 : 0 : fprintf (dump_file, " %s", node->dump_name ());
908 : 117 : fprintf (dump_file, "\n\n");
909 : 117 : fprintf (dump_file, "\nMarking externally visible functions:");
910 : 277 : FOR_EACH_DEFINED_FUNCTION (node)
911 : 160 : if (node->externally_visible)
912 : 157 : fprintf (dump_file, " %s", node->dump_name ());
913 : 117 : fprintf (dump_file, "\n\n");
914 : 117 : fprintf (dump_file, "\nMarking externally visible variables:");
915 : 189 : FOR_EACH_DEFINED_VARIABLE (vnode)
916 : 72 : if (vnode->externally_visible)
917 : 41 : fprintf (dump_file, " %s", vnode->dump_name ());
918 : 117 : fprintf (dump_file, "\n\n");
919 : : }
920 : 454244 : symtab->function_flags_ready = true;
921 : 454244 : return 0;
922 : : }
923 : :
924 : : /* Local function pass handling visibilities. This happens before LTO streaming
925 : : so in particular -fwhole-program should be ignored at this level. */
926 : :
927 : : namespace {
928 : :
929 : : const pass_data pass_data_ipa_function_and_variable_visibility =
930 : : {
931 : : SIMPLE_IPA_PASS, /* type */
932 : : "visibility", /* name */
933 : : OPTGROUP_NONE, /* optinfo_flags */
934 : : TV_CGRAPHOPT, /* tv_id */
935 : : 0, /* properties_required */
936 : : 0, /* properties_provided */
937 : : 0, /* properties_destroyed */
938 : : 0, /* todo_flags_start */
939 : : ( TODO_remove_functions | TODO_dump_symtab ), /* todo_flags_finish */
940 : : };
941 : :
942 : : /* Bring functions local at LTO time with -fwhole-program. */
943 : :
944 : : static unsigned int
945 : 226853 : whole_program_function_and_variable_visibility (void)
946 : : {
947 : 226853 : function_and_variable_visibility (flag_whole_program);
948 : 226853 : if (optimize || in_lto_p)
949 : 148877 : ipa_discover_variable_flags ();
950 : 226853 : return 0;
951 : : }
952 : :
953 : : } // anon namespace
954 : :
955 : : namespace {
956 : :
957 : : const pass_data pass_data_ipa_whole_program_visibility =
958 : : {
959 : : IPA_PASS, /* type */
960 : : "whole-program", /* name */
961 : : OPTGROUP_NONE, /* optinfo_flags */
962 : : TV_CGRAPHOPT, /* tv_id */
963 : : 0, /* properties_required */
964 : : 0, /* properties_provided */
965 : : 0, /* properties_destroyed */
966 : : 0, /* todo_flags_start */
967 : : ( TODO_remove_functions | TODO_dump_symtab ), /* todo_flags_finish */
968 : : };
969 : :
970 : : class pass_ipa_whole_program_visibility : public ipa_opt_pass_d
971 : : {
972 : : public:
973 : 283157 : pass_ipa_whole_program_visibility (gcc::context *ctxt)
974 : : : ipa_opt_pass_d (pass_data_ipa_whole_program_visibility, ctxt,
975 : : NULL, /* generate_summary */
976 : : NULL, /* write_summary */
977 : : NULL, /* read_summary */
978 : : NULL, /* write_optimization_summary */
979 : : NULL, /* read_optimization_summary */
980 : : NULL, /* stmt_fixup */
981 : : 0, /* function_transform_todo_flags_start */
982 : : NULL, /* function_transform */
983 : 283157 : NULL) /* variable_transform */
984 : 283157 : {}
985 : :
986 : : /* opt_pass methods: */
987 : :
988 : 558814 : bool gate (function *) final override
989 : : {
990 : : /* Do not re-run on ltrans stage. */
991 : 558814 : return !flag_ltrans;
992 : : }
993 : 226853 : unsigned int execute (function *) final override
994 : : {
995 : 226853 : return whole_program_function_and_variable_visibility ();
996 : : }
997 : :
998 : : }; // class pass_ipa_whole_program_visibility
999 : :
1000 : : } // anon namespace
1001 : :
1002 : : ipa_opt_pass_d *
1003 : 283157 : make_pass_ipa_whole_program_visibility (gcc::context *ctxt)
1004 : : {
1005 : 283157 : return new pass_ipa_whole_program_visibility (ctxt);
1006 : : }
1007 : :
1008 : : class pass_ipa_function_and_variable_visibility : public simple_ipa_opt_pass
1009 : : {
1010 : : public:
1011 : 283157 : pass_ipa_function_and_variable_visibility (gcc::context *ctxt)
1012 : : : simple_ipa_opt_pass (pass_data_ipa_function_and_variable_visibility,
1013 : 566314 : ctxt)
1014 : : {}
1015 : :
1016 : : /* opt_pass methods: */
1017 : 227391 : unsigned int execute (function *) final override
1018 : : {
1019 : 454687 : return function_and_variable_visibility (flag_whole_program && !flag_lto);
1020 : : }
1021 : :
1022 : : }; // class pass_ipa_function_and_variable_visibility
1023 : :
1024 : : simple_ipa_opt_pass *
1025 : 283157 : make_pass_ipa_function_and_variable_visibility (gcc::context *ctxt)
1026 : : {
1027 : 283157 : return new pass_ipa_function_and_variable_visibility (ctxt);
1028 : : }
|