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