/* Callgraph handling code.
   Copyright (C) 2003-2013 Free Software Foundation, Inc.
   Contributed by Jan Hubicka

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 "tm.h"
#include "tree.h"
#include "cgraph.h"
#include "langhooks.h"
#include "diagnostic-core.h"
#include "hashtab.h"
#include "ggc.h"
#include "timevar.h"
#include "debug.h"
#include "target.h"
#include "output.h"
#include "gimple.h"
#include "tree-flow.h"
#include "toplev.h"
#include "flags.h"
#include "l-ipo.h"

/* Return varpool node assigned to DECL.  Create new one when needed.  */
struct varpool_node *
varpool_node_for_decl (tree decl)
{
  struct varpool_node *node = varpool_get_node (decl);
  gcc_assert (TREE_CODE (decl) == VAR_DECL
	      && (TREE_STATIC (decl) || DECL_EXTERNAL (decl) || in_lto_p));
  if (node)
    return node;

  node = ggc_alloc_cleared_varpool_node ();
  node->module_id = current_module_id;
  node->symbol.type = SYMTAB_VARIABLE;
  node->symbol.decl = decl;
  symtab_register_node ((symtab_node)node);
  return node;
}

/* Remove node from the varpool.  */
void
varpool_remove_node (struct varpool_node *node)
{
  varpool_remove_link_node (node);
  symtab_unregister_node ((symtab_node)node);
  if (DECL_INITIAL (node->symbol.decl)
      && !DECL_IN_CONSTANT_POOL (node->symbol.decl)
      /* Keep vtables for BINFO folding.  */
      && !DECL_VIRTUAL_P (node->symbol.decl)
      /* FIXME: http://gcc.gnu.org/PR55395 */
      && debug_info_level == DINFO_LEVEL_NONE)
    DECL_INITIAL (node->symbol.decl) = error_mark_node;
  ggc_free (node);
}

/* Dump given cgraph node.  */
void
dump_varpool_node (FILE *f, struct varpool_node *node)
{
  dump_symtab_base (f, (symtab_node)node);
  fprintf (f, "  Availability: %s\n",
	   cgraph_function_flags_ready
	   ? cgraph_availability_names[cgraph_variable_initializer_availability (node)]
	   : "not-ready");
  fprintf (f, "  Varpool flags:");
  if (DECL_INITIAL (node->symbol.decl))
    fprintf (f, " initialized");
  if (node->analyzed)
    fprintf (f, " analyzed");
  if (node->finalized)
    fprintf (f, " finalized");
  if (node->output)
    fprintf (f, " output");
  fprintf (f, "\n");
}

/* Dump the variable pool.  */
void
dump_varpool (FILE *f)
{
  struct varpool_node *node;

  fprintf (f, "variable pool:\n\n");
  FOR_EACH_VARIABLE (node)
    dump_varpool_node (f, node);
}

/* Dump the variable pool to stderr.  */

DEBUG_FUNCTION void
debug_varpool (void)
{
  dump_varpool (stderr);
}

/* Given an assembler name, lookup node.  */

struct varpool_node *
varpool_node_for_asm (tree asmname)
{
  if (symtab_node node = symtab_node_for_asm (asmname))
    if (varpool_node *vnode = dyn_cast <varpool_node> (node))
      return vnode;
  return NULL;
}

/* Determine if variable DECL is needed.  That is, visible to something
   either outside this translation unit, something magic in the system
   configury */
bool
decide_is_variable_needed (struct varpool_node *node, tree decl)
{
  if (DECL_EXTERNAL (decl))
    return false;

  /* If the user told us it is used, then it must be so.  */
  if (node->symbol.force_output)
    return true;

  /* Externally visible variables must be output.  The exception is
     COMDAT variables that must be output only when they are needed.  */
  if (TREE_PUBLIC (decl)
      && !DECL_COMDAT (decl))
    return true;

  return false;
}

/* Return if DECL is constant and its initial value is known (so we can do
   constant folding using DECL_INITIAL (decl)).  */

bool
const_value_known_p (tree decl)
{
  if (TREE_CODE (decl) != VAR_DECL
      &&TREE_CODE (decl) != CONST_DECL)
    return false;

  if (TREE_CODE (decl) == CONST_DECL
      || DECL_IN_CONSTANT_POOL (decl))
    return true;

  gcc_assert (TREE_CODE (decl) == VAR_DECL);

  if (!TREE_READONLY (decl) || TREE_THIS_VOLATILE (decl))
    return false;

  /* Gimplifier takes away constructors of local vars  */
  if (!TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
    return DECL_INITIAL (decl) != NULL;

  gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl));

  /* Variables declared 'const' without an initializer
     have zero as the initializer if they may not be
     overridden at link or run time.  */
  if (!DECL_INITIAL (decl)
      && (DECL_EXTERNAL (decl)
	  || decl_replaceable_p (decl)))
    return false;

  /* Variables declared `const' with an initializer are considered
     to not be overwritable with different initializer by default. 

     ??? Previously we behaved so for scalar variables but not for array
     accesses.  */
  return true;
}

/* Add the variable DECL to the varpool.
   Unlike varpool_finalize_decl function is intended to be used
   by middle end and allows insertion of new variable at arbitrary point
   of compilation.  */
void
varpool_add_new_variable (tree decl)
{
  struct varpool_node *node;
  varpool_finalize_decl (decl);
  node = varpool_node_for_decl (decl);
  if (varpool_externally_visible_p (node, false))
    node->symbol.externally_visible = true;
}

/* Return variable availability.  See cgraph.h for description of individual
   return values.  */
enum availability
cgraph_variable_initializer_availability (struct varpool_node *node)
{
  gcc_assert (cgraph_function_flags_ready);
  if (!node->finalized)
    return AVAIL_NOT_AVAILABLE;
  if (!TREE_PUBLIC (node->symbol.decl))
    return AVAIL_AVAILABLE;
  /* If the variable can be overwritten, return OVERWRITABLE.  Takes
     care of at least two notable extensions - the COMDAT variables
     used to share template instantiations in C++.  */
  if (!decl_replaceable_p (node->symbol.decl))
    return AVAIL_OVERWRITABLE;
  return AVAIL_AVAILABLE;
}

void
varpool_analyze_node (struct varpool_node *node)
{
  tree decl = node->symbol.decl;

  /* When reading back varpool at LTO time, we re-construct the queue in order
     to have "needed" list right by inserting all needed nodes into varpool.
     We however don't want to re-analyze already analyzed nodes.  */
  if (!node->analyzed)
    {
      gcc_assert (!in_lto_p || cgraph_function_flags_ready);
      /* Compute the alignment early so function body expanders are
	 already informed about increased alignment.  */
      align_variable (decl, 0);
    }
  if (node->alias && node->alias_of)
    {
      struct varpool_node *tgt = varpool_node_for_decl (node->alias_of);
      struct varpool_node *n;

      for (n = tgt; n && n->alias;
	   n = n->analyzed ? varpool_alias_aliased_node (n) : NULL)
	if (n == node)
	  {
	    error ("variable %q+D part of alias cycle", node->symbol.decl);
	    node->alias = false;
	    continue;
	  }
      if (!vec_safe_length (node->symbol.ref_list.references))
	ipa_record_reference ((symtab_node)node, (symtab_node)tgt, IPA_REF_ALIAS, NULL);
      if (node->extra_name_alias)
	{
	  DECL_WEAK (node->symbol.decl) = DECL_WEAK (node->alias_of);
	  DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (node->alias_of);
	  DECL_VISIBILITY (node->symbol.decl) = DECL_VISIBILITY (node->alias_of);
	  fixup_same_cpp_alias_visibility ((symtab_node) node,
					   (symtab_node) tgt, node->alias_of);
	}
    }
  else if (DECL_INITIAL (decl))
    record_references_in_initializer (decl, node->analyzed);
  node->analyzed = true;
}

/* Assemble thunks and aliases associated to NODE.  */

static void
assemble_aliases (struct varpool_node *node)
{
  int i;
  struct ipa_ref *ref;
  for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list, i, ref); i++)
    if (ref->use == IPA_REF_ALIAS)
      {
	struct varpool_node *alias = ipa_ref_referring_varpool_node (ref);
	do_assemble_alias (alias->symbol.decl,
			DECL_ASSEMBLER_NAME (alias->alias_of));
	assemble_aliases (alias);
      }
}

/* Output one variable, if necessary.  Return whether we output it.  */

bool
varpool_assemble_decl (struct varpool_node *node)
{
  tree decl = node->symbol.decl;

  /* Aliases are outout when their target is produced or by
     output_weakrefs.  */
  if (node->alias)
    return false;

  /* Constant pool is output from RTL land when the reference
     survive till this level.  */
  if (DECL_IN_CONSTANT_POOL (decl) && TREE_ASM_WRITTEN (decl))
    return false;

  /* Decls with VALUE_EXPR should not be in the varpool at all.  They
     are not real variables, but just info for debugging and codegen.
     Unfortunately at the moment emutls is not updating varpool correctly
     after turning real vars into value_expr vars.  */
  if (DECL_HAS_VALUE_EXPR_P (decl)
      && !targetm.have_tls)
    return false;

  /* Hard register vars do not need to be output.  */
  if (DECL_HARD_REGISTER (decl))
    return false;

  gcc_checking_assert (!TREE_ASM_WRITTEN (decl)
		       && TREE_CODE (decl) == VAR_DECL
		       && !DECL_HAS_VALUE_EXPR_P (decl));

  if (!node->symbol.in_other_partition
      && !DECL_EXTERNAL (decl))
    {
      assemble_variable (decl, 0, 1, 0);
      gcc_assert (TREE_ASM_WRITTEN (decl));
      node->finalized = 1;
      assemble_aliases (node);
      return true;
    }

  return false;
}

/* Add NODE to queue starting at FIRST. 
   The queue is linked via AUX pointers and terminated by pointer to 1.  */

static void
enqueue_node (struct varpool_node *node, struct varpool_node **first)
{
  if (node->symbol.aux)
    return;
  gcc_checking_assert (*first);
  node->symbol.aux = *first;
  *first = node;
}

/* Optimization of function bodies might've rendered some variables as
   unnecessary so we want to avoid these from being compiled.  Re-do
   reachability starting from variables that are either externally visible
   or was referred from the asm output routines.  */

static void
varpool_remove_unreferenced_decls (void)
{
  struct varpool_node *next, *node;
  struct varpool_node *first = (struct varpool_node *)(void *)1;
  int i;
  struct ipa_ref *ref;

  if (seen_error ())
    return;

  if (cgraph_dump_file)
    fprintf (cgraph_dump_file, "Trivially needed variables:");
  FOR_EACH_DEFINED_VARIABLE (node)
    {
      if (node->analyzed
	  && (!varpool_can_remove_if_no_refs (node)
	      /* We just expanded all function bodies.  See if any of
		 them needed the variable.  */
	      || DECL_RTL_SET_P (node->symbol.decl)))
	{
	  enqueue_node (node, &first);
          if (cgraph_dump_file)
	    fprintf (cgraph_dump_file, " %s", varpool_node_asm_name (node));
	}
    }
  while (first != (struct varpool_node *)(void *)1)
    {
      node = first;
      first = (struct varpool_node *)first->symbol.aux;

      if (node->symbol.same_comdat_group)
	{
	  symtab_node next;
	  for (next = node->symbol.same_comdat_group;
	       next != (symtab_node)node;
	       next = next->symbol.same_comdat_group)
	    {
	      varpool_node *vnext = dyn_cast <varpool_node> (next);
	      if (vnext && vnext->analyzed)
		enqueue_node (vnext, &first);
	    }
	}
      for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref); i++)
	{
	  varpool_node *vnode = dyn_cast <varpool_node> (ref->referred);
	  if (vnode
	      && (!DECL_EXTERNAL (ref->referred->symbol.decl)
		  || vnode->alias)
	      && vnode->analyzed)
	    enqueue_node (vnode, &first);
	}
    }
  if (cgraph_dump_file)
    fprintf (cgraph_dump_file, "\nRemoving variables:");
  for (node = varpool_first_defined_variable (); node; node = next)
    {
      next = varpool_next_defined_variable (node);
      if (!node->symbol.aux)
	{
          if (cgraph_dump_file)
	    fprintf (cgraph_dump_file, " %s", varpool_node_asm_name (node));
	  varpool_remove_node (node);
	}
    }
  if (cgraph_dump_file)
    fprintf (cgraph_dump_file, "\n");
}

/* For variables in named sections make sure get_variable_section
   is called before we switch to those sections.  Then section
   conflicts between read-only and read-only requiring relocations
   sections can be resolved.  */
void
varpool_finalize_named_section_flags (struct varpool_node *node)
{
  if (!TREE_ASM_WRITTEN (node->symbol.decl)
      && !node->alias
      && !node->symbol.in_other_partition
      && !DECL_EXTERNAL (node->symbol.decl)
      && TREE_CODE (node->symbol.decl) == VAR_DECL
      && !DECL_HAS_VALUE_EXPR_P (node->symbol.decl)
      && DECL_SECTION_NAME (node->symbol.decl))
    get_variable_section (node->symbol.decl, false);
}

/* Output all variables enqueued to be assembled.  */
bool
varpool_output_variables (void)
{
  bool changed = false;
  struct varpool_node *node;

  if (seen_error ())
    return false;

  varpool_remove_unreferenced_decls ();

  timevar_push (TV_VAROUT);

  FOR_EACH_DEFINED_VARIABLE (node)
    varpool_finalize_named_section_flags (node);

  FOR_EACH_DEFINED_VARIABLE (node)
    if (varpool_assemble_decl (node))
      changed = true;
  timevar_pop (TV_VAROUT);
  return changed;
}

/* Create a new global variable of type TYPE.  */
tree
add_new_static_var (tree type)
{
  tree new_decl;
  struct varpool_node *new_node;

  new_decl = create_tmp_var_raw (type, NULL);
  DECL_NAME (new_decl) = create_tmp_var_name (NULL);
  TREE_READONLY (new_decl) = 0;
  TREE_STATIC (new_decl) = 1;
  TREE_USED (new_decl) = 1;
  DECL_CONTEXT (new_decl) = NULL_TREE;
  DECL_ABSTRACT (new_decl) = 0;
  lang_hooks.dup_lang_specific_decl (new_decl);
  new_node = varpool_node_for_decl (new_decl);
  varpool_finalize_decl (new_decl);

  return new_node->symbol.decl;
}

/* Attempt to mark ALIAS as an alias to DECL.  Return TRUE if successful.
   Extra name aliases are output whenever DECL is output.  */

struct varpool_node *
varpool_create_variable_alias (tree alias, tree decl)
{
  struct varpool_node *alias_node;

  gcc_assert (TREE_CODE (decl) == VAR_DECL);
  gcc_assert (TREE_CODE (alias) == VAR_DECL);
  alias_node = varpool_node_for_decl (alias);
  alias_node->alias = 1;
  alias_node->finalized = 1;
  alias_node->alias_of = decl;

  /* Extra name alias mechanizm creates aliases really late
     via DECL_ASSEMBLER_NAME mechanizm.
     This is unfortunate because they are not going through the
     standard channels.  Ensure they get output.  */
  if (cgraph_state >= CGRAPH_STATE_IPA)
    {
      varpool_analyze_node (alias_node);
      if (TREE_PUBLIC (alias))
	alias_node->symbol.externally_visible = true;
    }
  return alias_node;
}

/* Attempt to mark ALIAS as an alias to DECL.  Return TRUE if successful.
   Extra name aliases are output whenever DECL is output.  */

struct varpool_node *
varpool_extra_name_alias (tree alias, tree decl)
{
  struct varpool_node *alias_node;

#ifndef ASM_OUTPUT_DEF
  /* If aliases aren't supported by the assembler, fail.  */
  return NULL;
#endif
  alias_node = varpool_create_variable_alias (alias, decl);
  alias_node->extra_name_alias = true;
  return alias_node;
}

/* Call calback on NODE and aliases associated to NODE. 
   When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
   skipped. */

bool
varpool_for_node_and_aliases (struct varpool_node *node,
			      bool (*callback) (struct varpool_node *, void *),
			      void *data,
			      bool include_overwritable)
{
  int i;
  struct ipa_ref *ref;

  if (callback (node, data))
    return true;
  for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list, i, ref); i++)
    if (ref->use == IPA_REF_ALIAS)
      {
	struct varpool_node *alias = ipa_ref_referring_varpool_node (ref);
	if (include_overwritable
	    || cgraph_variable_initializer_availability (alias) > AVAIL_OVERWRITABLE)
          if (varpool_for_node_and_aliases (alias, callback, data,
					   include_overwritable))
	    return true;
      }
  return false;
}
