/* IPA visibility pass
   Copyright (C) 2003-2018 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

/* This file implements two related passes: 

     - pass_data_ipa_function_and_variable_visibility run just after
       symbol table, references and callgraph are built

     - pass_data_ipa_function_and_variable_visibility run as first
       proper IPA pass (that is after early optimization, or, (with LTO)
       as a first pass done at link-time.

   Purpose of both passes is to set correctly visibility properties
   of all symbols.  This includes:

    - Symbol privatization:

      Some symbols that are declared public by frontend may be
      turned local (either by -fwhole-program flag, by linker plugin feedback
      or by other reasons)

    - Discovery of local functions:

      A local function is one whose calls can occur only in the current
      compilation unit and all its calls are explicit, so we can change
      its calling convention.  We simply mark all static functions whose
      address is not taken as local.

      externally_visible flag is set for symbols that can not be privatized.
      For privatized symbols we clear TREE_PUBLIC flag and dismantle comdat
      group.

    - Dismantling of comdat groups:

      Comdat group represent a section that may be replaced by linker by
      a different copy of the same section from other unit.
      If we have resolution information (from linker plugin) and we know that
      a given comdat gorup is prevailing, we can dismantle it and turn symbols
      into normal symbols.  If the resolution information says that the
      section was previaled by copy from non-LTO code, we can also dismantle
      it and turn all symbols into external.

    - Local aliases:

      Some symbols can be interposed by dynamic linker. Refering to these
      symbols is expensive, since it needs to be overwritable by the dynamic
      linker.  In some cases we know that the interposition does not change
      semantic and we can always refer to a local copy (as in the case of
      inline function).  In this case we produce a local alias and redirect
      calls to it.

      TODO: This should be done for references, too.

    - Removal of static ocnstructors and destructors that have no side effects.

    - Regularization of several oddities introduced by frontends that may
      be impractical later in the optimization queue.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "function.h"
#include "tree.h"
#include "gimple-expr.h"
#include "tree-pass.h"
#include "cgraph.h"
#include "calls.h"
#include "varasm.h"
#include "ipa-utils.h"
#include "stringpool.h"
#include "attribs.h"

/* Return true when NODE can not be local. Worker for cgraph_local_node_p.  */

static bool
non_local_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
{
  return !(node->only_called_directly_or_aliased_p ()
	   /* i386 would need update to output thunk with local calling
	      conventions.  */
	   && !node->thunk.thunk_p
	   && node->definition
	   && !DECL_EXTERNAL (node->decl)
	   && !lookup_attribute ("noipa", DECL_ATTRIBUTES (node->decl))
	   && !node->externally_visible
	   && !node->used_from_other_partition
	   && !node->in_other_partition
	   && node->get_availability () >= AVAIL_AVAILABLE);
}

/* Return true when function can be marked local.  */

bool
cgraph_node::local_p (void)
{
   cgraph_node *n = ultimate_alias_target ();

   if (n->thunk.thunk_p)
     return n->callees->callee->local_p ();
   return !n->call_for_symbol_thunks_and_aliases (non_local_p,
						  NULL, true);
					
}

/* A helper for comdat_can_be_unshared_p.  */

static bool
comdat_can_be_unshared_p_1 (symtab_node *node)
{
  if (!node->externally_visible)
    return true;
  if (node->address_can_be_compared_p ())
    {
      struct ipa_ref *ref;

      for (unsigned int i = 0; node->iterate_referring (i, ref); i++)
	if (ref->address_matters_p ())
	  return false;
    }

  /* If the symbol is used in some weird way, better to not touch it.  */
  if (node->force_output)
    return false;

  /* Explicit instantiations needs to be output when possibly
     used externally.  */
  if (node->forced_by_abi
      && TREE_PUBLIC (node->decl)
      && (node->resolution != LDPR_PREVAILING_DEF_IRONLY
          && !flag_whole_program))
    return false;

  /* Non-readonly and volatile variables can not be duplicated.  */
  if (is_a <varpool_node *> (node)
      && (!TREE_READONLY (node->decl)
	  || TREE_THIS_VOLATILE (node->decl)))
    return false;
  return true;
}

/* COMDAT functions must be shared only if they have address taken,
   otherwise we can produce our own private implementation with
   -fwhole-program.  
   Return true when turning COMDAT function static can not lead to wrong
   code when the resulting object links with a library defining same COMDAT.

   Virtual functions do have their addresses taken from the vtables,
   but in C++ there is no way to compare their addresses for equality.  */

static bool
comdat_can_be_unshared_p (symtab_node *node)
{
  if (!comdat_can_be_unshared_p_1 (node))
    return false;
  if (node->same_comdat_group)
    {
      symtab_node *next;

      /* If more than one function is in the same COMDAT group, it must
         be shared even if just one function in the comdat group has
         address taken.  */
      for (next = node->same_comdat_group;
	   next != node; next = next->same_comdat_group)
        if (!comdat_can_be_unshared_p_1 (next))
          return false;
    }
  return true;
}

/* Return true when function NODE should be considered externally visible.  */

static bool
cgraph_externally_visible_p (struct cgraph_node *node,
			     bool whole_program)
{
  while (node->transparent_alias && node->definition)
    node = node->get_alias_target ();
  if (!node->definition)
    return false;
  if (!TREE_PUBLIC (node->decl)
      || DECL_EXTERNAL (node->decl))
    return false;

  /* Do not try to localize built-in functions yet.  One of problems is that we
     end up mangling their asm for WHOPR that makes it impossible to call them
     using the implicit built-in declarations anymore.  Similarly this enables
     us to remove them as unreachable before actual calls may appear during
     expansion or folding.  */
  if (DECL_BUILT_IN (node->decl))
    return true;

  /* If linker counts on us, we must preserve the function.  */
  if (node->used_from_object_file_p ())
    return true;
  if (DECL_PRESERVE_P (node->decl))
    return true;
  if (lookup_attribute ("externally_visible",
			DECL_ATTRIBUTES (node->decl)))
    return true;
  if (lookup_attribute ("noipa", DECL_ATTRIBUTES (node->decl)))
    return true;
  if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
      && lookup_attribute ("dllexport",
			   DECL_ATTRIBUTES (node->decl)))
    return true;
  if (node->resolution == LDPR_PREVAILING_DEF_IRONLY)
    return false;
  /* When doing LTO or whole program, we can bring COMDAT functoins static.
     This improves code quality and we know we will duplicate them at most twice
     (in the case that we are not using plugin and link with object file
      implementing same COMDAT)  */
  if (((in_lto_p || whole_program) && !flag_incremental_link)
      && DECL_COMDAT (node->decl)
      && comdat_can_be_unshared_p (node))
    return false;

  /* When doing link time optimizations, hidden symbols become local.  */
  if ((in_lto_p && !flag_incremental_link)
      && (DECL_VISIBILITY (node->decl) == VISIBILITY_HIDDEN
	  || DECL_VISIBILITY (node->decl) == VISIBILITY_INTERNAL)
      /* Be sure that node is defined in IR file, not in other object
	 file.  In that case we don't set used_from_other_object_file.  */
      && node->definition)
    ;
  else if (!whole_program)
    return true;

  if (MAIN_NAME_P (DECL_NAME (node->decl)))
    return true;

  if (node->instrumentation_clone
      && MAIN_NAME_P (DECL_NAME (node->orig_decl)))
    return true;

  return false;
}

/* Return true when variable should be considered externally visible.  */

bool
varpool_node::externally_visible_p (void)
{
  while (transparent_alias && definition)
    return get_alias_target ()->externally_visible_p ();
  if (DECL_EXTERNAL (decl))
    return true;

  if (!TREE_PUBLIC (decl))
    return false;

  /* If linker counts on us, we must preserve the function.  */
  if (used_from_object_file_p ())
    return true;

  /* Bringing TLS variables local may cause dynamic linker failures
     on limits of static TLS vars.  */
  if (DECL_THREAD_LOCAL_P (decl)
      && (DECL_TLS_MODEL (decl) != TLS_MODEL_EMULATED
	  && DECL_TLS_MODEL (decl) != TLS_MODEL_INITIAL_EXEC))
    return true;

  if (DECL_HARD_REGISTER (decl))
    return true;
  if (DECL_PRESERVE_P (decl))
    return true;
  if (lookup_attribute ("externally_visible",
			DECL_ATTRIBUTES (decl)))
    return true;
  if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
      && lookup_attribute ("dllexport",
			   DECL_ATTRIBUTES (decl)))
    return true;

  /* See if we have linker information about symbol not being used or
     if we need to make guess based on the declaration.

     Even if the linker clams the symbol is unused, never bring internal
     symbols that are declared by user as used or externally visible.
     This is needed for i.e. references from asm statements.   */
  if (used_from_object_file_p ())
    return true;
  if (resolution == LDPR_PREVAILING_DEF_IRONLY)
    return false;

  /* As a special case, the COMDAT virtual tables can be unshared.
     In LTO mode turn vtables into static variables.  The variable is readonly,
     so this does not enable more optimization, but referring static var
     is faster for dynamic linking.  Also this match logic hidding vtables
     from LTO symbol tables.  */
  if (((in_lto_p || flag_whole_program) && !flag_incremental_link)
      && DECL_COMDAT (decl)
      && comdat_can_be_unshared_p (this))
    return false;

  /* When doing link time optimizations, hidden symbols become local.  */
  if (in_lto_p && !flag_incremental_link
      && (DECL_VISIBILITY (decl) == VISIBILITY_HIDDEN
	  || DECL_VISIBILITY (decl) == VISIBILITY_INTERNAL)
      /* Be sure that node is defined in IR file, not in other object
	 file.  In that case we don't set used_from_other_object_file.  */
      && definition)
    ;
  else if (!flag_whole_program)
    return true;

  /* Do not attempt to privatize COMDATS by default.
     This would break linking with C++ libraries sharing
     inline definitions.

     FIXME: We can do so for readonly vars with no address taken and
     possibly also for vtables since no direct pointer comparsion is done.
     It might be interesting to do so to reduce linking overhead.  */
  if (DECL_COMDAT (decl) || DECL_WEAK (decl))
    return true;
  return false;
}

/* Return true if reference to NODE can be replaced by a local alias.
   Local aliases save dynamic linking overhead and enable more optimizations.
 */

static bool
can_replace_by_local_alias (symtab_node *node)
{
  /* If aliases aren't supported, we can't do replacement.  */
  if (!TARGET_SUPPORTS_ALIASES)
    return false;

  /* Weakrefs have a reason to be non-local.  Be sure we do not replace
     them.  */
  while (node->transparent_alias && node->definition && !node->weakref)
    node = node->get_alias_target ();
  if (node->weakref)
    return false;
  
  return (node->get_availability () > AVAIL_INTERPOSABLE
	  && !decl_binds_to_current_def_p (node->decl)
	  && !node->can_be_discarded_p ());
}

/* Return true if we can replace reference to NODE by local alias
   within a virtual table.  Generally we can replace function pointers
   and virtual table pointers.  */

static bool
can_replace_by_local_alias_in_vtable (symtab_node *node)
{
  if (is_a <varpool_node *> (node)
      && !DECL_VIRTUAL_P (node->decl))
    return false;
  return can_replace_by_local_alias (node);
}

/* walk_tree callback that rewrites initializer references.   */

static tree
update_vtable_references (tree *tp, int *walk_subtrees,
			  void *data ATTRIBUTE_UNUSED)
{
  if (VAR_OR_FUNCTION_DECL_P (*tp))
    {
      if (can_replace_by_local_alias_in_vtable (symtab_node::get (*tp)))
	*tp = symtab_node::get (*tp)->noninterposable_alias ()->decl;
      *walk_subtrees = 0;
    }
  else if (IS_TYPE_OR_DECL_P (*tp))
    *walk_subtrees = 0;
  return NULL;
}

/* In LTO we can remove COMDAT groups and weak symbols.
   Either turn them into normal symbols or external symbol depending on 
   resolution info.  */

static void
update_visibility_by_resolution_info (symtab_node * node)
{
  bool define;

  if (!node->externally_visible
      || (!DECL_WEAK (node->decl) && !DECL_ONE_ONLY (node->decl))
      || node->resolution == LDPR_UNKNOWN)
    return;

  define = (node->resolution == LDPR_PREVAILING_DEF_IRONLY
	    || node->resolution == LDPR_PREVAILING_DEF
	    || node->resolution == LDPR_UNDEF
	    || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP);

  /* The linker decisions ought to agree in the whole group.  */
  if (node->same_comdat_group)
    for (symtab_node *next = node->same_comdat_group;
	 next != node; next = next->same_comdat_group)
      {
	if (!next->externally_visible || next->transparent_alias)
	  continue;

	bool same_def
	  = define == (next->resolution == LDPR_PREVAILING_DEF_IRONLY
		       || next->resolution == LDPR_PREVAILING_DEF
		       || next->resolution == LDPR_UNDEF
		       || next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP);
	gcc_assert (in_lto_p || same_def);
	if (!same_def)
	  return;
      }

  if (node->same_comdat_group)
    for (symtab_node *next = node->same_comdat_group;
	 next != node; next = next->same_comdat_group)
      {
	/* During incremental linking we need to keep symbol weak for future
	   linking.  We can still drop definition if we know non-LTO world
	   prevails.  */
	if (!flag_incremental_link)
	  {
	    DECL_WEAK (next->decl) = false;
	    next->set_comdat_group (NULL);
	  }
	if (!define)
	  {
	    if (next->externally_visible)
	      DECL_EXTERNAL (next->decl) = true;
	    next->set_comdat_group (NULL);
	  }
      }

  /* During incremental linking we need to keep symbol weak for future
     linking.  We can still drop definition if we know non-LTO world prevails.  */
  if (!flag_incremental_link)
    {
      DECL_WEAK (node->decl) = false;
      node->set_comdat_group (NULL);
      node->dissolve_same_comdat_group_list ();
    }
  if (!define)
    {
      DECL_EXTERNAL (node->decl) = true;
      node->set_comdat_group (NULL);
      node->dissolve_same_comdat_group_list ();
    }
}

/* Try to get rid of weakref.  */

static void
optimize_weakref (symtab_node *node)
{
  bool strip_weakref = false;
  bool static_alias = false;

  gcc_assert (node->weakref);

  /* Weakrefs with no target defined can not be optimized.  */
  if (!node->analyzed)
    return;
  symtab_node *target = node->get_alias_target ();

  /* Weakrefs to weakrefs can be optimized only if target can be.  */
  if (target->weakref)
    optimize_weakref (target);
  if (target->weakref)
    return;

  /* If we have definition of weakref's target and we know it binds locally,
     we can turn weakref to static alias.  */
  if (TARGET_SUPPORTS_ALIASES
      && target->definition && decl_binds_to_current_def_p (target->decl))
    strip_weakref = static_alias = true;
  /* Otherwise we can turn weakref into transparent alias.  This transformation
     may break asm statements which directly refers to symbol name and expect
     GNU as to translate it via .weakref directive. So do not optimize when
     DECL_PRESERVED is set and .weakref is supported.  */
  else if ((!DECL_PRESERVE_P (target->decl)
	    || IDENTIFIER_TRANSPARENT_ALIAS (DECL_ASSEMBLER_NAME (node->decl)))
	   && !DECL_WEAK (target->decl)
	   && !DECL_EXTERNAL (target->decl)
	   && ((target->definition && !target->can_be_discarded_p ())
	       || target->resolution != LDPR_UNDEF))
    strip_weakref = true;
  if (!strip_weakref)
    return;
  node->weakref = false;
  IDENTIFIER_TRANSPARENT_ALIAS (DECL_ASSEMBLER_NAME (node->decl)) = 0;
  TREE_CHAIN (DECL_ASSEMBLER_NAME (node->decl)) = NULL_TREE;
  DECL_ATTRIBUTES (node->decl) = remove_attribute ("weakref",
					           DECL_ATTRIBUTES
							 (node->decl));

  if (dump_file)
    fprintf (dump_file, "Optimizing weakref %s %s\n",
	     node->name(),
	     static_alias ? "as static alias" : "as transparent alias");

  if (static_alias)
    {
      /* make_decl_local will shortcircuit if it doesn't see TREE_PUBLIC.
	 be sure it really clears the WEAK flag.  */
      TREE_PUBLIC (node->decl) = true;
      node->make_decl_local ();
      node->forced_by_abi = false;
      node->resolution = LDPR_PREVAILING_DEF_IRONLY;
      node->externally_visible = false;
      gcc_assert (!DECL_WEAK (node->decl));
      node->transparent_alias = false;
    }
  else
    {
      symtab->change_decl_assembler_name
        (node->decl, DECL_ASSEMBLER_NAME (node->get_alias_target ()->decl));
      node->transparent_alias = true;
      node->copy_visibility_from (target);
    }
  gcc_assert (node->alias);
}

/* NODE is an externally visible definition, which we've discovered is
   not needed externally.  Make it local to this compilation.  */

static void
localize_node (bool whole_program, symtab_node *node)
{
  gcc_assert (whole_program || in_lto_p || !TREE_PUBLIC (node->decl));

  /* It is possible that one comdat group contains both hidden and non-hidden
     symbols.  In this case we can privatize all hidden symbol but we need
     to keep non-hidden exported.  */
  if (node->same_comdat_group
      && (node->resolution == LDPR_PREVAILING_DEF_IRONLY
	  || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP))
    {
      symtab_node *next;
      for (next = node->same_comdat_group;
	   next != node; next = next->same_comdat_group)
	if (next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP
	    || next->resolution == LDPR_PREVAILING_DEF)
	  break;
      if (node != next)
	{
	  if (!node->transparent_alias)
	    {
	      node->resolution = LDPR_PREVAILING_DEF_IRONLY;
	      node->make_decl_local ();
	      if (!flag_incremental_link)
	        node->unique_name |= true;
	      return;
	    }
	}
    }
  /* For similar reason do not privatize whole comdat when seeing comdat
     local.  Wait for non-comdat symbol to be privatized first.  */
  if (node->comdat_local_p ())
    return;

  if (node->same_comdat_group && TREE_PUBLIC (node->decl))
    {
      for (symtab_node *next = node->same_comdat_group;
	   next != node; next = next->same_comdat_group)
	{
	  next->set_comdat_group (NULL);
	  if (!next->alias)
	    next->set_section (NULL);
	  if (!next->transparent_alias)
	    next->make_decl_local ();
	  next->unique_name
	    |= ((next->resolution == LDPR_PREVAILING_DEF_IRONLY
		 || next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
		&& TREE_PUBLIC (next->decl)
		&& !flag_incremental_link);
	}

      /* Now everything's localized, the grouping has no meaning, and
	 will cause crashes if we keep it around.  */
      node->dissolve_same_comdat_group_list ();
    }

  node->unique_name
    |= ((node->resolution == LDPR_PREVAILING_DEF_IRONLY
	 || node->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
	&& TREE_PUBLIC (node->decl)
	&& !flag_incremental_link);

  if (TREE_PUBLIC (node->decl))
    node->set_comdat_group (NULL);
  if (DECL_COMDAT (node->decl) && !node->alias)
    node->set_section (NULL);
  if (!node->transparent_alias)
    {
      node->resolution = LDPR_PREVAILING_DEF_IRONLY;
      node->make_decl_local ();
    }
}

/* Decide on visibility of all symbols.  */

static unsigned int
function_and_variable_visibility (bool whole_program)
{
  struct cgraph_node *node;
  varpool_node *vnode;

  /* All aliases should be processed at this point.  */
  gcc_checking_assert (!alias_pairs || !alias_pairs->length ());

#ifdef ASM_OUTPUT_DEF
  FOR_EACH_DEFINED_FUNCTION (node)
    {
      if (node->get_availability () != AVAIL_INTERPOSABLE
	  || DECL_EXTERNAL (node->decl)
	  || node->has_aliases_p ()
	  || lookup_attribute ("noipa", DECL_ATTRIBUTES (node->decl)))
	continue;

      cgraph_node *alias = 0;
      for (cgraph_edge *e = node->callees; e; e = e->next_callee)
	{
	  /* Recursive function calls usually can't be interposed.  */

	  if (!e->recursive_p ())
	    continue;

	  if (!alias)
	    {
	      alias = dyn_cast<cgraph_node *> (node->noninterposable_alias ());
	      gcc_assert (alias && alias != node);
	    }

	  e->redirect_callee (alias);
	  if (gimple_has_body_p (e->caller->decl))
	    {
	      push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
	      e->redirect_call_stmt_to_callee ();
	      pop_cfun ();
	    }
	}
    }
#endif

  FOR_EACH_FUNCTION (node)
    {
      int flags = flags_from_decl_or_type (node->decl);

      /* Optimize away PURE and CONST constructors and destructors.  */
      if (node->analyzed
	  && (DECL_STATIC_CONSTRUCTOR (node->decl)
	      || DECL_STATIC_DESTRUCTOR (node->decl))
	  && (flags & (ECF_CONST | ECF_PURE))
	  && !(flags & ECF_LOOPING_CONST_OR_PURE)
	  && opt_for_fn (node->decl, optimize))
	{
	  DECL_STATIC_CONSTRUCTOR (node->decl) = 0;
	  DECL_STATIC_DESTRUCTOR (node->decl) = 0;
	}

      /* Frontends and alias code marks nodes as needed before parsing
	 is finished.  We may end up marking as node external nodes
	 where this flag is meaningless strip it.  */
      if (DECL_EXTERNAL (node->decl) || !node->definition)
	{
	  node->force_output = 0;
	  node->forced_by_abi = 0;
	}

      /* C++ FE on lack of COMDAT support create local COMDAT functions
	 (that ought to be shared but can not due to object format
	 limitations).  It is necessary to keep the flag to make rest of C++ FE
	 happy.  Clear the flag here to avoid confusion in middle-end.  */
      if (DECL_COMDAT (node->decl) && !TREE_PUBLIC (node->decl))
        DECL_COMDAT (node->decl) = 0;

      /* For external decls stop tracking same_comdat_group. It doesn't matter
	 what comdat group they are in when they won't be emitted in this TU.

	 An exception is LTO where we may end up with both external
	 and non-external declarations in the same comdat group in
	 the case declarations was not merged.  */
      if (node->same_comdat_group && DECL_EXTERNAL (node->decl) && !in_lto_p)
	{
	  if (flag_checking)
	    {
	      for (symtab_node *n = node->same_comdat_group;
		   n != node;
		   n = n->same_comdat_group)
		/* If at least one of same comdat group functions is external,
		   all of them have to be, otherwise it is a front-end bug.  */
		gcc_assert (DECL_EXTERNAL (n->decl));
	    }
	  node->dissolve_same_comdat_group_list ();
	}
      gcc_assert ((!DECL_WEAK (node->decl)
		  && !DECL_COMDAT (node->decl))
      	          || TREE_PUBLIC (node->decl)
		  || node->weakref
		  || DECL_EXTERNAL (node->decl));
      if (cgraph_externally_visible_p (node, whole_program))
        {
	  gcc_assert (!node->global.inlined_to);
	  node->externally_visible = true;
	}
      else
	{
	  node->externally_visible = false;
	  node->forced_by_abi = false;
	}
      if (!node->externally_visible
	  && node->definition && !node->weakref
	  && !DECL_EXTERNAL (node->decl))
	localize_node (whole_program, node);

      if (node->thunk.thunk_p
	  && !node->thunk.add_pointer_bounds_args
	  && TREE_PUBLIC (node->decl))
	{
	  struct cgraph_node *decl_node = node;

	  decl_node = decl_node->callees->callee->function_symbol ();

	  /* Thunks have the same visibility as function they are attached to.
	     Make sure the C++ front end set this up properly.  */
	  if (DECL_ONE_ONLY (decl_node->decl))
	    {
	      gcc_checking_assert (DECL_COMDAT (node->decl)
				   == DECL_COMDAT (decl_node->decl));
	      gcc_checking_assert (node->in_same_comdat_group_p (decl_node));
	      gcc_checking_assert (node->same_comdat_group);
	    }
	  node->forced_by_abi = decl_node->forced_by_abi;
	  if (DECL_EXTERNAL (decl_node->decl))
	    DECL_EXTERNAL (node->decl) = 1;
	}

      update_visibility_by_resolution_info (node);
      if (node->weakref)
	optimize_weakref (node);
    }
  FOR_EACH_DEFINED_FUNCTION (node)
    {
      if (!node->local.local)
        node->local.local |= node->local_p ();

      /* If we know that function can not be overwritten by a
	 different semantics and moreover its section can not be
	 discarded, replace all direct calls by calls to an
	 noninterposable alias.  This make dynamic linking cheaper and
	 enable more optimization.

	 TODO: We can also update virtual tables.  */
      if (node->callers 
	  && can_replace_by_local_alias (node))
	{
	  cgraph_node *alias = dyn_cast<cgraph_node *>
	    (node->noninterposable_alias ());

	  if (alias && alias != node)
	    {
	      while (node->callers)
		{
		  struct cgraph_edge *e = node->callers;

		  e->redirect_callee (alias);
		  if (gimple_has_body_p (e->caller->decl))
		    {
		      push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
		      e->redirect_call_stmt_to_callee ();
		      pop_cfun ();
		    }
		}
	    }
	}
    }
  FOR_EACH_VARIABLE (vnode)
    {
      /* weak flag makes no sense on local variables.  */
      gcc_assert (!DECL_WEAK (vnode->decl)
		  || vnode->weakref
      		  || TREE_PUBLIC (vnode->decl)
		  || DECL_EXTERNAL (vnode->decl));
      /* In several cases declarations can not be common:

	 - when declaration has initializer
	 - when it is in weak
	 - when it has specific section
	 - when it resides in non-generic address space.
	 - if declaration is local, it will get into .local common section
	   so common flag is not needed.  Frontends still produce these in
	   certain cases, such as for:

	     static int a __attribute__ ((common))

	 Canonicalize things here and clear the redundant flag.  */
      if (DECL_COMMON (vnode->decl)
	  && (!(TREE_PUBLIC (vnode->decl)
	      || DECL_EXTERNAL (vnode->decl))
	      || (DECL_INITIAL (vnode->decl)
		  && DECL_INITIAL (vnode->decl) != error_mark_node)
	      || DECL_WEAK (vnode->decl)
	      || DECL_SECTION_NAME (vnode->decl) != NULL
	      || ! (ADDR_SPACE_GENERIC_P
		    (TYPE_ADDR_SPACE (TREE_TYPE (vnode->decl))))))
	DECL_COMMON (vnode->decl) = 0;
      if (vnode->weakref)
	optimize_weakref (vnode);
    }
  FOR_EACH_DEFINED_VARIABLE (vnode)
    {
      if (!vnode->definition)
        continue;
      if (vnode->externally_visible_p ())
	vnode->externally_visible = true;
      else
	{
          vnode->externally_visible = false;
	  vnode->forced_by_abi = false;
	}
      if (lookup_attribute ("no_reorder",
			    DECL_ATTRIBUTES (vnode->decl)))
	vnode->no_reorder = 1;

      if (!vnode->externally_visible
	  && !vnode->transparent_alias
	  && !DECL_EXTERNAL (vnode->decl))
	localize_node (whole_program, vnode);

      update_visibility_by_resolution_info (vnode);

      /* Update virtual tables to point to local aliases where possible.  */
      if (DECL_VIRTUAL_P (vnode->decl)
	  && !DECL_EXTERNAL (vnode->decl))
	{
	  int i;
	  struct ipa_ref *ref;
	  bool found = false;

	  /* See if there is something to update.  */
	  for (i = 0; vnode->iterate_reference (i, ref); i++)
	    if (ref->use == IPA_REF_ADDR
		&& can_replace_by_local_alias_in_vtable (ref->referred))
	      {
	        found = true;
		break;
	      }
	  if (found)
	    {
	      hash_set<tree> visited_nodes;

	      vnode->get_constructor ();
	      walk_tree (&DECL_INITIAL (vnode->decl),
			 update_vtable_references, NULL, &visited_nodes);
	      vnode->remove_all_references ();
	      record_references_in_initializer (vnode->decl, false);
	    }
	}
    }

  if (dump_file)
    {
      fprintf (dump_file, "\nMarking local functions:");
      FOR_EACH_DEFINED_FUNCTION (node)
	if (node->local.local)
	  fprintf (dump_file, " %s", node->name ());
      fprintf (dump_file, "\n\n");
      fprintf (dump_file, "\nMarking externally visible functions:");
      FOR_EACH_DEFINED_FUNCTION (node)
	if (node->externally_visible)
	  fprintf (dump_file, " %s", node->name ());
      fprintf (dump_file, "\n\n");
      fprintf (dump_file, "\nMarking externally visible variables:");
      FOR_EACH_DEFINED_VARIABLE (vnode)
	if (vnode->externally_visible)
	  fprintf (dump_file, " %s", vnode->name ());
      fprintf (dump_file, "\n\n");
    }
  symtab->function_flags_ready = true;
  return 0;
}

/* Local function pass handling visibilities.  This happens before LTO streaming
   so in particular -fwhole-program should be ignored at this level.  */

namespace {

const pass_data pass_data_ipa_function_and_variable_visibility =
{
  SIMPLE_IPA_PASS, /* type */
  "visibility", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_CGRAPHOPT, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  ( TODO_remove_functions | TODO_dump_symtab ), /* todo_flags_finish */
};

/* Bring functions local at LTO time with -fwhole-program.  */

static unsigned int
whole_program_function_and_variable_visibility (void)
{
  function_and_variable_visibility (flag_whole_program);
  if (optimize || in_lto_p)
    ipa_discover_readonly_nonaddressable_vars ();
  return 0;
}

} // anon namespace

namespace {

const pass_data pass_data_ipa_whole_program_visibility =
{
  IPA_PASS, /* type */
  "whole-program", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_CGRAPHOPT, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  ( TODO_remove_functions | TODO_dump_symtab ), /* todo_flags_finish */
};

class pass_ipa_whole_program_visibility : public ipa_opt_pass_d
{
public:
  pass_ipa_whole_program_visibility (gcc::context *ctxt)
    : ipa_opt_pass_d (pass_data_ipa_whole_program_visibility, ctxt,
		      NULL, /* generate_summary */
		      NULL, /* write_summary */
		      NULL, /* read_summary */
		      NULL, /* write_optimization_summary */
		      NULL, /* read_optimization_summary */
		      NULL, /* stmt_fixup */
		      0, /* function_transform_todo_flags_start */
		      NULL, /* function_transform */
		      NULL) /* variable_transform */
  {}

  /* opt_pass methods: */

  virtual bool gate (function *)
    {
      /* Do not re-run on ltrans stage.  */
      return !flag_ltrans;
    }
  virtual unsigned int execute (function *)
    {
      return whole_program_function_and_variable_visibility ();
    }

}; // class pass_ipa_whole_program_visibility

} // anon namespace

ipa_opt_pass_d *
make_pass_ipa_whole_program_visibility (gcc::context *ctxt)
{
  return new pass_ipa_whole_program_visibility (ctxt);
}

class pass_ipa_function_and_variable_visibility : public simple_ipa_opt_pass
{
public:
  pass_ipa_function_and_variable_visibility (gcc::context *ctxt)
    : simple_ipa_opt_pass (pass_data_ipa_function_and_variable_visibility,
			   ctxt)
  {}

  /* opt_pass methods: */
  virtual unsigned int execute (function *)
    {
      return function_and_variable_visibility (flag_whole_program && !flag_lto);
    }

}; // class pass_ipa_function_and_variable_visibility

simple_ipa_opt_pass *
make_pass_ipa_function_and_variable_visibility (gcc::context *ctxt)
{
  return new pass_ipa_function_and_variable_visibility (ctxt);
}
