PR ipa/63566
[official-gcc.git] / gcc / ipa-visibility.c
blob00b28e6e89c02c3572004266330b2885d3f1f2b4
1 /* IPA visibility pass
2 Copyright (C) 2003-2015 Free Software Foundation, Inc.
4 This file is part of GCC.
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.
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.
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/>. */
20 /* This file implements two related passes:
22 - pass_data_ipa_function_and_variable_visibility run just after
23 symbol table, references and callgraph are built
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.
29 Purpose of both passes is to set correctly visibility properties
30 of all symbols. This includes:
32 - Symbol privatization:
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)
38 - Discovery of local functions:
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.
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.
49 - Dismantling of comdat groups:
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.
59 - Local aliases:
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.
68 TODO: This should be done for references, too.
70 - Removal of static ocnstructors and destructors that have no side effects.
72 - Regularization of several oddities introduced by frontends that may
73 be impractical later in the optimization queue. */
75 #include "config.h"
76 #include "system.h"
77 #include "coretypes.h"
78 #include "tm.h"
79 #include "hash-set.h"
80 #include "machmode.h"
81 #include "vec.h"
82 #include "double-int.h"
83 #include "input.h"
84 #include "alias.h"
85 #include "symtab.h"
86 #include "wide-int.h"
87 #include "inchash.h"
88 #include "tree.h"
89 #include "hash-map.h"
90 #include "is-a.h"
91 #include "plugin-api.h"
92 #include "hard-reg-set.h"
93 #include "input.h"
94 #include "function.h"
95 #include "ipa-ref.h"
96 #include "cgraph.h"
97 #include "tree-pass.h"
98 #include "calls.h"
99 #include "gimple-expr.h"
100 #include "varasm.h"
102 /* Return true when NODE can not be local. Worker for cgraph_local_node_p. */
104 bool
105 cgraph_node::non_local_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
107 return !(node->only_called_directly_or_aliased_p ()
108 /* i386 would need update to output thunk with locak calling
109 ocnvetions. */
110 && !node->thunk.thunk_p
111 && node->definition
112 && !DECL_EXTERNAL (node->decl)
113 && !node->externally_visible
114 && !node->used_from_other_partition
115 && !node->in_other_partition);
118 /* Return true when function can be marked local. */
120 bool
121 cgraph_node::local_p (void)
123 cgraph_node *n = ultimate_alias_target ();
125 if (n->thunk.thunk_p)
126 return n->callees->callee->local_p ();
127 return !n->call_for_symbol_thunks_and_aliases (cgraph_node::non_local_p,
128 NULL, true);
132 /* Return true when there is a reference to node and it is not vtable. */
134 bool
135 symtab_node::address_taken_from_non_vtable_p (void)
137 int i;
138 struct ipa_ref *ref = NULL;
140 for (i = 0; iterate_referring (i, ref); i++)
141 if (ref->use == IPA_REF_ADDR)
143 varpool_node *node;
144 if (is_a <cgraph_node *> (ref->referring))
145 return true;
146 node = dyn_cast <varpool_node *> (ref->referring);
147 if (!DECL_VIRTUAL_P (node->decl))
148 return true;
150 return false;
153 /* A helper for comdat_can_be_unshared_p. */
155 static bool
156 comdat_can_be_unshared_p_1 (symtab_node *node)
158 if (!node->externally_visible)
159 return true;
160 /* When address is taken, we don't know if equality comparison won't
161 break eventually. Exception are virutal functions, C++
162 constructors/destructors and vtables, where this is not possible by
163 language standard. */
164 if (!DECL_VIRTUAL_P (node->decl)
165 && (TREE_CODE (node->decl) != FUNCTION_DECL
166 || (!DECL_CXX_CONSTRUCTOR_P (node->decl)
167 && !DECL_CXX_DESTRUCTOR_P (node->decl)))
168 && node->address_taken_from_non_vtable_p ())
169 return false;
171 /* If the symbol is used in some weird way, better to not touch it. */
172 if (node->force_output)
173 return false;
175 /* Explicit instantiations needs to be output when possibly
176 used externally. */
177 if (node->forced_by_abi
178 && TREE_PUBLIC (node->decl)
179 && (node->resolution != LDPR_PREVAILING_DEF_IRONLY
180 && !flag_whole_program))
181 return false;
183 /* Non-readonly and volatile variables can not be duplicated. */
184 if (is_a <varpool_node *> (node)
185 && (!TREE_READONLY (node->decl)
186 || TREE_THIS_VOLATILE (node->decl)))
187 return false;
188 return true;
191 /* COMDAT functions must be shared only if they have address taken,
192 otherwise we can produce our own private implementation with
193 -fwhole-program.
194 Return true when turning COMDAT functoin static can not lead to wrong
195 code when the resulting object links with a library defining same COMDAT.
197 Virtual functions do have their addresses taken from the vtables,
198 but in C++ there is no way to compare their addresses for equality. */
200 static bool
201 comdat_can_be_unshared_p (symtab_node *node)
203 if (!comdat_can_be_unshared_p_1 (node))
204 return false;
205 if (node->same_comdat_group)
207 symtab_node *next;
209 /* If more than one function is in the same COMDAT group, it must
210 be shared even if just one function in the comdat group has
211 address taken. */
212 for (next = node->same_comdat_group;
213 next != node; next = next->same_comdat_group)
214 if (!comdat_can_be_unshared_p_1 (next))
215 return false;
217 return true;
220 /* Return true when function NODE should be considered externally visible. */
222 static bool
223 cgraph_externally_visible_p (struct cgraph_node *node,
224 bool whole_program)
226 if (!node->definition)
227 return false;
228 if (!TREE_PUBLIC (node->decl)
229 || DECL_EXTERNAL (node->decl))
230 return false;
232 /* Do not try to localize built-in functions yet. One of problems is that we
233 end up mangling their asm for WHOPR that makes it impossible to call them
234 using the implicit built-in declarations anymore. Similarly this enables
235 us to remove them as unreachable before actual calls may appear during
236 expansion or folding. */
237 if (DECL_BUILT_IN (node->decl))
238 return true;
240 /* If linker counts on us, we must preserve the function. */
241 if (node->used_from_object_file_p ())
242 return true;
243 if (DECL_PRESERVE_P (node->decl))
244 return true;
245 if (lookup_attribute ("externally_visible",
246 DECL_ATTRIBUTES (node->decl)))
247 return true;
248 if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
249 && lookup_attribute ("dllexport",
250 DECL_ATTRIBUTES (node->decl)))
251 return true;
252 if (node->resolution == LDPR_PREVAILING_DEF_IRONLY)
253 return false;
254 /* When doing LTO or whole program, we can bring COMDAT functoins static.
255 This improves code quality and we know we will duplicate them at most twice
256 (in the case that we are not using plugin and link with object file
257 implementing same COMDAT) */
258 if ((in_lto_p || whole_program)
259 && DECL_COMDAT (node->decl)
260 && comdat_can_be_unshared_p (node))
261 return false;
263 /* When doing link time optimizations, hidden symbols become local. */
264 if (in_lto_p
265 && (DECL_VISIBILITY (node->decl) == VISIBILITY_HIDDEN
266 || DECL_VISIBILITY (node->decl) == VISIBILITY_INTERNAL)
267 /* Be sure that node is defined in IR file, not in other object
268 file. In that case we don't set used_from_other_object_file. */
269 && node->definition)
271 else if (!whole_program)
272 return true;
274 if (MAIN_NAME_P (DECL_NAME (node->decl)))
275 return true;
277 if (node->instrumentation_clone
278 && MAIN_NAME_P (DECL_NAME (node->orig_decl)))
279 return true;
281 return false;
284 /* Return true when variable should be considered externally visible. */
286 bool
287 varpool_node::externally_visible_p (void)
289 if (DECL_EXTERNAL (decl))
290 return true;
292 if (!TREE_PUBLIC (decl))
293 return false;
295 /* If linker counts on us, we must preserve the function. */
296 if (used_from_object_file_p ())
297 return true;
299 /* Bringing TLS variables local may cause dynamic linker failures
300 on limits of static TLS vars. */
301 if (DECL_THREAD_LOCAL_P (decl)
302 && (DECL_TLS_MODEL (decl) != TLS_MODEL_EMULATED
303 && DECL_TLS_MODEL (decl) != TLS_MODEL_INITIAL_EXEC))
304 return true;
306 if (DECL_HARD_REGISTER (decl))
307 return true;
308 if (DECL_PRESERVE_P (decl))
309 return true;
310 if (lookup_attribute ("externally_visible",
311 DECL_ATTRIBUTES (decl)))
312 return true;
313 if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
314 && lookup_attribute ("dllexport",
315 DECL_ATTRIBUTES (decl)))
316 return true;
318 /* See if we have linker information about symbol not being used or
319 if we need to make guess based on the declaration.
321 Even if the linker clams the symbol is unused, never bring internal
322 symbols that are declared by user as used or externally visible.
323 This is needed for i.e. references from asm statements. */
324 if (used_from_object_file_p ())
325 return true;
326 if (resolution == LDPR_PREVAILING_DEF_IRONLY)
327 return false;
329 /* As a special case, the COMDAT virtual tables can be unshared.
330 In LTO mode turn vtables into static variables. The variable is readonly,
331 so this does not enable more optimization, but referring static var
332 is faster for dynamic linking. Also this match logic hidding vtables
333 from LTO symbol tables. */
334 if ((in_lto_p || flag_whole_program)
335 && DECL_COMDAT (decl)
336 && comdat_can_be_unshared_p (this))
337 return false;
339 /* When doing link time optimizations, hidden symbols become local. */
340 if (in_lto_p
341 && (DECL_VISIBILITY (decl) == VISIBILITY_HIDDEN
342 || DECL_VISIBILITY (decl) == VISIBILITY_INTERNAL)
343 /* Be sure that node is defined in IR file, not in other object
344 file. In that case we don't set used_from_other_object_file. */
345 && definition)
347 else if (!flag_whole_program)
348 return true;
350 /* Do not attempt to privatize COMDATS by default.
351 This would break linking with C++ libraries sharing
352 inline definitions.
354 FIXME: We can do so for readonly vars with no address taken and
355 possibly also for vtables since no direct pointer comparsion is done.
356 It might be interesting to do so to reduce linking overhead. */
357 if (DECL_COMDAT (decl) || DECL_WEAK (decl))
358 return true;
359 return false;
362 /* Return true if reference to NODE can be replaced by a local alias.
363 Local aliases save dynamic linking overhead and enable more optimizations.
366 bool
367 can_replace_by_local_alias (symtab_node *node)
369 return (node->get_availability () > AVAIL_INTERPOSABLE
370 && !decl_binds_to_current_def_p (node->decl)
371 && !node->can_be_discarded_p ());
374 /* Return true if we can replace refernece to NODE by local alias
375 within a virtual table. Generally we can replace function pointers
376 and virtual table pointers. */
378 bool
379 can_replace_by_local_alias_in_vtable (symtab_node *node)
381 if (is_a <varpool_node *> (node)
382 && !DECL_VIRTUAL_P (node->decl))
383 return false;
384 return can_replace_by_local_alias (node);
387 /* walk_tree callback that rewrites initializer references. */
389 static tree
390 update_vtable_references (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
392 if (TREE_CODE (*tp) == VAR_DECL
393 || TREE_CODE (*tp) == FUNCTION_DECL)
395 if (can_replace_by_local_alias_in_vtable (symtab_node::get (*tp)))
396 *tp = symtab_node::get (*tp)->noninterposable_alias ()->decl;
397 *walk_subtrees = 0;
399 else if (IS_TYPE_OR_DECL_P (*tp))
400 *walk_subtrees = 0;
401 return NULL;
404 /* In LTO we can remove COMDAT groups and weak symbols.
405 Either turn them into normal symbols or external symbol depending on
406 resolution info. */
408 static void
409 update_visibility_by_resolution_info (symtab_node * node)
411 bool define;
413 if (!node->externally_visible
414 || (!DECL_WEAK (node->decl) && !DECL_ONE_ONLY (node->decl))
415 || node->resolution == LDPR_UNKNOWN)
416 return;
418 define = (node->resolution == LDPR_PREVAILING_DEF_IRONLY
419 || node->resolution == LDPR_PREVAILING_DEF
420 || node->resolution == LDPR_UNDEF
421 || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP);
423 /* The linker decisions ought to agree in the whole group. */
424 if (node->same_comdat_group)
425 for (symtab_node *next = node->same_comdat_group;
426 next != node; next = next->same_comdat_group)
427 gcc_assert (!next->externally_visible
428 || define == (next->resolution == LDPR_PREVAILING_DEF_IRONLY
429 || next->resolution == LDPR_PREVAILING_DEF
430 || next->resolution == LDPR_UNDEF
431 || next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP));
433 if (node->same_comdat_group)
434 for (symtab_node *next = node->same_comdat_group;
435 next != node; next = next->same_comdat_group)
437 next->set_comdat_group (NULL);
438 DECL_WEAK (next->decl) = false;
439 if (next->externally_visible
440 && !define)
441 DECL_EXTERNAL (next->decl) = true;
443 node->set_comdat_group (NULL);
444 DECL_WEAK (node->decl) = false;
445 if (!define)
446 DECL_EXTERNAL (node->decl) = true;
447 node->dissolve_same_comdat_group_list ();
450 /* Decide on visibility of all symbols. */
452 static unsigned int
453 function_and_variable_visibility (bool whole_program)
455 struct cgraph_node *node;
456 varpool_node *vnode;
458 /* All aliases should be procssed at this point. */
459 gcc_checking_assert (!alias_pairs || !alias_pairs->length ());
461 FOR_EACH_FUNCTION (node)
463 int flags = flags_from_decl_or_type (node->decl);
465 /* Optimize away PURE and CONST constructors and destructors. */
466 if (optimize
467 && (flags & (ECF_CONST | ECF_PURE))
468 && !(flags & ECF_LOOPING_CONST_OR_PURE))
470 DECL_STATIC_CONSTRUCTOR (node->decl) = 0;
471 DECL_STATIC_DESTRUCTOR (node->decl) = 0;
474 /* Frontends and alias code marks nodes as needed before parsing is finished.
475 We may end up marking as node external nodes where this flag is meaningless
476 strip it. */
477 if (DECL_EXTERNAL (node->decl) || !node->definition)
479 node->force_output = 0;
480 node->forced_by_abi = 0;
483 /* C++ FE on lack of COMDAT support create local COMDAT functions
484 (that ought to be shared but can not due to object format
485 limitations). It is necessary to keep the flag to make rest of C++ FE
486 happy. Clear the flag here to avoid confusion in middle-end. */
487 if (DECL_COMDAT (node->decl) && !TREE_PUBLIC (node->decl))
488 DECL_COMDAT (node->decl) = 0;
490 /* For external decls stop tracking same_comdat_group. It doesn't matter
491 what comdat group they are in when they won't be emitted in this TU. */
492 if (node->same_comdat_group && DECL_EXTERNAL (node->decl))
494 #ifdef ENABLE_CHECKING
495 symtab_node *n;
497 for (n = node->same_comdat_group;
498 n != node;
499 n = n->same_comdat_group)
500 /* If at least one of same comdat group functions is external,
501 all of them have to be, otherwise it is a front-end bug. */
502 gcc_assert (DECL_EXTERNAL (n->decl));
503 #endif
504 node->dissolve_same_comdat_group_list ();
506 gcc_assert ((!DECL_WEAK (node->decl)
507 && !DECL_COMDAT (node->decl))
508 || TREE_PUBLIC (node->decl)
509 || node->weakref
510 || DECL_EXTERNAL (node->decl));
511 if (cgraph_externally_visible_p (node, whole_program))
513 gcc_assert (!node->global.inlined_to);
514 node->externally_visible = true;
516 else
518 node->externally_visible = false;
519 node->forced_by_abi = false;
521 if (!node->externally_visible
522 && node->definition && !node->weakref
523 && !DECL_EXTERNAL (node->decl))
525 gcc_assert (whole_program || in_lto_p
526 || !TREE_PUBLIC (node->decl));
527 node->unique_name = ((node->resolution == LDPR_PREVAILING_DEF_IRONLY
528 || node->unique_name
529 || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
530 && TREE_PUBLIC (node->decl));
531 node->resolution = LDPR_PREVAILING_DEF_IRONLY;
532 if (node->same_comdat_group && TREE_PUBLIC (node->decl))
534 symtab_node *next = node;
536 /* Set all members of comdat group local. */
537 if (node->same_comdat_group)
538 for (next = node->same_comdat_group;
539 next != node;
540 next = next->same_comdat_group)
542 next->set_comdat_group (NULL);
543 if (!next->alias)
544 next->set_section (NULL);
545 next->make_decl_local ();
546 next->unique_name = ((next->resolution == LDPR_PREVAILING_DEF_IRONLY
547 || next->unique_name
548 || next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
549 && TREE_PUBLIC (next->decl));
551 /* cgraph_externally_visible_p has already checked all other nodes
552 in the group and they will all be made local. We need to
553 dissolve the group at once so that the predicate does not
554 segfault though. */
555 node->dissolve_same_comdat_group_list ();
557 if (TREE_PUBLIC (node->decl))
558 node->set_comdat_group (NULL);
559 if (DECL_COMDAT (node->decl) && !node->alias)
560 node->set_section (NULL);
561 node->make_decl_local ();
564 if (node->thunk.thunk_p
565 && !node->thunk.add_pointer_bounds_args
566 && TREE_PUBLIC (node->decl))
568 struct cgraph_node *decl_node = node;
570 decl_node = decl_node->callees->callee->function_symbol ();
572 /* Thunks have the same visibility as function they are attached to.
573 Make sure the C++ front end set this up properly. */
574 if (DECL_ONE_ONLY (decl_node->decl))
576 gcc_checking_assert (DECL_COMDAT (node->decl)
577 == DECL_COMDAT (decl_node->decl));
578 gcc_checking_assert (node->in_same_comdat_group_p (decl_node));
579 gcc_checking_assert (node->same_comdat_group);
581 node->forced_by_abi = decl_node->forced_by_abi;
582 if (DECL_EXTERNAL (decl_node->decl))
583 DECL_EXTERNAL (node->decl) = 1;
586 update_visibility_by_resolution_info (node);
588 FOR_EACH_DEFINED_FUNCTION (node)
590 node->local.local |= node->local_p ();
592 /* If we know that function can not be overwritten by a different semantics
593 and moreover its section can not be discarded, replace all direct calls
594 by calls to an noninterposable alias. This make dynamic linking
595 cheaper and enable more optimization.
597 TODO: We can also update virtual tables. */
598 if (node->callers
599 && can_replace_by_local_alias (node))
601 cgraph_node *alias = dyn_cast<cgraph_node *>
602 (node->noninterposable_alias ());
604 if (alias && alias != node)
606 while (node->callers)
608 struct cgraph_edge *e = node->callers;
610 e->redirect_callee (alias);
611 if (gimple_has_body_p (e->caller->decl))
613 push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
614 e->redirect_call_stmt_to_callee ();
615 pop_cfun ();
621 FOR_EACH_VARIABLE (vnode)
623 /* weak flag makes no sense on local variables. */
624 gcc_assert (!DECL_WEAK (vnode->decl)
625 || vnode->weakref
626 || TREE_PUBLIC (vnode->decl)
627 || DECL_EXTERNAL (vnode->decl));
628 /* In several cases declarations can not be common:
630 - when declaration has initializer
631 - when it is in weak
632 - when it has specific section
633 - when it resides in non-generic address space.
634 - if declaration is local, it will get into .local common section
635 so common flag is not needed. Frontends still produce these in
636 certain cases, such as for:
638 static int a __attribute__ ((common))
640 Canonicalize things here and clear the redundant flag. */
641 if (DECL_COMMON (vnode->decl)
642 && (!(TREE_PUBLIC (vnode->decl)
643 || DECL_EXTERNAL (vnode->decl))
644 || (DECL_INITIAL (vnode->decl)
645 && DECL_INITIAL (vnode->decl) != error_mark_node)
646 || DECL_WEAK (vnode->decl)
647 || DECL_SECTION_NAME (vnode->decl) != NULL
648 || ! (ADDR_SPACE_GENERIC_P
649 (TYPE_ADDR_SPACE (TREE_TYPE (vnode->decl))))))
650 DECL_COMMON (vnode->decl) = 0;
652 FOR_EACH_DEFINED_VARIABLE (vnode)
654 if (!vnode->definition)
655 continue;
656 if (vnode->externally_visible_p ())
657 vnode->externally_visible = true;
658 else
660 vnode->externally_visible = false;
661 vnode->forced_by_abi = false;
663 if (lookup_attribute ("no_reorder",
664 DECL_ATTRIBUTES (vnode->decl)))
665 vnode->no_reorder = 1;
666 if (!vnode->externally_visible
667 && !vnode->weakref)
669 gcc_assert (in_lto_p || whole_program || !TREE_PUBLIC (vnode->decl));
670 vnode->unique_name = ((vnode->resolution == LDPR_PREVAILING_DEF_IRONLY
671 || vnode->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
672 && TREE_PUBLIC (vnode->decl));
673 if (vnode->same_comdat_group && TREE_PUBLIC (vnode->decl))
675 symtab_node *next = vnode;
677 /* Set all members of comdat group local. */
678 if (vnode->same_comdat_group)
679 for (next = vnode->same_comdat_group;
680 next != vnode;
681 next = next->same_comdat_group)
683 next->set_comdat_group (NULL);
684 if (!next->alias)
685 next->set_section (NULL);
686 next->make_decl_local ();
687 next->unique_name = ((next->resolution == LDPR_PREVAILING_DEF_IRONLY
688 || next->unique_name
689 || next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
690 && TREE_PUBLIC (next->decl));
692 vnode->dissolve_same_comdat_group_list ();
694 if (TREE_PUBLIC (vnode->decl))
695 vnode->set_comdat_group (NULL);
696 if (DECL_COMDAT (vnode->decl) && !vnode->alias)
697 vnode->set_section (NULL);
698 vnode->make_decl_local ();
699 vnode->resolution = LDPR_PREVAILING_DEF_IRONLY;
701 update_visibility_by_resolution_info (vnode);
703 /* Update virtual tables to point to local aliases where possible. */
704 if (DECL_VIRTUAL_P (vnode->decl)
705 && !DECL_EXTERNAL (vnode->decl))
707 int i;
708 struct ipa_ref *ref;
709 bool found = false;
711 /* See if there is something to update. */
712 for (i = 0; vnode->iterate_referring (i, ref); i++)
713 if (ref->use == IPA_REF_ADDR
714 && can_replace_by_local_alias_in_vtable (ref->referred))
716 found = true;
717 break;
719 if (found)
721 hash_set<tree> visited_nodes;
723 vnode->get_constructor ();
724 walk_tree (&DECL_INITIAL (vnode->decl),
725 update_vtable_references, NULL, &visited_nodes);
726 vnode->remove_all_references ();
727 record_references_in_initializer (vnode->decl, false);
732 if (dump_file)
734 fprintf (dump_file, "\nMarking local functions:");
735 FOR_EACH_DEFINED_FUNCTION (node)
736 if (node->local.local)
737 fprintf (dump_file, " %s", node->name ());
738 fprintf (dump_file, "\n\n");
739 fprintf (dump_file, "\nMarking externally visible functions:");
740 FOR_EACH_DEFINED_FUNCTION (node)
741 if (node->externally_visible)
742 fprintf (dump_file, " %s", node->name ());
743 fprintf (dump_file, "\n\n");
744 fprintf (dump_file, "\nMarking externally visible variables:");
745 FOR_EACH_DEFINED_VARIABLE (vnode)
746 if (vnode->externally_visible)
747 fprintf (dump_file, " %s", vnode->name ());
748 fprintf (dump_file, "\n\n");
750 symtab->function_flags_ready = true;
751 return 0;
754 /* Local function pass handling visibilities. This happens before LTO streaming
755 so in particular -fwhole-program should be ignored at this level. */
757 namespace {
759 const pass_data pass_data_ipa_function_and_variable_visibility =
761 SIMPLE_IPA_PASS, /* type */
762 "visibility", /* name */
763 OPTGROUP_NONE, /* optinfo_flags */
764 TV_CGRAPHOPT, /* tv_id */
765 0, /* properties_required */
766 0, /* properties_provided */
767 0, /* properties_destroyed */
768 0, /* todo_flags_start */
769 ( TODO_remove_functions | TODO_dump_symtab ), /* todo_flags_finish */
772 /* Bring functions local at LTO time with -fwhole-program. */
774 static unsigned int
775 whole_program_function_and_variable_visibility (void)
777 function_and_variable_visibility (flag_whole_program);
778 if (optimize)
779 ipa_discover_readonly_nonaddressable_vars ();
780 return 0;
783 } // anon namespace
785 namespace {
787 const pass_data pass_data_ipa_whole_program_visibility =
789 IPA_PASS, /* type */
790 "whole-program", /* name */
791 OPTGROUP_NONE, /* optinfo_flags */
792 TV_CGRAPHOPT, /* tv_id */
793 0, /* properties_required */
794 0, /* properties_provided */
795 0, /* properties_destroyed */
796 0, /* todo_flags_start */
797 ( TODO_remove_functions | TODO_dump_symtab ), /* todo_flags_finish */
800 class pass_ipa_whole_program_visibility : public ipa_opt_pass_d
802 public:
803 pass_ipa_whole_program_visibility (gcc::context *ctxt)
804 : ipa_opt_pass_d (pass_data_ipa_whole_program_visibility, ctxt,
805 NULL, /* generate_summary */
806 NULL, /* write_summary */
807 NULL, /* read_summary */
808 NULL, /* write_optimization_summary */
809 NULL, /* read_optimization_summary */
810 NULL, /* stmt_fixup */
811 0, /* function_transform_todo_flags_start */
812 NULL, /* function_transform */
813 NULL) /* variable_transform */
816 /* opt_pass methods: */
818 virtual bool gate (function *)
820 /* Do not re-run on ltrans stage. */
821 return !flag_ltrans;
823 virtual unsigned int execute (function *)
825 return whole_program_function_and_variable_visibility ();
828 }; // class pass_ipa_whole_program_visibility
830 } // anon namespace
832 ipa_opt_pass_d *
833 make_pass_ipa_whole_program_visibility (gcc::context *ctxt)
835 return new pass_ipa_whole_program_visibility (ctxt);
838 class pass_ipa_function_and_variable_visibility : public simple_ipa_opt_pass
840 public:
841 pass_ipa_function_and_variable_visibility (gcc::context *ctxt)
842 : simple_ipa_opt_pass (pass_data_ipa_function_and_variable_visibility,
843 ctxt)
846 /* opt_pass methods: */
847 virtual unsigned int execute (function *)
849 return function_and_variable_visibility (flag_whole_program && !flag_lto);
852 }; // class pass_ipa_function_and_variable_visibility
854 simple_ipa_opt_pass *
855 make_pass_ipa_function_and_variable_visibility (gcc::context *ctxt)
857 return new pass_ipa_function_and_variable_visibility (ctxt);