/* IPA visibility pass
   Copyright (C) 2003-2017 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"

/* 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
	      convetions.  */
	   && !node->thunk.thunk_p
	   && node->definition
	   && !DECL_EXTERNAL (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 (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)
{
#ifndef ASM_OUTPUT_DEF
  /* If aliases aren't supported, we can't do replacement.  */
  return false;
#endif
  /* 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)
{
#ifdef ASM_OUTPUT_DEF
  bool aliases_supported = true;
#else
  bool aliases_supported = false;
#endif
  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->definition && decl_binds_to_current_def_p (target->decl)
      && aliases_supported)
    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)
    {
      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 procssed at this point.  */
  gcc_checking_assert (!alias_pairs || !alias_pairs->length ());

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

      /* Optimize away PURE and CONST constructors and destructors.  */
      if (optimize
	  && (flags & (ECF_CONST | ECF_PURE))
	  && !(flags & ECF_LOOPING_CONST_OR_PURE))
	{
	  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)
    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);
}
