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