/* Localize comdats.
   Copyright (C) 2014-2019 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 is very simple pass that looks for static symbols that are used
   exclusively by symbol within one comdat group.  In this case it makes
   sense to bring the symbol itself into the group to avoid dead code
   that would arrise when the comdat group from current unit is replaced
   by a different copy.  Consider for example:

    static int q(void)
    {
      ....
    }
    inline int t(void)
    {
      return q();
    }

   if Q is used only by T, it makes sense to put Q into T's comdat group.

   The pass solve simple dataflow across the callgraph trying to prove what
   symbols are used exclusively from a given comdat group.

   The implementation maintains a queue linked by AUX pointer terminated by
   pointer value 1. Lattice values are NULL for TOP, actual comdat group, or
   ERROR_MARK_NODE for bottom.

   TODO: When symbol is used only by comdat symbols, but from different groups,
   it would make sense to produce a new comdat group for it with anonymous name.

   TODO2: We can't mix variables and functions within one group.  Currently
   we just give up on references of symbols of different types.  We also should
   handle this by anonymous comdat group section.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "tree-pass.h"
#include "cgraph.h"

/* Main dataflow loop propagating comdat groups across
   the symbol table.  All references to SYMBOL are examined
   and NEWGROUP is updated accordingly. MAP holds current lattice
   values for individual symbols.  */

tree
propagate_comdat_group (struct symtab_node *symbol,
			tree newgroup, hash_map<symtab_node *, tree> &map)
{
  int i;
  struct ipa_ref *ref;

  /* Walk all references to SYMBOL, recursively dive into aliases.  */

  for (i = 0;
       symbol->iterate_referring (i, ref)
       && newgroup != error_mark_node; i++)
    {
      struct symtab_node *symbol2 = ref->referring;

      if (ref->use == IPA_REF_ALIAS)
	{
	  newgroup = propagate_comdat_group (symbol2, newgroup, map);
	  continue;
	}

      /* One COMDAT group cannot hold both variables and functions at
	 a same time.  For now we just go to BOTTOM, in future we may
	 invent special comdat groups for this case.  */

      if (symbol->type != symbol2->type)
	{
	  newgroup = error_mark_node;
	  break;
	}

      /* If we see inline clone, its comdat group actually
	 corresponds to the comdat group of the function it is inlined
	 to.  */

      if (cgraph_node * cn = dyn_cast <cgraph_node *> (symbol2))
	{
	  if (cn->inlined_to)
	    symbol2 = cn->inlined_to;
	}

      /* The actual merge operation.  */

      tree *val2 = map.get (symbol2);

      if (val2 && *val2 != newgroup)
	{
	  if (!newgroup)
	    newgroup = *val2;
	  else
	    newgroup = error_mark_node;
	}
    }

  /* If we analyze function, walk also callers.  */

  cgraph_node *cnode = dyn_cast <cgraph_node *> (symbol);

  if (cnode)
    for (struct cgraph_edge * edge = cnode->callers;
	 edge && newgroup != error_mark_node; edge = edge->next_caller)
      {
	struct symtab_node *symbol2 = edge->caller;

	if (cgraph_node * cn = dyn_cast <cgraph_node *> (symbol2))
	  {
	    /* Thunks cannot call across section boundary.  */
	    if (cn->thunk.thunk_p)
	      newgroup = propagate_comdat_group (symbol2, newgroup, map);
	    /* If we see inline clone, its comdat group actually
	       corresponds to the comdat group of the function it
	       is inlined to.  */
	    if (cn->inlined_to)
	      symbol2 = cn->inlined_to;
	  }

        /* The actual merge operation.  */

	tree *val2 = map.get (symbol2);

	if (val2 && *val2 != newgroup)
	  {
	    if (!newgroup)
	      newgroup = *val2;
	    else
	      newgroup = error_mark_node;
	  }
      }
  return newgroup;
}


/* Add all references of SYMBOL that are defined into queue started by FIRST
   and linked by AUX pointer (unless they are already enqueued).
   Walk recursively inlined functions.  */

void
enqueue_references (symtab_node **first,
		    symtab_node *symbol)
{
  int i;
  struct ipa_ref *ref = NULL;

  for (i = 0; symbol->iterate_reference (i, ref); i++)
    {
      symtab_node *node = ref->referred->ultimate_alias_target ();

      /* Always keep thunks in same sections as target function.  */
      if (is_a <cgraph_node *>(node))
	node = dyn_cast <cgraph_node *> (node)->function_symbol ();
      if (!node->aux && node->definition)
	{
	   node->aux = *first;
	   *first = node;
	}
    }

  if (cgraph_node *cnode = dyn_cast <cgraph_node *> (symbol))
    {
      struct cgraph_edge *edge;

      for (edge = cnode->callees; edge; edge = edge->next_callee)
	if (!edge->inline_failed)
	  enqueue_references (first, edge->callee);
	else
	  {
	    symtab_node *node = edge->callee->ultimate_alias_target ();

	    /* Always keep thunks in same sections as target function.  */
	    if (is_a <cgraph_node *>(node))
	      node = dyn_cast <cgraph_node *> (node)->function_symbol ();
	    if (!node->aux && node->definition)
	      {
		 node->aux = *first;
		 *first = node;
	      }
	  }
    }
}

/* Set comdat group of SYMBOL to GROUP.
   Callback for for_node_and_aliases.  */

bool
set_comdat_group (symtab_node *symbol,
	          void *head_p)
{
  symtab_node *head = (symtab_node *)head_p;

  gcc_assert (!symbol->get_comdat_group ());
  if (symbol->real_symbol_p ())
    {
      symbol->set_comdat_group (head->get_comdat_group ());
      symbol->add_to_same_comdat_group (head);
    }
  return false;
}

/* Set comdat group of SYMBOL to GROUP.
   Callback for for_node_thunks_and_aliases.  */

bool
set_comdat_group_1 (cgraph_node *symbol,
		    void *head_p)
{
  return set_comdat_group (symbol, head_p);
}

/* The actual pass with the main dataflow loop.  */

static unsigned int
ipa_comdats (void)
{
  hash_map<symtab_node *, tree> map (251);
  hash_map<tree, symtab_node *> comdat_head_map (251);
  symtab_node *symbol;
  bool comdat_group_seen = false;
  symtab_node *first = (symtab_node *) (void *) 1;
  tree group;

  /* Start the dataflow by assigning comdat group to symbols that are in comdat
     groups already.  All other externally visible symbols must stay, we use
     ERROR_MARK_NODE as bottom for the propagation.  */

  FOR_EACH_DEFINED_SYMBOL (symbol)
    if (!symbol->real_symbol_p ())
      ;
    else if ((group = symbol->get_comdat_group ()) != NULL)
      {
        map.put (symbol, group);
        comdat_head_map.put (group, symbol);
	comdat_group_seen = true;

	/* Mark the symbol so we won't waste time visiting it for dataflow.  */
	symbol->aux = (symtab_node *) (void *) 1;
      }
    /* See symbols that cannot be privatized to comdats; that is externally
       visible symbols or otherwise used ones.  We also do not want to mangle
       user section names.  */
    else if (symbol->externally_visible
	     || symbol->force_output
	     || symbol->used_from_other_partition
	     || TREE_THIS_VOLATILE (symbol->decl)
	     || symbol->get_section ()
	     || (TREE_CODE (symbol->decl) == FUNCTION_DECL
		 && (DECL_STATIC_CONSTRUCTOR (symbol->decl)
		     || DECL_STATIC_DESTRUCTOR (symbol->decl))))
      {
	symtab_node *target = symbol->ultimate_alias_target ();

	/* Always keep thunks in same sections as target function.  */
	if (is_a <cgraph_node *>(target))
	  target = dyn_cast <cgraph_node *> (target)->function_symbol ();
	map.put (target, error_mark_node);

	/* Mark the symbol so we won't waste time visiting it for dataflow.  */
	symbol->aux = (symtab_node *) (void *) 1;
      }
    else
      {
	/* Enqueue symbol for dataflow.  */
        symbol->aux = first;
	first = symbol;
      }

  if (!comdat_group_seen)
    {
      FOR_EACH_DEFINED_SYMBOL (symbol)
        symbol->aux = NULL;
      return 0;
    }

  /* The actual dataflow.  */

  while (first != (void *) 1)
    {
      tree group = NULL;
      tree newgroup, *val;

      symbol = first;
      first = (symtab_node *)first->aux;

      /* Get current lattice value of SYMBOL.  */
      val = map.get (symbol);
      if (val)
	group = *val;

      /* If it is bottom, there is nothing to do; do not clear AUX
	 so we won't re-queue the symbol.  */
      if (group == error_mark_node)
	continue;

      newgroup = propagate_comdat_group (symbol, group, map);

      /* If nothing changed, proceed to next symbol.  */
      if (newgroup == group)
	{
	  symbol->aux = NULL;
	  continue;
	}

      /* Update lattice value and enqueue all references for re-visiting.  */
      gcc_assert (newgroup);
      if (val)
	*val = newgroup;
      else
	map.put (symbol, newgroup);
      enqueue_references (&first, symbol);

      /* We may need to revisit the symbol unless it is BOTTOM.  */
      if (newgroup != error_mark_node)
        symbol->aux = NULL;
    }

  /* Finally assign symbols to the sections.  */

  FOR_EACH_DEFINED_SYMBOL (symbol)
    {
      struct cgraph_node *fun;
      symbol->aux = NULL; 
      if (!symbol->get_comdat_group ()
	  && !symbol->alias
	  && (!(fun = dyn_cast <cgraph_node *> (symbol))
	      || !fun->thunk.thunk_p)
	  && symbol->real_symbol_p ())
	{
	  tree *val = map.get (symbol);

	  /* A NULL here means that SYMBOL is unreachable in the definition
	     of ipa-comdats. Either ipa-comdats is wrong about this or someone
	     forgot to cleanup and remove unreachable functions earlier.  */
	  gcc_assert (val);

	  tree group = *val;

	  if (group == error_mark_node)
	    continue;
	  if (dump_file)
	    {
	      fprintf (dump_file, "Localizing symbol\n");
	      symbol->dump (dump_file);
	      fprintf (dump_file, "To group: %s\n", IDENTIFIER_POINTER (group));
	    }
	  if (is_a <cgraph_node *> (symbol))
	   dyn_cast <cgraph_node *>(symbol)->call_for_symbol_thunks_and_aliases
		  (set_comdat_group_1,
		   *comdat_head_map.get (group),
		   true);
	  else
	   symbol->call_for_symbol_and_aliases
		  (set_comdat_group,
		   *comdat_head_map.get (group),
		   true);
	}
    }
  return 0;
}

namespace {

const pass_data pass_data_ipa_comdats =
{
  IPA_PASS, /* type */
  "comdats", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_IPA_COMDATS, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_ipa_comdats : public ipa_opt_pass_d
{
public:
  pass_ipa_comdats (gcc::context *ctxt)
    : ipa_opt_pass_d (pass_data_ipa_comdats, 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_comdats (); }

}; // class pass_ipa_comdats

bool
pass_ipa_comdats::gate (function *)
{
  return HAVE_COMDAT_GROUP;
}

} // anon namespace

ipa_opt_pass_d *
make_pass_ipa_comdats (gcc::context *ctxt)
{
  return new pass_ipa_comdats (ctxt);
}
