1 /* IPA visibility pass
2 Copyright (C) 2003-2016 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 can not 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
87 /* Return true when NODE can not be local. Worker for cgraph_local_node_p. */
88
89 static bool
non_local_p(struct cgraph_node * node,void * data ATTRIBUTE_UNUSED)90 non_local_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
91 {
92 return !(node->only_called_directly_or_aliased_p ()
93 /* i386 would need update to output thunk with local calling
94 ocnvetions. */
95 && !node->thunk.thunk_p
96 && node->definition
97 && !DECL_EXTERNAL (node->decl)
98 && !node->externally_visible
99 && !node->used_from_other_partition
100 && !node->in_other_partition
101 && node->get_availability () >= AVAIL_AVAILABLE);
102 }
103
104 /* Return true when function can be marked local. */
105
106 bool
local_p(void)107 cgraph_node::local_p (void)
108 {
109 cgraph_node *n = ultimate_alias_target ();
110
111 if (n->thunk.thunk_p)
112 return n->callees->callee->local_p ();
113 return !n->call_for_symbol_thunks_and_aliases (non_local_p,
114 NULL, true);
115
116 }
117
118 /* A helper for comdat_can_be_unshared_p. */
119
120 static bool
comdat_can_be_unshared_p_1(symtab_node * node)121 comdat_can_be_unshared_p_1 (symtab_node *node)
122 {
123 if (!node->externally_visible)
124 return true;
125 if (node->address_can_be_compared_p ())
126 {
127 struct ipa_ref *ref;
128
129 for (unsigned int i = 0; node->iterate_referring (i, ref); i++)
130 if (ref->address_matters_p ())
131 return false;
132 }
133
134 /* If the symbol is used in some weird way, better to not touch it. */
135 if (node->force_output)
136 return false;
137
138 /* Explicit instantiations needs to be output when possibly
139 used externally. */
140 if (node->forced_by_abi
141 && TREE_PUBLIC (node->decl)
142 && (node->resolution != LDPR_PREVAILING_DEF_IRONLY
143 && !flag_whole_program))
144 return false;
145
146 /* Non-readonly and volatile variables can not be duplicated. */
147 if (is_a <varpool_node *> (node)
148 && (!TREE_READONLY (node->decl)
149 || TREE_THIS_VOLATILE (node->decl)))
150 return false;
151 return true;
152 }
153
154 /* COMDAT functions must be shared only if they have address taken,
155 otherwise we can produce our own private implementation with
156 -fwhole-program.
157 Return true when turning COMDAT function static can not lead to wrong
158 code when the resulting object links with a library defining same COMDAT.
159
160 Virtual functions do have their addresses taken from the vtables,
161 but in C++ there is no way to compare their addresses for equality. */
162
163 static bool
comdat_can_be_unshared_p(symtab_node * node)164 comdat_can_be_unshared_p (symtab_node *node)
165 {
166 if (!comdat_can_be_unshared_p_1 (node))
167 return false;
168 if (node->same_comdat_group)
169 {
170 symtab_node *next;
171
172 /* If more than one function is in the same COMDAT group, it must
173 be shared even if just one function in the comdat group has
174 address taken. */
175 for (next = node->same_comdat_group;
176 next != node; next = next->same_comdat_group)
177 if (!comdat_can_be_unshared_p_1 (next))
178 return false;
179 }
180 return true;
181 }
182
183 /* Return true when function NODE should be considered externally visible. */
184
185 static bool
cgraph_externally_visible_p(struct cgraph_node * node,bool whole_program)186 cgraph_externally_visible_p (struct cgraph_node *node,
187 bool whole_program)
188 {
189 while (node->transparent_alias && node->definition)
190 node = node->get_alias_target ();
191 if (!node->definition)
192 return false;
193 if (!TREE_PUBLIC (node->decl)
194 || DECL_EXTERNAL (node->decl))
195 return false;
196
197 /* Do not try to localize built-in functions yet. One of problems is that we
198 end up mangling their asm for WHOPR that makes it impossible to call them
199 using the implicit built-in declarations anymore. Similarly this enables
200 us to remove them as unreachable before actual calls may appear during
201 expansion or folding. */
202 if (DECL_BUILT_IN (node->decl))
203 return true;
204
205 /* If linker counts on us, we must preserve the function. */
206 if (node->used_from_object_file_p ())
207 return true;
208 if (DECL_PRESERVE_P (node->decl))
209 return true;
210 if (lookup_attribute ("externally_visible",
211 DECL_ATTRIBUTES (node->decl)))
212 return true;
213 if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
214 && lookup_attribute ("dllexport",
215 DECL_ATTRIBUTES (node->decl)))
216 return true;
217 if (node->resolution == LDPR_PREVAILING_DEF_IRONLY)
218 return false;
219 /* When doing LTO or whole program, we can bring COMDAT functoins static.
220 This improves code quality and we know we will duplicate them at most twice
221 (in the case that we are not using plugin and link with object file
222 implementing same COMDAT) */
223 if (((in_lto_p || whole_program) && !flag_incremental_link)
224 && DECL_COMDAT (node->decl)
225 && comdat_can_be_unshared_p (node))
226 return false;
227
228 /* When doing link time optimizations, hidden symbols become local. */
229 if ((in_lto_p && !flag_incremental_link)
230 && (DECL_VISIBILITY (node->decl) == VISIBILITY_HIDDEN
231 || DECL_VISIBILITY (node->decl) == VISIBILITY_INTERNAL)
232 /* Be sure that node is defined in IR file, not in other object
233 file. In that case we don't set used_from_other_object_file. */
234 && node->definition)
235 ;
236 else if (!whole_program)
237 return true;
238
239 if (MAIN_NAME_P (DECL_NAME (node->decl)))
240 return true;
241
242 if (node->instrumentation_clone
243 && MAIN_NAME_P (DECL_NAME (node->orig_decl)))
244 return true;
245
246 return false;
247 }
248
249 /* Return true when variable should be considered externally visible. */
250
251 bool
externally_visible_p(void)252 varpool_node::externally_visible_p (void)
253 {
254 while (transparent_alias && definition)
255 return get_alias_target ()->externally_visible_p ();
256 if (DECL_EXTERNAL (decl))
257 return true;
258
259 if (!TREE_PUBLIC (decl))
260 return false;
261
262 /* If linker counts on us, we must preserve the function. */
263 if (used_from_object_file_p ())
264 return true;
265
266 /* Bringing TLS variables local may cause dynamic linker failures
267 on limits of static TLS vars. */
268 if (DECL_THREAD_LOCAL_P (decl)
269 && (DECL_TLS_MODEL (decl) != TLS_MODEL_EMULATED
270 && DECL_TLS_MODEL (decl) != TLS_MODEL_INITIAL_EXEC))
271 return true;
272
273 if (DECL_HARD_REGISTER (decl))
274 return true;
275 if (DECL_PRESERVE_P (decl))
276 return true;
277 if (lookup_attribute ("externally_visible",
278 DECL_ATTRIBUTES (decl)))
279 return true;
280 if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
281 && lookup_attribute ("dllexport",
282 DECL_ATTRIBUTES (decl)))
283 return true;
284
285 /* See if we have linker information about symbol not being used or
286 if we need to make guess based on the declaration.
287
288 Even if the linker clams the symbol is unused, never bring internal
289 symbols that are declared by user as used or externally visible.
290 This is needed for i.e. references from asm statements. */
291 if (used_from_object_file_p ())
292 return true;
293 if (resolution == LDPR_PREVAILING_DEF_IRONLY)
294 return false;
295
296 /* As a special case, the COMDAT virtual tables can be unshared.
297 In LTO mode turn vtables into static variables. The variable is readonly,
298 so this does not enable more optimization, but referring static var
299 is faster for dynamic linking. Also this match logic hidding vtables
300 from LTO symbol tables. */
301 if (((in_lto_p || flag_whole_program) && !flag_incremental_link)
302 && DECL_COMDAT (decl)
303 && comdat_can_be_unshared_p (this))
304 return false;
305
306 /* When doing link time optimizations, hidden symbols become local. */
307 if (in_lto_p && !flag_incremental_link
308 && (DECL_VISIBILITY (decl) == VISIBILITY_HIDDEN
309 || DECL_VISIBILITY (decl) == VISIBILITY_INTERNAL)
310 /* Be sure that node is defined in IR file, not in other object
311 file. In that case we don't set used_from_other_object_file. */
312 && definition)
313 ;
314 else if (!flag_whole_program)
315 return true;
316
317 /* Do not attempt to privatize COMDATS by default.
318 This would break linking with C++ libraries sharing
319 inline definitions.
320
321 FIXME: We can do so for readonly vars with no address taken and
322 possibly also for vtables since no direct pointer comparsion is done.
323 It might be interesting to do so to reduce linking overhead. */
324 if (DECL_COMDAT (decl) || DECL_WEAK (decl))
325 return true;
326 return false;
327 }
328
329 /* Return true if reference to NODE can be replaced by a local alias.
330 Local aliases save dynamic linking overhead and enable more optimizations.
331 */
332
333 static bool
can_replace_by_local_alias(symtab_node * node)334 can_replace_by_local_alias (symtab_node *node)
335 {
336 #ifndef ASM_OUTPUT_DEF
337 /* If aliases aren't supported, we can't do replacement. */
338 return false;
339 #endif
340 /* Weakrefs have a reason to be non-local. Be sure we do not replace
341 them. */
342 while (node->transparent_alias && node->definition && !node->weakref)
343 node = node->get_alias_target ();
344 if (node->weakref)
345 return false;
346
347 return (node->get_availability () > AVAIL_INTERPOSABLE
348 && !decl_binds_to_current_def_p (node->decl)
349 && !node->can_be_discarded_p ());
350 }
351
352 /* Return true if we can replace reference to NODE by local alias
353 within a virtual table. Generally we can replace function pointers
354 and virtual table pointers. */
355
356 static bool
can_replace_by_local_alias_in_vtable(symtab_node * node)357 can_replace_by_local_alias_in_vtable (symtab_node *node)
358 {
359 if (is_a <varpool_node *> (node)
360 && !DECL_VIRTUAL_P (node->decl))
361 return false;
362 return can_replace_by_local_alias (node);
363 }
364
365 /* walk_tree callback that rewrites initializer references. */
366
367 static tree
update_vtable_references(tree * tp,int * walk_subtrees,void * data ATTRIBUTE_UNUSED)368 update_vtable_references (tree *tp, int *walk_subtrees,
369 void *data ATTRIBUTE_UNUSED)
370 {
371 if (TREE_CODE (*tp) == VAR_DECL
372 || TREE_CODE (*tp) == FUNCTION_DECL)
373 {
374 if (can_replace_by_local_alias_in_vtable (symtab_node::get (*tp)))
375 *tp = symtab_node::get (*tp)->noninterposable_alias ()->decl;
376 *walk_subtrees = 0;
377 }
378 else if (IS_TYPE_OR_DECL_P (*tp))
379 *walk_subtrees = 0;
380 return NULL;
381 }
382
383 /* In LTO we can remove COMDAT groups and weak symbols.
384 Either turn them into normal symbols or external symbol depending on
385 resolution info. */
386
387 static void
update_visibility_by_resolution_info(symtab_node * node)388 update_visibility_by_resolution_info (symtab_node * node)
389 {
390 bool define;
391
392 if (!node->externally_visible
393 || (!DECL_WEAK (node->decl) && !DECL_ONE_ONLY (node->decl))
394 || node->resolution == LDPR_UNKNOWN)
395 return;
396
397 define = (node->resolution == LDPR_PREVAILING_DEF_IRONLY
398 || node->resolution == LDPR_PREVAILING_DEF
399 || node->resolution == LDPR_UNDEF
400 || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP);
401
402 /* The linker decisions ought to agree in the whole group. */
403 if (node->same_comdat_group)
404 for (symtab_node *next = node->same_comdat_group;
405 next != node; next = next->same_comdat_group)
406 {
407 if (!next->externally_visible || next->transparent_alias)
408 continue;
409
410 bool same_def
411 = define == (next->resolution == LDPR_PREVAILING_DEF_IRONLY
412 || next->resolution == LDPR_PREVAILING_DEF
413 || next->resolution == LDPR_UNDEF
414 || next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP);
415 gcc_assert (in_lto_p || same_def);
416 if (!same_def)
417 return;
418 }
419
420 if (node->same_comdat_group)
421 for (symtab_node *next = node->same_comdat_group;
422 next != node; next = next->same_comdat_group)
423 {
424 /* During incremental linking we need to keep symbol weak for future
425 linking. We can still drop definition if we know non-LTO world
426 prevails. */
427 if (!flag_incremental_link)
428 {
429 DECL_WEAK (next->decl) = false;
430 next->set_comdat_group (NULL);
431 }
432 if (!define)
433 {
434 if (next->externally_visible)
435 DECL_EXTERNAL (next->decl) = true;
436 next->set_comdat_group (NULL);
437 }
438 }
439
440 /* During incremental linking we need to keep symbol weak for future
441 linking. We can still drop definition if we know non-LTO world prevails. */
442 if (!flag_incremental_link)
443 {
444 DECL_WEAK (node->decl) = false;
445 node->set_comdat_group (NULL);
446 node->dissolve_same_comdat_group_list ();
447 }
448 if (!define)
449 {
450 DECL_EXTERNAL (node->decl) = true;
451 node->set_comdat_group (NULL);
452 node->dissolve_same_comdat_group_list ();
453 }
454 }
455
456 /* Try to get rid of weakref. */
457
458 static void
optimize_weakref(symtab_node * node)459 optimize_weakref (symtab_node *node)
460 {
461 #ifdef ASM_OUTPUT_DEF
462 bool aliases_supported = true;
463 #else
464 bool aliases_supported = false;
465 #endif
466 bool strip_weakref = false;
467 bool static_alias = false;
468
469 gcc_assert (node->weakref);
470
471 /* Weakrefs with no target defined can not be optimized. */
472 if (!node->analyzed)
473 return;
474 symtab_node *target = node->get_alias_target ();
475
476 /* Weakrefs to weakrefs can be optimized only if target can be. */
477 if (target->weakref)
478 optimize_weakref (target);
479 if (target->weakref)
480 return;
481
482 /* If we have definition of weakref's target and we know it binds locally,
483 we can turn weakref to static alias. */
484 if (target->definition && decl_binds_to_current_def_p (target->decl)
485 && aliases_supported)
486 strip_weakref = static_alias = true;
487 /* Otherwise we can turn weakref into transparent alias. This transformation
488 may break asm statements which directly refers to symbol name and expect
489 GNU as to translate it via .weakref directive. So do not optimize when
490 DECL_PRESERVED is set and .weakref is supported. */
491 else if ((!DECL_PRESERVE_P (target->decl)
492 || IDENTIFIER_TRANSPARENT_ALIAS (DECL_ASSEMBLER_NAME (node->decl)))
493 && !DECL_WEAK (target->decl)
494 && !DECL_EXTERNAL (target->decl)
495 && ((target->definition && !target->can_be_discarded_p ())
496 || target->resolution != LDPR_UNDEF))
497 strip_weakref = true;
498 if (!strip_weakref)
499 return;
500 node->weakref = false;
501 IDENTIFIER_TRANSPARENT_ALIAS (DECL_ASSEMBLER_NAME (node->decl)) = 0;
502 TREE_CHAIN (DECL_ASSEMBLER_NAME (node->decl)) = NULL_TREE;
503 DECL_ATTRIBUTES (node->decl) = remove_attribute ("weakref",
504 DECL_ATTRIBUTES
505 (node->decl));
506
507 if (dump_file)
508 fprintf (dump_file, "Optimizing weakref %s %s\n",
509 node->name(),
510 static_alias ? "as static alias" : "as transparent alias");
511
512 if (static_alias)
513 {
514 /* make_decl_local will shortcircuit if it doesn't see TREE_PUBLIC.
515 be sure it really clears the WEAK flag. */
516 TREE_PUBLIC (node->decl) = true;
517 node->make_decl_local ();
518 node->forced_by_abi = false;
519 node->resolution = LDPR_PREVAILING_DEF_IRONLY;
520 node->externally_visible = false;
521 gcc_assert (!DECL_WEAK (node->decl));
522 node->transparent_alias = false;
523 }
524 else
525 {
526 symtab->change_decl_assembler_name
527 (node->decl, DECL_ASSEMBLER_NAME (node->get_alias_target ()->decl));
528 node->transparent_alias = true;
529 node->copy_visibility_from (target);
530 }
531 gcc_assert (node->alias);
532 }
533
534 /* NODE is an externally visible definition, which we've discovered is
535 not needed externally. Make it local to this compilation. */
536
537 static void
localize_node(bool whole_program,symtab_node * node)538 localize_node (bool whole_program, symtab_node *node)
539 {
540 gcc_assert (whole_program || in_lto_p || !TREE_PUBLIC (node->decl));
541
542 /* It is possible that one comdat group contains both hidden and non-hidden
543 symbols. In this case we can privatize all hidden symbol but we need
544 to keep non-hidden exported. */
545 if (node->same_comdat_group
546 && node->resolution == LDPR_PREVAILING_DEF_IRONLY)
547 {
548 symtab_node *next;
549 for (next = node->same_comdat_group;
550 next != node; next = next->same_comdat_group)
551 if (next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP
552 || next->resolution == LDPR_PREVAILING_DEF)
553 break;
554 if (node != next)
555 {
556 if (!node->transparent_alias)
557 {
558 node->resolution = LDPR_PREVAILING_DEF_IRONLY;
559 node->make_decl_local ();
560 if (!flag_incremental_link)
561 node->unique_name |= true;
562 return;
563 }
564 }
565 }
566 /* For similar reason do not privatize whole comdat when seeing comdat
567 local. Wait for non-comdat symbol to be privatized first. */
568 if (node->comdat_local_p ())
569 return;
570
571 if (node->same_comdat_group && TREE_PUBLIC (node->decl))
572 {
573 for (symtab_node *next = node->same_comdat_group;
574 next != node; next = next->same_comdat_group)
575 {
576 next->set_comdat_group (NULL);
577 if (!next->alias)
578 next->set_section (NULL);
579 if (!next->transparent_alias)
580 next->make_decl_local ();
581 next->unique_name
582 |= ((next->resolution == LDPR_PREVAILING_DEF_IRONLY
583 || next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
584 && TREE_PUBLIC (next->decl)
585 && !flag_incremental_link);
586 }
587
588 /* Now everything's localized, the grouping has no meaning, and
589 will cause crashes if we keep it around. */
590 node->dissolve_same_comdat_group_list ();
591 }
592
593 node->unique_name
594 |= ((node->resolution == LDPR_PREVAILING_DEF_IRONLY
595 || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
596 && TREE_PUBLIC (node->decl)
597 && !flag_incremental_link);
598
599 if (TREE_PUBLIC (node->decl))
600 node->set_comdat_group (NULL);
601 if (DECL_COMDAT (node->decl) && !node->alias)
602 node->set_section (NULL);
603 if (!node->transparent_alias)
604 {
605 node->resolution = LDPR_PREVAILING_DEF_IRONLY;
606 node->make_decl_local ();
607 }
608 }
609
610 /* Decide on visibility of all symbols. */
611
612 static unsigned int
function_and_variable_visibility(bool whole_program)613 function_and_variable_visibility (bool whole_program)
614 {
615 struct cgraph_node *node;
616 varpool_node *vnode;
617
618 /* All aliases should be procssed at this point. */
619 gcc_checking_assert (!alias_pairs || !alias_pairs->length ());
620
621 FOR_EACH_FUNCTION (node)
622 {
623 int flags = flags_from_decl_or_type (node->decl);
624
625 /* Optimize away PURE and CONST constructors and destructors. */
626 if (optimize
627 && (flags & (ECF_CONST | ECF_PURE))
628 && !(flags & ECF_LOOPING_CONST_OR_PURE))
629 {
630 DECL_STATIC_CONSTRUCTOR (node->decl) = 0;
631 DECL_STATIC_DESTRUCTOR (node->decl) = 0;
632 }
633
634 /* Frontends and alias code marks nodes as needed before parsing
635 is finished. We may end up marking as node external nodes
636 where this flag is meaningless strip it. */
637 if (DECL_EXTERNAL (node->decl) || !node->definition)
638 {
639 node->force_output = 0;
640 node->forced_by_abi = 0;
641 }
642
643 /* C++ FE on lack of COMDAT support create local COMDAT functions
644 (that ought to be shared but can not due to object format
645 limitations). It is necessary to keep the flag to make rest of C++ FE
646 happy. Clear the flag here to avoid confusion in middle-end. */
647 if (DECL_COMDAT (node->decl) && !TREE_PUBLIC (node->decl))
648 DECL_COMDAT (node->decl) = 0;
649
650 /* For external decls stop tracking same_comdat_group. It doesn't matter
651 what comdat group they are in when they won't be emitted in this TU.
652
653 An exception is LTO where we may end up with both external
654 and non-external declarations in the same comdat group in
655 the case declarations was not merged. */
656 if (node->same_comdat_group && DECL_EXTERNAL (node->decl) && !in_lto_p)
657 {
658 if (flag_checking)
659 {
660 for (symtab_node *n = node->same_comdat_group;
661 n != node;
662 n = n->same_comdat_group)
663 /* If at least one of same comdat group functions is external,
664 all of them have to be, otherwise it is a front-end bug. */
665 gcc_assert (DECL_EXTERNAL (n->decl));
666 }
667 node->dissolve_same_comdat_group_list ();
668 }
669 gcc_assert ((!DECL_WEAK (node->decl)
670 && !DECL_COMDAT (node->decl))
671 || TREE_PUBLIC (node->decl)
672 || node->weakref
673 || DECL_EXTERNAL (node->decl));
674 if (cgraph_externally_visible_p (node, whole_program))
675 {
676 gcc_assert (!node->global.inlined_to);
677 node->externally_visible = true;
678 }
679 else
680 {
681 node->externally_visible = false;
682 node->forced_by_abi = false;
683 }
684 if (!node->externally_visible
685 && node->definition && !node->weakref
686 && !DECL_EXTERNAL (node->decl))
687 localize_node (whole_program, node);
688
689 if (node->thunk.thunk_p
690 && !node->thunk.add_pointer_bounds_args
691 && TREE_PUBLIC (node->decl))
692 {
693 struct cgraph_node *decl_node = node;
694
695 decl_node = decl_node->callees->callee->function_symbol ();
696
697 /* Thunks have the same visibility as function they are attached to.
698 Make sure the C++ front end set this up properly. */
699 if (DECL_ONE_ONLY (decl_node->decl))
700 {
701 gcc_checking_assert (DECL_COMDAT (node->decl)
702 == DECL_COMDAT (decl_node->decl));
703 gcc_checking_assert (node->in_same_comdat_group_p (decl_node));
704 gcc_checking_assert (node->same_comdat_group);
705 }
706 node->forced_by_abi = decl_node->forced_by_abi;
707 if (DECL_EXTERNAL (decl_node->decl))
708 DECL_EXTERNAL (node->decl) = 1;
709 }
710
711 update_visibility_by_resolution_info (node);
712 if (node->weakref)
713 optimize_weakref (node);
714 }
715 FOR_EACH_DEFINED_FUNCTION (node)
716 {
717 if (!node->local.local)
718 node->local.local |= node->local_p ();
719
720 /* If we know that function can not be overwritten by a
721 different semantics and moreover its section can not be
722 discarded, replace all direct calls by calls to an
723 noninterposable alias. This make dynamic linking cheaper and
724 enable more optimization.
725
726 TODO: We can also update virtual tables. */
727 if (node->callers
728 && can_replace_by_local_alias (node))
729 {
730 cgraph_node *alias = dyn_cast<cgraph_node *>
731 (node->noninterposable_alias ());
732
733 if (alias && alias != node)
734 {
735 while (node->callers)
736 {
737 struct cgraph_edge *e = node->callers;
738
739 e->redirect_callee (alias);
740 if (gimple_has_body_p (e->caller->decl))
741 {
742 push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
743 e->redirect_call_stmt_to_callee ();
744 pop_cfun ();
745 }
746 }
747 }
748 }
749 }
750 FOR_EACH_VARIABLE (vnode)
751 {
752 /* weak flag makes no sense on local variables. */
753 gcc_assert (!DECL_WEAK (vnode->decl)
754 || vnode->weakref
755 || TREE_PUBLIC (vnode->decl)
756 || DECL_EXTERNAL (vnode->decl));
757 /* In several cases declarations can not be common:
758
759 - when declaration has initializer
760 - when it is in weak
761 - when it has specific section
762 - when it resides in non-generic address space.
763 - if declaration is local, it will get into .local common section
764 so common flag is not needed. Frontends still produce these in
765 certain cases, such as for:
766
767 static int a __attribute__ ((common))
768
769 Canonicalize things here and clear the redundant flag. */
770 if (DECL_COMMON (vnode->decl)
771 && (!(TREE_PUBLIC (vnode->decl)
772 || DECL_EXTERNAL (vnode->decl))
773 || (DECL_INITIAL (vnode->decl)
774 && DECL_INITIAL (vnode->decl) != error_mark_node)
775 || DECL_WEAK (vnode->decl)
776 || DECL_SECTION_NAME (vnode->decl) != NULL
777 || ! (ADDR_SPACE_GENERIC_P
778 (TYPE_ADDR_SPACE (TREE_TYPE (vnode->decl))))))
779 DECL_COMMON (vnode->decl) = 0;
780 if (vnode->weakref)
781 optimize_weakref (vnode);
782 }
783 FOR_EACH_DEFINED_VARIABLE (vnode)
784 {
785 if (!vnode->definition)
786 continue;
787 if (vnode->externally_visible_p ())
788 vnode->externally_visible = true;
789 else
790 {
791 vnode->externally_visible = false;
792 vnode->forced_by_abi = false;
793 }
794 if (lookup_attribute ("no_reorder",
795 DECL_ATTRIBUTES (vnode->decl)))
796 vnode->no_reorder = 1;
797
798 if (!vnode->externally_visible
799 && !vnode->transparent_alias
800 && !DECL_EXTERNAL (vnode->decl))
801 localize_node (whole_program, vnode);
802
803 update_visibility_by_resolution_info (vnode);
804
805 /* Update virtual tables to point to local aliases where possible. */
806 if (DECL_VIRTUAL_P (vnode->decl)
807 && !DECL_EXTERNAL (vnode->decl))
808 {
809 int i;
810 struct ipa_ref *ref;
811 bool found = false;
812
813 /* See if there is something to update. */
814 for (i = 0; vnode->iterate_reference (i, ref); i++)
815 if (ref->use == IPA_REF_ADDR
816 && can_replace_by_local_alias_in_vtable (ref->referred))
817 {
818 found = true;
819 break;
820 }
821 if (found)
822 {
823 hash_set<tree> visited_nodes;
824
825 vnode->get_constructor ();
826 walk_tree (&DECL_INITIAL (vnode->decl),
827 update_vtable_references, NULL, &visited_nodes);
828 vnode->remove_all_references ();
829 record_references_in_initializer (vnode->decl, false);
830 }
831 }
832 }
833
834 if (dump_file)
835 {
836 fprintf (dump_file, "\nMarking local functions:");
837 FOR_EACH_DEFINED_FUNCTION (node)
838 if (node->local.local)
839 fprintf (dump_file, " %s", node->name ());
840 fprintf (dump_file, "\n\n");
841 fprintf (dump_file, "\nMarking externally visible functions:");
842 FOR_EACH_DEFINED_FUNCTION (node)
843 if (node->externally_visible)
844 fprintf (dump_file, " %s", node->name ());
845 fprintf (dump_file, "\n\n");
846 fprintf (dump_file, "\nMarking externally visible variables:");
847 FOR_EACH_DEFINED_VARIABLE (vnode)
848 if (vnode->externally_visible)
849 fprintf (dump_file, " %s", vnode->name ());
850 fprintf (dump_file, "\n\n");
851 }
852 symtab->function_flags_ready = true;
853 return 0;
854 }
855
856 /* Local function pass handling visibilities. This happens before LTO streaming
857 so in particular -fwhole-program should be ignored at this level. */
858
859 namespace {
860
861 const pass_data pass_data_ipa_function_and_variable_visibility =
862 {
863 SIMPLE_IPA_PASS, /* type */
864 "visibility", /* name */
865 OPTGROUP_NONE, /* optinfo_flags */
866 TV_CGRAPHOPT, /* tv_id */
867 0, /* properties_required */
868 0, /* properties_provided */
869 0, /* properties_destroyed */
870 0, /* todo_flags_start */
871 ( TODO_remove_functions | TODO_dump_symtab ), /* todo_flags_finish */
872 };
873
874 /* Bring functions local at LTO time with -fwhole-program. */
875
876 static unsigned int
whole_program_function_and_variable_visibility(void)877 whole_program_function_and_variable_visibility (void)
878 {
879 function_and_variable_visibility (flag_whole_program);
880 if (optimize)
881 ipa_discover_readonly_nonaddressable_vars ();
882 return 0;
883 }
884
885 } // anon namespace
886
887 namespace {
888
889 const pass_data pass_data_ipa_whole_program_visibility =
890 {
891 IPA_PASS, /* type */
892 "whole-program", /* name */
893 OPTGROUP_NONE, /* optinfo_flags */
894 TV_CGRAPHOPT, /* tv_id */
895 0, /* properties_required */
896 0, /* properties_provided */
897 0, /* properties_destroyed */
898 0, /* todo_flags_start */
899 ( TODO_remove_functions | TODO_dump_symtab ), /* todo_flags_finish */
900 };
901
902 class pass_ipa_whole_program_visibility : public ipa_opt_pass_d
903 {
904 public:
pass_ipa_whole_program_visibility(gcc::context * ctxt)905 pass_ipa_whole_program_visibility (gcc::context *ctxt)
906 : ipa_opt_pass_d (pass_data_ipa_whole_program_visibility, ctxt,
907 NULL, /* generate_summary */
908 NULL, /* write_summary */
909 NULL, /* read_summary */
910 NULL, /* write_optimization_summary */
911 NULL, /* read_optimization_summary */
912 NULL, /* stmt_fixup */
913 0, /* function_transform_todo_flags_start */
914 NULL, /* function_transform */
915 NULL) /* variable_transform */
916 {}
917
918 /* opt_pass methods: */
919
gate(function *)920 virtual bool gate (function *)
921 {
922 /* Do not re-run on ltrans stage. */
923 return !flag_ltrans;
924 }
execute(function *)925 virtual unsigned int execute (function *)
926 {
927 return whole_program_function_and_variable_visibility ();
928 }
929
930 }; // class pass_ipa_whole_program_visibility
931
932 } // anon namespace
933
934 ipa_opt_pass_d *
make_pass_ipa_whole_program_visibility(gcc::context * ctxt)935 make_pass_ipa_whole_program_visibility (gcc::context *ctxt)
936 {
937 return new pass_ipa_whole_program_visibility (ctxt);
938 }
939
940 class pass_ipa_function_and_variable_visibility : public simple_ipa_opt_pass
941 {
942 public:
pass_ipa_function_and_variable_visibility(gcc::context * ctxt)943 pass_ipa_function_and_variable_visibility (gcc::context *ctxt)
944 : simple_ipa_opt_pass (pass_data_ipa_function_and_variable_visibility,
945 ctxt)
946 {}
947
948 /* opt_pass methods: */
execute(function *)949 virtual unsigned int execute (function *)
950 {
951 return function_and_variable_visibility (flag_whole_program && !flag_lto);
952 }
953
954 }; // class pass_ipa_function_and_variable_visibility
955
956 simple_ipa_opt_pass *
make_pass_ipa_function_and_variable_visibility(gcc::context * ctxt)957 make_pass_ipa_function_and_variable_visibility (gcc::context *ctxt)
958 {
959 return new pass_ipa_function_and_variable_visibility (ctxt);
960 }
961