/* Basic IPA optimizations and utilities.
   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/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "tree.h"
#include "gimple.h"
#include "alloc-pool.h"
#include "tree-pass.h"
#include "stringpool.h"
#include "cgraph.h"
#include "gimplify.h"
#include "tree-iterator.h"
#include "ipa-utils.h"
#include "symbol-summary.h"
#include "tree-vrp.h"
#include "ipa-prop.h"
#include "ipa-fnsummary.h"
#include "dbgcnt.h"
#include "debug.h"
#include "stringpool.h"
#include "attribs.h"

/* Return true when NODE has ADDR reference.  */

static bool
has_addr_references_p (struct cgraph_node *node,
		       void *)
{
  int i;
  struct ipa_ref *ref = NULL;

  for (i = 0; node->iterate_referring (i, ref); i++)
    if (ref->use == IPA_REF_ADDR)
      return true;
  return false;
}

/* Return true when NODE can be target of an indirect call.  */

static bool
is_indirect_call_target_p (struct cgraph_node *node, void *)
{
  return node->indirect_call_target;
}

/* Look for all functions inlined to NODE and update their inlined_to pointers
   to INLINED_TO.  */

static void
update_inlined_to_pointer (struct cgraph_node *node, struct cgraph_node *inlined_to)
{
  struct cgraph_edge *e;
  for (e = node->callees; e; e = e->next_callee)
    if (e->callee->global.inlined_to)
      {
        e->callee->global.inlined_to = inlined_to;
	update_inlined_to_pointer (e->callee, inlined_to);
      }
}

/* Add symtab NODE to queue starting at FIRST.

   The queue is linked via AUX pointers and terminated by pointer to 1.
   We enqueue nodes at two occasions: when we find them reachable or when we find
   their bodies needed for further clonning.  In the second case we mark them
   by pointer to 2 after processing so they are re-queue when they become
   reachable.  */

static void
enqueue_node (symtab_node *node, symtab_node **first,
	      hash_set<symtab_node *> *reachable)
{
  /* Node is still in queue; do nothing.  */
  if (node->aux && node->aux != (void *) 2)
    return;
  /* Node was already processed as unreachable, re-enqueue
     only if it became reachable now.  */
  if (node->aux == (void *)2 && !reachable->contains (node))
    return;
  node->aux = *first;
  *first = node;
}

/* Process references.  */

static void
process_references (symtab_node *snode,
		    symtab_node **first,
		    bool before_inlining_p,
		    hash_set<symtab_node *> *reachable)
{
  int i;
  struct ipa_ref *ref = NULL;
  for (i = 0; snode->iterate_reference (i, ref); i++)
    {
      symtab_node *node = ref->referred;
      symtab_node *body = node->ultimate_alias_target ();

      if (node->definition && !node->in_other_partition
	  && ((!DECL_EXTERNAL (node->decl) || node->alias)
	      || (((before_inlining_p
		    && (TREE_CODE (node->decl) != FUNCTION_DECL
			|| (TREE_CODE (node->decl) == FUNCTION_DECL
			    && opt_for_fn (body->decl, optimize))
		        || (symtab->state < IPA_SSA
		            && lookup_attribute
				 ("always_inline",
			          DECL_ATTRIBUTES (body->decl))))))
		  /* We use variable constructors during late compilation for
		     constant folding.  Keep references alive so partitioning
		     knows about potential references.  */
		  || (VAR_P (node->decl)
		      && flag_wpa
		      && ctor_for_folding (node->decl)
		         != error_mark_node))))
	{
	  /* Be sure that we will not optimize out alias target
	     body.  */
	  if (DECL_EXTERNAL (node->decl)
	      && node->alias
	      && before_inlining_p)
	    reachable->add (body);
	  reachable->add (node);
	}
      enqueue_node (node, first, reachable);
    }
}

/* EDGE is an polymorphic call.  If BEFORE_INLINING_P is set, mark
   all its potential targets as reachable to permit later inlining if
   devirtualization happens.  After inlining still keep their declarations
   around, so we can devirtualize to a direct call.

   Also try to make trivial devirutalization when no or only one target is
   possible.  */

static void
walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
			       struct cgraph_edge *edge,
			       symtab_node **first,
			       hash_set<symtab_node *> *reachable,
			       bool before_inlining_p)
{
  unsigned int i;
  void *cache_token;
  bool final;
  vec <cgraph_node *>targets
    = possible_polymorphic_call_targets
	(edge, &final, &cache_token);

  if (!reachable_call_targets->add (cache_token))
    {
      for (i = 0; i < targets.length (); i++)
	{
	  struct cgraph_node *n = targets[i];

	  /* Do not bother to mark virtual methods in anonymous namespace;
	     either we will find use of virtual table defining it, or it is
	     unused.  */
	  if (TREE_CODE (TREE_TYPE (n->decl)) == METHOD_TYPE
	      && type_in_anonymous_namespace_p
		    (TYPE_METHOD_BASETYPE (TREE_TYPE (n->decl))))
	    continue;

	  n->indirect_call_target = true;
	  symtab_node *body = n->function_symbol ();

	  /* Prior inlining, keep alive bodies of possible targets for
	     devirtualization.  */
	  if (n->definition
	      && (before_inlining_p
		  && opt_for_fn (body->decl, optimize)
		  && opt_for_fn (body->decl, flag_devirtualize)))
	     {
		/* Be sure that we will not optimize out alias target
		   body.  */
		if (DECL_EXTERNAL (n->decl)
		    && n->alias
		    && before_inlining_p)
		  reachable->add (body);
	       reachable->add (n);
	     }
	  /* Even after inlining we want to keep the possible targets in the
	     boundary, so late passes can still produce direct call even if
	     the chance for inlining is lost.  */
	  enqueue_node (n, first, reachable);
	}
    }

  /* Very trivial devirtualization; when the type is
     final or anonymous (so we know all its derivation)
     and there is only one possible virtual call target,
     make the edge direct.  */
  if (final)
    {
      if (targets.length () <= 1 && dbg_cnt (devirt))
	{
	  cgraph_node *target, *node = edge->caller;
	  if (targets.length () == 1)
	    target = targets[0];
	  else
	    target = cgraph_node::get_create
		       (builtin_decl_implicit (BUILT_IN_UNREACHABLE));

	  if (dump_enabled_p ())
            {
	      location_t locus;
	      if (edge->call_stmt)
		locus = gimple_location (edge->call_stmt);
	      else
		locus = UNKNOWN_LOCATION;
	      dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, locus,
			       "devirtualizing call in %s to %s\n",
			       edge->caller->dump_name (),
			       target->dump_name ());
	    }
	  edge = edge->make_direct (target);
	  if (ipa_fn_summaries)
	    ipa_update_overall_fn_summary (node);
	  else if (edge->call_stmt)
	    {
	      edge->redirect_call_stmt_to_callee ();

	      /* Call to __builtin_unreachable shouldn't be instrumented.  */
	      if (!targets.length ())
		gimple_call_set_with_bounds (edge->call_stmt, false);
	    }
	}
    }
}

/* Perform reachability analysis and reclaim all unreachable nodes.

   The algorithm is basically mark&sweep but with some extra refinements:

   - reachable extern inline functions needs special handling; the bodies needs
     to stay in memory until inlining in hope that they will be inlined.
     After inlining we release their bodies and turn them into unanalyzed
     nodes even when they are reachable.

   - virtual functions are kept in callgraph even if they seem unreachable in
     hope calls to them will be devirtualized. 

     Again we remove them after inlining.  In late optimization some
     devirtualization may happen, but it is not important since we won't inline
     the call. In theory early opts and IPA should work out all important cases.

   - virtual clones needs bodies of their origins for later materialization;
     this means that we want to keep the body even if the origin is unreachable
     otherwise.  To avoid origin from sitting in the callgraph and being
     walked by IPA passes, we turn them into unanalyzed nodes with body
     defined.

     We maintain set of function declaration where body needs to stay in
     body_needed_for_clonning

     Inline clones represent special case: their declaration match the
     declaration of origin and cgraph_remove_node already knows how to
     reshape callgraph and preserve body when offline copy of function or
     inline clone is being removed.

   - C++ virtual tables keyed to other unit are represented as DECL_EXTERNAL
     variables with DECL_INITIAL set.  We finalize these and keep reachable
     ones around for constant folding purposes.  After inlining we however
     stop walking their references to let everything static referneced by them
     to be removed when it is otherwise unreachable.

   We maintain queue of both reachable symbols (i.e. defined symbols that needs
   to stay) and symbols that are in boundary (i.e. external symbols referenced
   by reachable symbols or origins of clones).  The queue is represented
   as linked list by AUX pointer terminated by 1.

   At the end we keep all reachable symbols. For symbols in boundary we always
   turn definition into a declaration, but we may keep function body around
   based on body_needed_for_clonning

   All symbols that enter the queue have AUX pointer non-zero and are in the
   boundary.  Pointer set REACHABLE is used to track reachable symbols.

   Every symbol can be visited twice - once as part of boundary and once
   as real reachable symbol. enqueue_node needs to decide whether the
   node needs to be re-queued for second processing.  For this purpose
   we set AUX pointer of processed symbols in the boundary to constant 2.  */

bool
symbol_table::remove_unreachable_nodes (FILE *file)
{
  symtab_node *first = (symtab_node *) (void *) 1;
  struct cgraph_node *node, *next;
  varpool_node *vnode, *vnext;
  bool changed = false;
  hash_set<symtab_node *> reachable;
  hash_set<tree> body_needed_for_clonning;
  hash_set<void *> reachable_call_targets;
  bool before_inlining_p = symtab->state < (!optimize && !in_lto_p ? IPA_SSA
					    : IPA_SSA_AFTER_INLINING);

  timevar_push (TV_IPA_UNREACHABLE);
  build_type_inheritance_graph ();
  if (file)
    fprintf (file, "\nReclaiming functions:");
  if (flag_checking)
    {
      FOR_EACH_FUNCTION (node)
	gcc_assert (!node->aux);
      FOR_EACH_VARIABLE (vnode)
	gcc_assert (!vnode->aux);
    }
  /* Mark functions whose bodies are obviously needed.
     This is mostly when they can be referenced externally.  Inline clones
     are special since their declarations are shared with master clone and thus
     cgraph_can_remove_if_no_direct_calls_and_refs_p should not be called on them.  */
  FOR_EACH_FUNCTION (node)
    {
      node->used_as_abstract_origin = false;
      node->indirect_call_target = false;
      if (node->definition
	  && !node->global.inlined_to
	  && !node->in_other_partition
	  && !node->can_remove_if_no_direct_calls_and_refs_p ())
	{
	  gcc_assert (!node->global.inlined_to);
	  reachable.add (node);
	  enqueue_node (node, &first, &reachable);
	}
      else
	gcc_assert (!node->aux);
     }

  /* Mark variables that are obviously needed.  */
  FOR_EACH_DEFINED_VARIABLE (vnode)
    if (!vnode->can_remove_if_no_refs_p()
	&& !vnode->in_other_partition)
      {
	reachable.add (vnode);
	enqueue_node (vnode, &first, &reachable);
      }

  /* Perform reachability analysis.  */
  while (first != (symtab_node *) (void *) 1)
    {
      bool in_boundary_p = !reachable.contains (first);
      symtab_node *node = first;

      first = (symtab_node *)first->aux;

      /* If we are processing symbol in boundary, mark its AUX pointer for
	 possible later re-processing in enqueue_node.  */
      if (in_boundary_p)
	{
	  node->aux = (void *)2;
	  if (node->alias && node->analyzed)
	    enqueue_node (node->get_alias_target (), &first, &reachable);
	}
      else
	{
	  if (TREE_CODE (node->decl) == FUNCTION_DECL
	      && DECL_ABSTRACT_ORIGIN (node->decl))
	    {
	      struct cgraph_node *origin_node
	      = cgraph_node::get (DECL_ABSTRACT_ORIGIN (node->decl));
	      if (origin_node && !origin_node->used_as_abstract_origin)
		{
	          origin_node->used_as_abstract_origin = true;
		  gcc_assert (!origin_node->prev_sibling_clone);
		  gcc_assert (!origin_node->next_sibling_clone);
		  for (cgraph_node *n = origin_node->clones; n;
		       n = n->next_sibling_clone)
		    if (n->decl == DECL_ABSTRACT_ORIGIN (node->decl))
		      n->used_as_abstract_origin = true;
		}
	    }
	  /* If any symbol in a comdat group is reachable, force
	     all externally visible symbols in the same comdat
	     group to be reachable as well.  Comdat-local symbols
	     can be discarded if all uses were inlined.  */
	  if (node->same_comdat_group)
	    {
	      symtab_node *next;
	      for (next = node->same_comdat_group;
		   next != node;
		   next = next->same_comdat_group)
		if (!next->comdat_local_p ()
		    && !reachable.add (next))
		  enqueue_node (next, &first, &reachable);
	    }
	  /* Mark references as reachable.  */
	  process_references (node, &first, before_inlining_p, &reachable);
	}

      if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node))
	{
	  /* Mark the callees reachable unless they are direct calls to extern
 	     inline functions we decided to not inline.  */
	  if (!in_boundary_p)
	    {
	      struct cgraph_edge *e;
	      /* Keep alive possible targets for devirtualization.  */
	      if (opt_for_fn (cnode->decl, optimize)
		  && opt_for_fn (cnode->decl, flag_devirtualize))
		{
		  struct cgraph_edge *next;
		  for (e = cnode->indirect_calls; e; e = next)
		    {
		      next = e->next_callee;
		      if (e->indirect_info->polymorphic)
			walk_polymorphic_call_targets (&reachable_call_targets,
						       e, &first, &reachable,
						       before_inlining_p);
		    }
		}
	      for (e = cnode->callees; e; e = e->next_callee)
		{
	          symtab_node *body = e->callee->function_symbol ();
		  if (e->callee->definition
		      && !e->callee->in_other_partition
		      && (!e->inline_failed
			  || !DECL_EXTERNAL (e->callee->decl)
			  || e->callee->alias
			  || (before_inlining_p
			      && (opt_for_fn (body->decl, optimize)
		                  || (symtab->state < IPA_SSA
		                      && lookup_attribute
				          ("always_inline",
				           DECL_ATTRIBUTES (body->decl)))))))
		    {
		      /* Be sure that we will not optimize out alias target
			 body.  */
		      if (DECL_EXTERNAL (e->callee->decl)
			  && e->callee->alias
			  && before_inlining_p)
			reachable.add (body);
		      reachable.add (e->callee);
		    }
		  enqueue_node (e->callee, &first, &reachable);
		}

	      /* When inline clone exists, mark body to be preserved so when removing
		 offline copy of the function we don't kill it.  */
	      if (cnode->global.inlined_to)
	        body_needed_for_clonning.add (cnode->decl);

	      /* For instrumentation clones we always need original
		 function node for proper LTO privatization.  */
	      if (cnode->instrumentation_clone
		  && cnode->definition)
		{
		  gcc_assert (cnode->instrumented_version || in_lto_p);
		  if (cnode->instrumented_version)
		    {
		      enqueue_node (cnode->instrumented_version, &first,
				    &reachable);
		      reachable.add (cnode->instrumented_version);
		    }
		}

	      /* For non-inline clones, force their origins to the boundary and ensure
		 that body is not removed.  */
	      while (cnode->clone_of)
		{
		  bool noninline = cnode->clone_of->decl != cnode->decl;
		  cnode = cnode->clone_of;
		  if (noninline)
		    {
		      body_needed_for_clonning.add (cnode->decl);
		      enqueue_node (cnode, &first, &reachable);
		    }
		}

	    }
	  else if (cnode->thunk.thunk_p)
	    enqueue_node (cnode->callees->callee, &first, &reachable);

	  /* If any reachable function has simd clones, mark them as
	     reachable as well.  */
	  if (cnode->simd_clones)
	    {
	      cgraph_node *next;
	      for (next = cnode->simd_clones;
		   next;
		   next = next->simdclone->next_clone)
		if (in_boundary_p
		    || !reachable.add (next))
		  enqueue_node (next, &first, &reachable);
	    }
	}
      /* When we see constructor of external variable, keep referred nodes in the
	boundary.  This will also hold initializers of the external vars NODE
	refers to.  */
      varpool_node *vnode = dyn_cast <varpool_node *> (node);
      if (vnode
	  && DECL_EXTERNAL (node->decl)
	  && !vnode->alias
	  && in_boundary_p)
	{
	  struct ipa_ref *ref = NULL;
	  for (int i = 0; node->iterate_reference (i, ref); i++)
	    enqueue_node (ref->referred, &first, &reachable);
	}
    }

  /* Remove unreachable functions.   */
  for (node = first_function (); node; node = next)
    {
      next = next_function (node);

      /* If node is not needed at all, remove it.  */
      if (!node->aux)
	{
	  if (file)
	    fprintf (file, " %s", node->dump_name ());
	  node->remove ();
	  changed = true;
	}
      /* If node is unreachable, remove its body.  */
      else if (!reachable.contains (node))
        {
	  /* We keep definitions of thunks and aliases in the boundary so
	     we can walk to the ultimate alias targets and function symbols
	     reliably.  */
	  if (node->alias || node->thunk.thunk_p)
	    ;
	  else if (!body_needed_for_clonning.contains (node->decl)
	      && !node->alias && !node->thunk.thunk_p)
	    node->release_body ();
	  else if (!node->clone_of)
	    gcc_assert (in_lto_p || DECL_RESULT (node->decl));
	  if (node->definition && !node->alias && !node->thunk.thunk_p)
	    {
	      if (file)
		fprintf (file, " %s", node->dump_name ());
	      node->body_removed = true;
	      node->analyzed = false;
	      node->definition = false;
	      node->cpp_implicit_alias = false;
	      node->alias = false;
	      node->transparent_alias = false;
	      node->thunk.thunk_p = false;
	      node->weakref = false;
	      /* After early inlining we drop always_inline attributes on
		 bodies of functions that are still referenced (have their
		 address taken).  */
	      DECL_ATTRIBUTES (node->decl)
		= remove_attribute ("always_inline",
				    DECL_ATTRIBUTES (node->decl));
	      if (!node->in_other_partition)
		node->local.local = false;
	      node->remove_callees ();
	      node->remove_all_references ();
	      changed = true;
	      if (node->thunk.thunk_p
		  && node->thunk.add_pointer_bounds_args)
		{
		  node->thunk.thunk_p = false;
		  node->thunk.add_pointer_bounds_args = false;
		}
	    }
	}
      else
	gcc_assert (node->clone_of || !node->has_gimple_body_p ()
		    || in_lto_p || DECL_RESULT (node->decl));
    }

  /* Inline clones might be kept around so their materializing allows further
     cloning.  If the function the clone is inlined into is removed, we need
     to turn it into normal cone.  */
  FOR_EACH_FUNCTION (node)
    {
      if (node->global.inlined_to
	  && !node->callers)
	{
	  gcc_assert (node->clones);
	  node->global.inlined_to = NULL;
	  update_inlined_to_pointer (node, node);
	}
      node->aux = NULL;
    }

  /* Remove unreachable variables.  */
  if (file)
    fprintf (file, "\nReclaiming variables:");
  for (vnode = first_variable (); vnode; vnode = vnext)
    {
      vnext = next_variable (vnode);
      if (!vnode->aux
	  /* For can_refer_decl_in_current_unit_p we want to track for
	     all external variables if they are defined in other partition
	     or not.  */
	  && (!flag_ltrans || !DECL_EXTERNAL (vnode->decl)))
	{
	  struct ipa_ref *ref = NULL;

	  /* First remove the aliases, so varpool::remove can possibly lookup
	     the constructor and save it for future use.  */
	  while (vnode->iterate_direct_aliases (0, ref))
	    {
	      if (file)
		fprintf (file, " %s", ref->referred->dump_name ());
	      ref->referring->remove ();
	    }
	  if (file)
	    fprintf (file, " %s", vnode->dump_name ());
          vnext = next_variable (vnode);
	  /* Signal removal to the debug machinery.  */
	  if (! flag_wpa)
	    {
	      vnode->definition = false;
	      (*debug_hooks->late_global_decl) (vnode->decl);
	    }
	  vnode->remove ();
	  changed = true;
	}
      else if (!reachable.contains (vnode) && !vnode->alias)
        {
	  tree init;
	  if (vnode->definition)
	    {
	      if (file)
		fprintf (file, " %s", vnode->name ());
	      changed = true;
	    }
	  /* Keep body if it may be useful for constant folding.  */
	  if ((init = ctor_for_folding (vnode->decl)) == error_mark_node
	      && !POINTER_BOUNDS_P (vnode->decl))
	    vnode->remove_initializer ();
	  else
	    DECL_INITIAL (vnode->decl) = init;
	  vnode->body_removed = true;
	  vnode->definition = false;
	  vnode->analyzed = false;
	  vnode->aux = NULL;

	  vnode->remove_from_same_comdat_group ();

	  vnode->remove_all_references ();
	}
      else
	vnode->aux = NULL;
    }

  /* Now update address_taken flags and try to promote functions to be local.  */
  if (file)
    fprintf (file, "\nClearing address taken flags:");
  FOR_EACH_DEFINED_FUNCTION (node)
    if (node->address_taken
	&& !node->used_from_other_partition)
      {
	if (!node->call_for_symbol_and_aliases
	    (has_addr_references_p, NULL, true)
	    && (!node->instrumentation_clone
		|| !node->instrumented_version
		|| !node->instrumented_version->address_taken))
	  {
	    if (file)
	      fprintf (file, " %s", node->name ());
	    node->address_taken = false;
	    changed = true;
	    if (node->local_p ()
		/* Virtual functions may be kept in cgraph just because
		   of possible later devirtualization.  Do not mark them as
		   local too early so we won't optimize them out before
		   we are done with polymorphic call analysis.  */
		&& (!before_inlining_p
		    || !node->call_for_symbol_and_aliases
		       (is_indirect_call_target_p, NULL, true)))
	      {
		node->local.local = true;
		if (file)
		  fprintf (file, " (local)");
	      }
	  }
      }
  if (file)
    fprintf (file, "\n");

  symtab_node::checking_verify_symtab_nodes ();

  /* If we removed something, perhaps profile could be improved.  */
  if (changed && (optimize || in_lto_p) && ipa_call_summaries)
    FOR_EACH_DEFINED_FUNCTION (node)
      ipa_propagate_frequency (node);

  timevar_pop (TV_IPA_UNREACHABLE);
  return changed;
}

/* Process references to VNODE and set flags WRITTEN, ADDRESS_TAKEN, READ
   as needed, also clear EXPLICIT_REFS if the references to given variable
   do not need to be explicit.  */

void
process_references (varpool_node *vnode,
		    bool *written, bool *address_taken,
		    bool *read, bool *explicit_refs)
{
  int i;
  struct ipa_ref *ref;

  if (!vnode->all_refs_explicit_p ()
      || TREE_THIS_VOLATILE (vnode->decl))
    *explicit_refs = false;

  for (i = 0; vnode->iterate_referring (i, ref)
	      && *explicit_refs && (!*written || !*address_taken || !*read); i++)
    switch (ref->use)
      {
      case IPA_REF_ADDR:
	*address_taken = true;
	break;
      case IPA_REF_LOAD:
	*read = true;
	break;
      case IPA_REF_STORE:
	*written = true;
	break;
      case IPA_REF_ALIAS:
	process_references (dyn_cast<varpool_node *> (ref->referring), written,
			    address_taken, read, explicit_refs);
	break;
      case IPA_REF_CHKP:
	gcc_unreachable ();
      }
}

/* Set TREE_READONLY bit.  */

bool
set_readonly_bit (varpool_node *vnode, void *data ATTRIBUTE_UNUSED)
{
  TREE_READONLY (vnode->decl) = true;
  return false;
}

/* Set writeonly bit and clear the initalizer, since it will not be needed.  */

bool
set_writeonly_bit (varpool_node *vnode, void *data)
{
  vnode->writeonly = true;
  if (optimize || in_lto_p)
    {
      DECL_INITIAL (vnode->decl) = NULL;
      if (!vnode->alias)
	{
	  if (vnode->num_references ())
	    *(bool *)data = true;
	  vnode->remove_all_references ();
	}
    }
  return false;
}

/* Clear addressale bit of VNODE.  */

bool
clear_addressable_bit (varpool_node *vnode, void *data ATTRIBUTE_UNUSED)
{
  vnode->address_taken = false;
  TREE_ADDRESSABLE (vnode->decl) = 0;
  return false;
}

/* Discover variables that have no longer address taken or that are read only
   and update their flags.

   Return true when unreachable symbol removan should be done.

   FIXME: This can not be done in between gimplify and omp_expand since
   readonly flag plays role on what is shared and what is not.  Currently we do
   this transformation as part of whole program visibility and re-do at
   ipa-reference pass (to take into account clonning), but it would
   make sense to do it before early optimizations.  */

bool
ipa_discover_readonly_nonaddressable_vars (void)
{
  bool remove_p = false;
  varpool_node *vnode;
  if (dump_file)
    fprintf (dump_file, "Clearing variable flags:");
  FOR_EACH_VARIABLE (vnode)
    if (!vnode->alias
	&& (TREE_ADDRESSABLE (vnode->decl)
	    || !vnode->writeonly
	    || !TREE_READONLY (vnode->decl)))
      {
	bool written = false;
	bool address_taken = false;
	bool read = false;
	bool explicit_refs = true;

	process_references (vnode, &written, &address_taken, &read,
			    &explicit_refs);
	if (!explicit_refs)
	  continue;
	if (!address_taken)
	  {
	    if (TREE_ADDRESSABLE (vnode->decl) && dump_file)
	      fprintf (dump_file, " %s (non-addressable)", vnode->name ());
	    vnode->call_for_symbol_and_aliases (clear_addressable_bit, NULL,
					        true);
	  }
	if (!address_taken && !written
	    /* Making variable in explicit section readonly can cause section
	       type conflict. 
	       See e.g. gcc.c-torture/compile/pr23237.c */
	    && vnode->get_section () == NULL)
	  {
	    if (!TREE_READONLY (vnode->decl) && dump_file)
	      fprintf (dump_file, " %s (read-only)", vnode->name ());
	    vnode->call_for_symbol_and_aliases (set_readonly_bit, NULL, true);
	  }
	if (!vnode->writeonly && !read && !address_taken && written)
	  {
	    if (dump_file)
	      fprintf (dump_file, " %s (write-only)", vnode->name ());
	    vnode->call_for_symbol_and_aliases (set_writeonly_bit, &remove_p, 
					        true);
	  }
      }
  if (dump_file)
    fprintf (dump_file, "\n");
  return remove_p;
}

/* Generate and emit a static constructor or destructor.  WHICH must
   be one of 'I' (for a constructor), 'D' (for a destructor), 'P'
   (for chp static vars constructor) or 'B' (for chkp static bounds
   constructor).  BODY is a STATEMENT_LIST containing GENERIC
   statements.  PRIORITY is the initialization priority for this
   constructor or destructor.

   FINAL specify whether the externally visible name for collect2 should
   be produced. */

static void
cgraph_build_static_cdtor_1 (char which, tree body, int priority, bool final)
{
  static int counter = 0;
  char which_buf[16];
  tree decl, name, resdecl;

  /* The priority is encoded in the constructor or destructor name.
     collect2 will sort the names and arrange that they are called at
     program startup.  */
  if (final)
    sprintf (which_buf, "%c_%.5d_%d", which, priority, counter++);
  else
  /* Proudce sane name but one not recognizable by collect2, just for the
     case we fail to inline the function.  */
    sprintf (which_buf, "sub_%c_%.5d_%d", which, priority, counter++);
  name = get_file_function_name (which_buf);

  decl = build_decl (input_location, FUNCTION_DECL, name,
		     build_function_type_list (void_type_node, NULL_TREE));
  current_function_decl = decl;

  resdecl = build_decl (input_location,
			RESULT_DECL, NULL_TREE, void_type_node);
  DECL_ARTIFICIAL (resdecl) = 1;
  DECL_RESULT (decl) = resdecl;
  DECL_CONTEXT (resdecl) = decl;

  allocate_struct_function (decl, false);

  TREE_STATIC (decl) = 1;
  TREE_USED (decl) = 1;
  DECL_ARTIFICIAL (decl) = 1;
  DECL_IGNORED_P (decl) = 1;
  DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
  DECL_SAVED_TREE (decl) = body;
  if (!targetm.have_ctors_dtors && final)
    {
      TREE_PUBLIC (decl) = 1;
      DECL_PRESERVE_P (decl) = 1;
    }
  DECL_UNINLINABLE (decl) = 1;

  DECL_INITIAL (decl) = make_node (BLOCK);
  BLOCK_SUPERCONTEXT (DECL_INITIAL (decl)) = decl;
  TREE_USED (DECL_INITIAL (decl)) = 1;

  DECL_SOURCE_LOCATION (decl) = input_location;
  cfun->function_end_locus = input_location;

  switch (which)
    {
    case 'I':
      DECL_STATIC_CONSTRUCTOR (decl) = 1;
      decl_init_priority_insert (decl, priority);
      break;
    case 'P':
      DECL_STATIC_CONSTRUCTOR (decl) = 1;
      DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("chkp ctor"),
					  NULL,
					  NULL_TREE);
      decl_init_priority_insert (decl, priority);
      break;
    case 'B':
      DECL_STATIC_CONSTRUCTOR (decl) = 1;
      DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("bnd_legacy"),
					  NULL,
					  NULL_TREE);
      decl_init_priority_insert (decl, priority);
      break;
    case 'D':
      DECL_STATIC_DESTRUCTOR (decl) = 1;
      decl_fini_priority_insert (decl, priority);
      break;
    default:
      gcc_unreachable ();
    }

  gimplify_function_tree (decl);

  cgraph_node::add_new_function (decl, false);

  set_cfun (NULL);
  current_function_decl = NULL;
}

/* Generate and emit a static constructor or destructor.  WHICH must
   be one of 'I' (for a constructor), 'D' (for a destructor), 'P'
   (for chkp static vars constructor) or 'B' (for chkp static bounds
   constructor).  BODY is a STATEMENT_LIST containing GENERIC
   statements.  PRIORITY is the initialization priority for this
   constructor or destructor.  */

void
cgraph_build_static_cdtor (char which, tree body, int priority)
{
  cgraph_build_static_cdtor_1 (which, body, priority, false);
}

/* When target does not have ctors and dtors, we call all constructor
   and destructor by special initialization/destruction function
   recognized by collect2.

   When we are going to build this function, collect all constructors and
   destructors and turn them into normal functions.  */

static void
record_cdtor_fn (struct cgraph_node *node, vec<tree> *ctors, vec<tree> *dtors)
{
  if (DECL_STATIC_CONSTRUCTOR (node->decl))
    ctors->safe_push (node->decl);
  if (DECL_STATIC_DESTRUCTOR (node->decl))
    dtors->safe_push (node->decl);
  node = cgraph_node::get (node->decl);
  DECL_DISREGARD_INLINE_LIMITS (node->decl) = 1;
}

/* Define global constructors/destructor functions for the CDTORS, of
   which they are LEN.  The CDTORS are sorted by initialization
   priority.  If CTOR_P is true, these are constructors; otherwise,
   they are destructors.  */

static void
build_cdtor (bool ctor_p, const vec<tree> &cdtors)
{
  size_t i,j;
  size_t len = cdtors.length ();

  i = 0;
  while (i < len)
    {
      tree body;
      tree fn;
      priority_type priority;

      priority = 0;
      body = NULL_TREE;
      j = i;
      do
	{
	  priority_type p;
	  fn = cdtors[j];
	  p = ctor_p ? DECL_INIT_PRIORITY (fn) : DECL_FINI_PRIORITY (fn);
	  if (j == i)
	    priority = p;
	  else if (p != priority)
	    break;
	  j++;
	}
      while (j < len);

      /* When there is only one cdtor and target supports them, do nothing.  */
      if (j == i + 1
	  && targetm.have_ctors_dtors)
	{
	  i++;
	  continue;
	}
      /* Find the next batch of constructors/destructors with the same
	 initialization priority.  */
      for (;i < j; i++)
	{
	  tree call;
	  fn = cdtors[i];
	  call = build_call_expr (fn, 0);
	  if (ctor_p)
	    DECL_STATIC_CONSTRUCTOR (fn) = 0;
	  else
	    DECL_STATIC_DESTRUCTOR (fn) = 0;
	  /* We do not want to optimize away pure/const calls here.
	     When optimizing, these should be already removed, when not
	     optimizing, we want user to be able to breakpoint in them.  */
	  TREE_SIDE_EFFECTS (call) = 1;
	  append_to_statement_list (call, &body);
	}
      gcc_assert (body != NULL_TREE);
      /* Generate a function to call all the function of like
	 priority.  */
      cgraph_build_static_cdtor_1 (ctor_p ? 'I' : 'D', body, priority, true);
    }
}

/* Comparison function for qsort.  P1 and P2 are actually of type
   "tree *" and point to static constructors.  DECL_INIT_PRIORITY is
   used to determine the sort order.  */

static int
compare_ctor (const void *p1, const void *p2)
{
  tree f1;
  tree f2;
  int priority1;
  int priority2;

  f1 = *(const tree *)p1;
  f2 = *(const tree *)p2;
  priority1 = DECL_INIT_PRIORITY (f1);
  priority2 = DECL_INIT_PRIORITY (f2);

  if (priority1 < priority2)
    return -1;
  else if (priority1 > priority2)
    return 1;
  else
    /* Ensure a stable sort.  Constructors are executed in backwarding
       order to make LTO initialize braries first.  */
    return DECL_UID (f2) - DECL_UID (f1);
}

/* Comparison function for qsort.  P1 and P2 are actually of type
   "tree *" and point to static destructors.  DECL_FINI_PRIORITY is
   used to determine the sort order.  */

static int
compare_dtor (const void *p1, const void *p2)
{
  tree f1;
  tree f2;
  int priority1;
  int priority2;

  f1 = *(const tree *)p1;
  f2 = *(const tree *)p2;
  priority1 = DECL_FINI_PRIORITY (f1);
  priority2 = DECL_FINI_PRIORITY (f2);

  if (priority1 < priority2)
    return -1;
  else if (priority1 > priority2)
    return 1;
  else
    /* Ensure a stable sort.  */
    return DECL_UID (f1) - DECL_UID (f2);
}

/* Generate functions to call static constructors and destructors
   for targets that do not support .ctors/.dtors sections.  These
   functions have magic names which are detected by collect2.  */

static void
build_cdtor_fns (vec<tree> *ctors, vec<tree> *dtors)
{
  if (!ctors->is_empty ())
    {
      gcc_assert (!targetm.have_ctors_dtors || in_lto_p);
      ctors->qsort (compare_ctor);
      build_cdtor (/*ctor_p=*/true, *ctors);
    }

  if (!dtors->is_empty ())
    {
      gcc_assert (!targetm.have_ctors_dtors || in_lto_p);
      dtors->qsort (compare_dtor);
      build_cdtor (/*ctor_p=*/false, *dtors);
    }
}

/* Look for constructors and destructors and produce function calling them.
   This is needed for targets not supporting ctors or dtors, but we perform the
   transformation also at linktime to merge possibly numerous
   constructors/destructors into single function to improve code locality and
   reduce size.  */

static unsigned int
ipa_cdtor_merge (void)
{
  /* A vector of FUNCTION_DECLs declared as static constructors.  */
  auto_vec<tree, 20> ctors;
  /* A vector of FUNCTION_DECLs declared as static destructors.  */
  auto_vec<tree, 20> dtors;
  struct cgraph_node *node;
  FOR_EACH_DEFINED_FUNCTION (node)
    if (DECL_STATIC_CONSTRUCTOR (node->decl)
	|| DECL_STATIC_DESTRUCTOR (node->decl))
       record_cdtor_fn (node, &ctors, &dtors);
  build_cdtor_fns (&ctors, &dtors);
  return 0;
}

namespace {

const pass_data pass_data_ipa_cdtor_merge =
{
  IPA_PASS, /* type */
  "cdtor", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_CGRAPHOPT, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_ipa_cdtor_merge : public ipa_opt_pass_d
{
public:
  pass_ipa_cdtor_merge (gcc::context *ctxt)
    : ipa_opt_pass_d (pass_data_ipa_cdtor_merge, 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 *);
  virtual unsigned int execute (function *) { return ipa_cdtor_merge (); }

}; // class pass_ipa_cdtor_merge

bool
pass_ipa_cdtor_merge::gate (function *)
{
  /* Perform the pass when we have no ctors/dtors support
     or at LTO time to merge multiple constructors into single
     function.  */
  return !targetm.have_ctors_dtors || in_lto_p;
}

} // anon namespace

ipa_opt_pass_d *
make_pass_ipa_cdtor_merge (gcc::context *ctxt)
{
  return new pass_ipa_cdtor_merge (ctxt);
}

/* Invalid pointer representing BOTTOM for single user dataflow.  */
#define BOTTOM ((cgraph_node *)(size_t) 2)

/* Meet operation for single user dataflow.
   Here we want to associate variables with sigle function that may access it.

   FUNCTION is current single user of a variable, VAR is variable that uses it.
   Latttice is stored in SINGLE_USER_MAP.

   We represent: 
    - TOP by no entry in SIGNLE_USER_MAP
    - BOTTOM by BOTTOM in AUX pointer (to save lookups)
    - known single user by cgraph pointer in SINGLE_USER_MAP.  */

cgraph_node *
meet (cgraph_node *function, varpool_node *var,
       hash_map<varpool_node *, cgraph_node *> &single_user_map)
{
  struct cgraph_node *user, **f;

  if (var->aux == BOTTOM)
    return BOTTOM;

  f = single_user_map.get (var);
  if (!f)
    return function;
  user = *f;
  if (!function)
    return user;
  else if (function != user)
    return BOTTOM;
  else
    return function;
}

/* Propagation step of single-use dataflow.

   Check all uses of VNODE and see if they are used by single function FUNCTION.
   SINGLE_USER_MAP represents the dataflow lattice.  */

cgraph_node *
propagate_single_user (varpool_node *vnode, cgraph_node *function,
		       hash_map<varpool_node *, cgraph_node *> &single_user_map)
{
  int i;
  struct ipa_ref *ref;

  gcc_assert (!vnode->externally_visible);

  /* If node is an alias, first meet with its target.  */
  if (vnode->alias)
    function = meet (function, vnode->get_alias_target (), single_user_map);

  /* Check all users and see if they correspond to a single function.  */
  for (i = 0; vnode->iterate_referring (i, ref) && function != BOTTOM; i++)
    {
      struct cgraph_node *cnode = dyn_cast <cgraph_node *> (ref->referring);
      if (cnode)
	{
	  if (cnode->global.inlined_to)
	    cnode = cnode->global.inlined_to;
	  if (!function)
	    function = cnode;
	  else if (function != cnode)
	    function = BOTTOM;
	}
      else
	function = meet (function, dyn_cast <varpool_node *> (ref->referring),
			 single_user_map);
    }
  return function;
}

/* Pass setting used_by_single_function flag.
   This flag is set on variable when there is only one function that may
   possibly referr to it.  */

static unsigned int
ipa_single_use (void)
{
  varpool_node *first = (varpool_node *) (void *) 1;
  varpool_node *var;
  hash_map<varpool_node *, cgraph_node *> single_user_map;

  FOR_EACH_DEFINED_VARIABLE (var)
    if (!var->all_refs_explicit_p ())
      var->aux = BOTTOM;
    else
      {
	/* Enqueue symbol for dataflow.  */
        var->aux = first;
	first = var;
      }

  /* The actual dataflow.  */

  while (first != (void *) 1)
    {
      cgraph_node *user, *orig_user, **f;

      var = first;
      first = (varpool_node *)first->aux;

      f = single_user_map.get (var);
      if (f)
	orig_user = *f;
      else
	orig_user = NULL;
      user = propagate_single_user (var, orig_user, single_user_map);

      gcc_checking_assert (var->aux != BOTTOM);

      /* If user differs, enqueue all references.  */
      if (user != orig_user)
	{
	  unsigned int i;
	  ipa_ref *ref;

	  single_user_map.put (var, user);

	  /* Enqueue all aliases for re-processing.  */
	  for (i = 0; var->iterate_direct_aliases (i, ref); i++)
	    if (!ref->referring->aux)
	      {
		ref->referring->aux = first;
		first = dyn_cast <varpool_node *> (ref->referring);
	      }
	  /* Enqueue all users for re-processing.  */
	  for (i = 0; var->iterate_reference (i, ref); i++)
	    if (!ref->referred->aux
	        && ref->referred->definition
		&& is_a <varpool_node *> (ref->referred))
	      {
		ref->referred->aux = first;
		first = dyn_cast <varpool_node *> (ref->referred);
	      }

	  /* If user is BOTTOM, just punt on this var.  */
	  if (user == BOTTOM)
	    var->aux = BOTTOM;
	  else
	    var->aux = NULL;
	}
      else
	var->aux = NULL;
    }

  FOR_EACH_DEFINED_VARIABLE (var)
    {
      if (var->aux != BOTTOM)
	{
	  /* Not having the single user known means that the VAR is
	     unreachable.  Either someone forgot to remove unreachable
	     variables or the reachability here is wrong.  */

	  gcc_checking_assert (single_user_map.get (var));

	  if (dump_file)
	    {
	      fprintf (dump_file, "Variable %s is used by single function\n",
		       var->dump_name ());
	    }
	  var->used_by_single_function = true;
	}
      var->aux = NULL;
    }
  return 0;
}

namespace {

const pass_data pass_data_ipa_single_use =
{
  IPA_PASS, /* type */
  "single-use", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_CGRAPHOPT, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_ipa_single_use : public ipa_opt_pass_d
{
public:
  pass_ipa_single_use (gcc::context *ctxt)
    : ipa_opt_pass_d (pass_data_ipa_single_use, 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 unsigned int execute (function *) { return ipa_single_use (); }

}; // class pass_ipa_single_use

} // anon namespace

ipa_opt_pass_d *
make_pass_ipa_single_use (gcc::context *ctxt)
{
  return new pass_ipa_single_use (ctxt);
}

/* Materialize all clones.  */

namespace {

const pass_data pass_data_materialize_all_clones =
{
  SIMPLE_IPA_PASS, /* type */
  "materialize-all-clones", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_IPA_OPT, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_materialize_all_clones : public simple_ipa_opt_pass
{
public:
  pass_materialize_all_clones (gcc::context *ctxt)
    : simple_ipa_opt_pass (pass_data_materialize_all_clones, ctxt)
  {}

  /* opt_pass methods: */
  virtual unsigned int execute (function *)
    {
      symtab->materialize_all_clones ();
      return 0;
    }

}; // class pass_materialize_all_clones

} // anon namespace

simple_ipa_opt_pass *
make_pass_materialize_all_clones (gcc::context *ctxt)
{
  return new pass_materialize_all_clones (ctxt);
}
