/* Interprocedural Identical Code Folding pass
   Copyright (C) 2014-2019 Free Software Foundation, Inc.

   Contributed by Jan Hubicka <hubicka@ucw.cz> and Martin Liska <mliska@suse.cz>

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/>.  */

/* Interprocedural Identical Code Folding for functions and
   read-only variables.

   The goal of this transformation is to discover functions and read-only
   variables which do have exactly the same semantics.

   In case of functions,
   we could either create a virtual clone or do a simple function wrapper
   that will call equivalent function. If the function is just locally visible,
   all function calls can be redirected. For read-only variables, we create
   aliases if possible.

   Optimization pass arranges as follows:
   1) All functions and read-only variables are visited and internal
      data structure, either sem_function or sem_variables is created.
   2) For every symbol from the previous step, VAR_DECL and FUNCTION_DECL are
      saved and matched to corresponding sem_items.
   3) These declaration are ignored for equality check and are solved
      by Value Numbering algorithm published by Alpert, Zadeck in 1992.
   4) We compute hash value for each symbol.
   5) Congruence classes are created based on hash value. If hash value are
      equal, equals function is called and symbols are deeply compared.
      We must prove that all SSA names, declarations and other items
      correspond.
   6) Value Numbering is executed for these classes. At the end of the process
      all symbol members in remaining classes can be merged.
   7) Merge operation creates alias in case of read-only variables. For
      callgraph node, we must decide if we can redirect local calls,
      create an alias or a thunk.

*/

#include "config.h"
#define INCLUDE_LIST
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "alloc-pool.h"
#include "tree-pass.h"
#include "ssa.h"
#include "cgraph.h"
#include "coverage.h"
#include "gimple-pretty-print.h"
#include "data-streamer.h"
#include "fold-const.h"
#include "calls.h"
#include "varasm.h"
#include "gimple-iterator.h"
#include "tree-cfg.h"
#include "symbol-summary.h"
#include "ipa-prop.h"
#include "ipa-fnsummary.h"
#include "except.h"
#include "attribs.h"
#include "print-tree.h"
#include "ipa-utils.h"
#include "ipa-icf-gimple.h"
#include "ipa-icf.h"
#include "stor-layout.h"
#include "dbgcnt.h"
#include "tree-vector-builder.h"

using namespace ipa_icf_gimple;

namespace ipa_icf {

/* Initialization and computation of symtab node hash, there data
   are propagated later on.  */

static sem_item_optimizer *optimizer = NULL;

/* Constructor.  */

symbol_compare_collection::symbol_compare_collection (symtab_node *node)
{
  m_references.create (0);
  m_interposables.create (0);

  ipa_ref *ref;

  if (is_a <varpool_node *> (node) && DECL_VIRTUAL_P (node->decl))
    return;

  for (unsigned i = 0; node->iterate_reference (i, ref); i++)
    {
      if (ref->address_matters_p ())
	m_references.safe_push (ref->referred);

      if (ref->referred->get_availability () <= AVAIL_INTERPOSABLE)
        {
	  if (ref->address_matters_p ())
	    m_references.safe_push (ref->referred);
	  else
	    m_interposables.safe_push (ref->referred);
	}
    }

  if (is_a <cgraph_node *> (node))
    {
      cgraph_node *cnode = dyn_cast <cgraph_node *> (node);

      for (cgraph_edge *e = cnode->callees; e; e = e->next_callee)
	if (e->callee->get_availability () <= AVAIL_INTERPOSABLE)
	  m_interposables.safe_push (e->callee);
    }
}

/* Constructor for key value pair, where _ITEM is key and _INDEX is a target.  */

sem_usage_pair::sem_usage_pair (sem_item *_item, unsigned int _index)
: item (_item), index (_index)
{
}

sem_item::sem_item (sem_item_type _type, bitmap_obstack *stack)
: type (_type), m_hash (-1), m_hash_set (false)
{
  setup (stack);
}

sem_item::sem_item (sem_item_type _type, symtab_node *_node,
		    bitmap_obstack *stack)
: type (_type), node (_node), m_hash (-1), m_hash_set (false)
{
  decl = node->decl;
  setup (stack);
}

/* Add reference to a semantic TARGET.  */

void
sem_item::add_reference (sem_item *target)
{
  refs.safe_push (target);
  unsigned index = refs.length ();
  target->usages.safe_push (new sem_usage_pair(this, index));
  bitmap_set_bit (target->usage_index_bitmap, index);
  refs_set.add (target->node);
}

/* Initialize internal data structures. Bitmap STACK is used for
   bitmap memory allocation process.  */

void
sem_item::setup (bitmap_obstack *stack)
{
  gcc_checking_assert (node);

  refs.create (0);
  tree_refs.create (0);
  usages.create (0);
  usage_index_bitmap = BITMAP_ALLOC (stack);
}

sem_item::~sem_item ()
{
  for (unsigned i = 0; i < usages.length (); i++)
    delete usages[i];

  refs.release ();
  tree_refs.release ();
  usages.release ();

  BITMAP_FREE (usage_index_bitmap);
}

/* Dump function for debugging purpose.  */

DEBUG_FUNCTION void
sem_item::dump (void)
{
  if (dump_file)
    {
      fprintf (dump_file, "[%s] %s (tree:%p)\n", type == FUNC ? "func" : "var",
	       node->dump_name (), (void *) node->decl);
      fprintf (dump_file, "  hash: %u\n", get_hash ());
      fprintf (dump_file, "  references: ");

      for (unsigned i = 0; i < refs.length (); i++)
	fprintf (dump_file, "%s%s ", refs[i]->node->name (),
		 i < refs.length() - 1 ? "," : "");

      fprintf (dump_file, "\n");
    }
}

/* Return true if target supports alias symbols.  */

bool
sem_item::target_supports_symbol_aliases_p (void)
{
#if !defined (ASM_OUTPUT_DEF) || (!defined(ASM_OUTPUT_WEAK_ALIAS) && !defined (ASM_WEAKEN_DECL))
  return false;
#else
  return true;
#endif
}

void sem_item::set_hash (hashval_t hash)
{
  m_hash = hash;
  m_hash_set = true;
}

hash_map<const_tree, hashval_t> sem_item::m_type_hash_cache;

/* Semantic function constructor that uses STACK as bitmap memory stack.  */

sem_function::sem_function (bitmap_obstack *stack)
: sem_item (FUNC, stack), m_checker (NULL), m_compared_func (NULL)
{
  bb_sizes.create (0);
  bb_sorted.create (0);
}

sem_function::sem_function (cgraph_node *node, bitmap_obstack *stack)
: sem_item (FUNC, node, stack), m_checker (NULL), m_compared_func (NULL)
{
  bb_sizes.create (0);
  bb_sorted.create (0);
}

sem_function::~sem_function ()
{
  for (unsigned i = 0; i < bb_sorted.length (); i++)
    delete (bb_sorted[i]);

  bb_sizes.release ();
  bb_sorted.release ();
}

/* Calculates hash value based on a BASIC_BLOCK.  */

hashval_t
sem_function::get_bb_hash (const sem_bb *basic_block)
{
  inchash::hash hstate;

  hstate.add_int (basic_block->nondbg_stmt_count);
  hstate.add_int (basic_block->edge_count);

  return hstate.end ();
}

/* References independent hash function.  */

hashval_t
sem_function::get_hash (void)
{
  if (!m_hash_set)
    {
      inchash::hash hstate;
      hstate.add_int (177454); /* Random number for function type.  */

      hstate.add_int (arg_count);
      hstate.add_int (cfg_checksum);
      hstate.add_int (gcode_hash);

      for (unsigned i = 0; i < bb_sorted.length (); i++)
	hstate.merge_hash (get_bb_hash (bb_sorted[i]));

      for (unsigned i = 0; i < bb_sizes.length (); i++)
	hstate.add_int (bb_sizes[i]);

      /* Add common features of declaration itself.  */
      if (DECL_FUNCTION_SPECIFIC_TARGET (decl))
        hstate.add_hwi
	 (cl_target_option_hash
	   (TREE_TARGET_OPTION (DECL_FUNCTION_SPECIFIC_TARGET (decl))));
      if (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl))
	hstate.add_hwi
	 (cl_optimization_hash
	   (TREE_OPTIMIZATION (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl))));
      hstate.add_flag (DECL_CXX_CONSTRUCTOR_P (decl));
      hstate.add_flag (DECL_CXX_DESTRUCTOR_P (decl));

      set_hash (hstate.end ());
    }

  return m_hash;
}

/* Compare properties of symbols N1 and N2 that does not affect semantics of
   symbol itself but affects semantics of its references from USED_BY (which
   may be NULL if it is unknown).  If comparsion is false, symbols
   can still be merged but any symbols referring them can't.

   If ADDRESS is true, do extra checking needed for IPA_REF_ADDR.

   TODO: We can also split attributes to those that determine codegen of
   a function body/variable constructor itself and those that are used when
   referring to it.  */

bool
sem_item::compare_referenced_symbol_properties (symtab_node *used_by,
						symtab_node *n1,
						symtab_node *n2,
						bool address)
{
  if (is_a <cgraph_node *> (n1))
    {
      /* Inline properties matters: we do now want to merge uses of inline
	 function to uses of normal function because inline hint would be lost.
	 We however can merge inline function to noinline because the alias
	 will keep its DECL_DECLARED_INLINE flag.

	 Also ignore inline flag when optimizing for size or when function
	 is known to not be inlinable.

	 TODO: the optimize_size checks can also be assumed to be true if
	 unit has no !optimize_size functions. */

      if ((!used_by || address || !is_a <cgraph_node *> (used_by)
	   || !opt_for_fn (used_by->decl, optimize_size))
	  && !opt_for_fn (n1->decl, optimize_size)
	  && n1->get_availability () > AVAIL_INTERPOSABLE
	  && (!DECL_UNINLINABLE (n1->decl) || !DECL_UNINLINABLE (n2->decl)))
	{
	  if (DECL_DISREGARD_INLINE_LIMITS (n1->decl)
	      != DECL_DISREGARD_INLINE_LIMITS (n2->decl))
	    return return_false_with_msg
		     ("DECL_DISREGARD_INLINE_LIMITS are different");

	  if (DECL_DECLARED_INLINE_P (n1->decl)
	      != DECL_DECLARED_INLINE_P (n2->decl))
	    return return_false_with_msg ("inline attributes are different");
	}

      if (DECL_IS_OPERATOR_NEW (n1->decl)
	  != DECL_IS_OPERATOR_NEW (n2->decl))
	return return_false_with_msg ("operator new flags are different");
    }

  /* Merging two definitions with a reference to equivalent vtables, but
     belonging to a different type may result in ipa-polymorphic-call analysis
     giving a wrong answer about the dynamic type of instance.  */
  if (is_a <varpool_node *> (n1))
    {
      if ((DECL_VIRTUAL_P (n1->decl) || DECL_VIRTUAL_P (n2->decl))
	  && (DECL_VIRTUAL_P (n1->decl) != DECL_VIRTUAL_P (n2->decl)
	      || !types_must_be_same_for_odr (DECL_CONTEXT (n1->decl),
					      DECL_CONTEXT (n2->decl)))
	  && (!used_by || !is_a <cgraph_node *> (used_by) || address
	      || opt_for_fn (used_by->decl, flag_devirtualize)))
	return return_false_with_msg
		 ("references to virtual tables cannot be merged");

      if (address && DECL_ALIGN (n1->decl) != DECL_ALIGN (n2->decl))
	return return_false_with_msg ("alignment mismatch");

      /* For functions we compare attributes in equals_wpa, because we do
	 not know what attributes may cause codegen differences, but for
	 variables just compare attributes for references - the codegen
	 for constructors is affected only by those attributes that we lower
	 to explicit representation (such as DECL_ALIGN or DECL_SECTION).  */
      if (!attribute_list_equal (DECL_ATTRIBUTES (n1->decl),
				 DECL_ATTRIBUTES (n2->decl)))
	return return_false_with_msg ("different var decl attributes");
      if (comp_type_attributes (TREE_TYPE (n1->decl),
				TREE_TYPE (n2->decl)) != 1)
	return return_false_with_msg ("different var type attributes");
    }

  /* When matching virtual tables, be sure to also match information
     relevant for polymorphic call analysis.  */
  if (used_by && is_a <varpool_node *> (used_by)
      && DECL_VIRTUAL_P (used_by->decl))
    {
      if (DECL_VIRTUAL_P (n1->decl) != DECL_VIRTUAL_P (n2->decl))
	return return_false_with_msg ("virtual flag mismatch");
      if (DECL_VIRTUAL_P (n1->decl) && is_a <cgraph_node *> (n1)
	  && (DECL_FINAL_P (n1->decl) != DECL_FINAL_P (n2->decl)))
	return return_false_with_msg ("final flag mismatch");
    }
  return true;
}

/* Hash properties that are compared by compare_referenced_symbol_properties. */

void
sem_item::hash_referenced_symbol_properties (symtab_node *ref,
					     inchash::hash &hstate,
					     bool address)
{
  if (is_a <cgraph_node *> (ref))
    {
      if ((type != FUNC || address || !opt_for_fn (decl, optimize_size))
	  && !opt_for_fn (ref->decl, optimize_size)
	  && !DECL_UNINLINABLE (ref->decl))
	{
	  hstate.add_flag (DECL_DISREGARD_INLINE_LIMITS (ref->decl));
	  hstate.add_flag (DECL_DECLARED_INLINE_P (ref->decl));
	}
      hstate.add_flag (DECL_IS_OPERATOR_NEW (ref->decl));
    }
  else if (is_a <varpool_node *> (ref))
    {
      hstate.add_flag (DECL_VIRTUAL_P (ref->decl));
      if (address)
	hstate.add_int (DECL_ALIGN (ref->decl));
    }
}


/* For a given symbol table nodes N1 and N2, we check that FUNCTION_DECLs
   point to a same function. Comparison can be skipped if IGNORED_NODES
   contains these nodes.  ADDRESS indicate if address is taken.  */

bool
sem_item::compare_symbol_references (
    hash_map <symtab_node *, sem_item *> &ignored_nodes,
    symtab_node *n1, symtab_node *n2, bool address)
{
  enum availability avail1, avail2;

  if (n1 == n2)
    return true;

  /* Never match variable and function.  */
  if (is_a <varpool_node *> (n1) != is_a <varpool_node *> (n2))
    return false;

  if (!compare_referenced_symbol_properties (node, n1, n2, address))
    return false;
  if (address && n1->equal_address_to (n2) == 1)
    return true;
  if (!address && n1->semantically_equivalent_p (n2))
    return true;

  n1 = n1->ultimate_alias_target (&avail1);
  n2 = n2->ultimate_alias_target (&avail2);

  if (avail1 > AVAIL_INTERPOSABLE && ignored_nodes.get (n1)
      && avail2 > AVAIL_INTERPOSABLE && ignored_nodes.get (n2))
    return true;

  return return_false_with_msg ("different references");
}

/* If cgraph edges E1 and E2 are indirect calls, verify that
   ECF flags are the same.  */

bool sem_function::compare_edge_flags (cgraph_edge *e1, cgraph_edge *e2)
{
  if (e1->indirect_info && e2->indirect_info)
    {
      int e1_flags = e1->indirect_info->ecf_flags;
      int e2_flags = e2->indirect_info->ecf_flags;

      if (e1_flags != e2_flags)
	return return_false_with_msg ("ICF flags are different");
    }
  else if (e1->indirect_info || e2->indirect_info)
    return false;

  return true;
}

/* Return true if parameter I may be used.  */

bool
sem_function::param_used_p (unsigned int i)
{
  if (ipa_node_params_sum == NULL)
    return true;

  struct ipa_node_params *parms_info = IPA_NODE_REF (get_node ());

  if (vec_safe_length (parms_info->descriptors) <= i)
    return true;

  return ipa_is_param_used (IPA_NODE_REF (get_node ()), i);
}

/* Perform additional check needed to match types function parameters that are
   used.  Unlike for normal decls it matters if type is TYPE_RESTRICT and we
   make an assumption that REFERENCE_TYPE parameters are always non-NULL.  */

bool
sem_function::compatible_parm_types_p (tree parm1, tree parm2)
{
  /* Be sure that parameters are TBAA compatible.  */
  if (!func_checker::compatible_types_p (parm1, parm2))
    return return_false_with_msg ("parameter type is not compatible");

  if (POINTER_TYPE_P (parm1)
      && (TYPE_RESTRICT (parm1) != TYPE_RESTRICT (parm2)))
    return return_false_with_msg ("argument restrict flag mismatch");

  /* nonnull_arg_p implies non-zero range to REFERENCE types.  */
  if (POINTER_TYPE_P (parm1)
      && TREE_CODE (parm1) != TREE_CODE (parm2)
      && opt_for_fn (decl, flag_delete_null_pointer_checks))
    return return_false_with_msg ("pointer wrt reference mismatch");

  return true;
}

/* Fast equality function based on knowledge known in WPA.  */

bool
sem_function::equals_wpa (sem_item *item,
			  hash_map <symtab_node *, sem_item *> &ignored_nodes)
{
  gcc_assert (item->type == FUNC);
  cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
  cgraph_node *cnode2 = dyn_cast <cgraph_node *> (item->node);

  m_compared_func = static_cast<sem_function *> (item);

  if (cnode->thunk.thunk_p != cnode2->thunk.thunk_p)
    return return_false_with_msg ("thunk_p mismatch");

  if (cnode->thunk.thunk_p)
    {
      if (cnode->thunk.fixed_offset != cnode2->thunk.fixed_offset)
        return return_false_with_msg ("thunk fixed_offset mismatch");
      if (cnode->thunk.virtual_value != cnode2->thunk.virtual_value)
        return return_false_with_msg ("thunk virtual_value mismatch");
      if (cnode->thunk.indirect_offset != cnode2->thunk.indirect_offset)
        return return_false_with_msg ("thunk indirect_offset mismatch");
      if (cnode->thunk.this_adjusting != cnode2->thunk.this_adjusting)
        return return_false_with_msg ("thunk this_adjusting mismatch");
      if (cnode->thunk.virtual_offset_p != cnode2->thunk.virtual_offset_p)
        return return_false_with_msg ("thunk virtual_offset_p mismatch");
    }

  /* Compare special function DECL attributes.  */
  if (DECL_FUNCTION_PERSONALITY (decl)
      != DECL_FUNCTION_PERSONALITY (item->decl))
    return return_false_with_msg ("function personalities are different");

  if (DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl)
       != DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (item->decl))
    return return_false_with_msg ("intrument function entry exit "
				  "attributes are different");

  if (DECL_NO_LIMIT_STACK (decl) != DECL_NO_LIMIT_STACK (item->decl))
    return return_false_with_msg ("no stack limit attributes are different");

  if (DECL_CXX_CONSTRUCTOR_P (decl) != DECL_CXX_CONSTRUCTOR_P (item->decl))
    return return_false_with_msg ("DECL_CXX_CONSTRUCTOR mismatch");

  if (DECL_CXX_DESTRUCTOR_P (decl) != DECL_CXX_DESTRUCTOR_P (item->decl))
    return return_false_with_msg ("DECL_CXX_DESTRUCTOR mismatch");

  /* TODO: pure/const flags mostly matters only for references, except for
     the fact that codegen takes LOOPING flag as a hint that loops are
     finite.  We may arrange the code to always pick leader that has least
     specified flags and then this can go into comparing symbol properties.  */
  if (flags_from_decl_or_type (decl) != flags_from_decl_or_type (item->decl))
    return return_false_with_msg ("decl_or_type flags are different");

  /* Do not match polymorphic constructors of different types.  They calls
     type memory location for ipa-polymorphic-call and we do not want
     it to get confused by wrong type.  */
  if (DECL_CXX_CONSTRUCTOR_P (decl)
      && TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
    {
      if (TREE_CODE (TREE_TYPE (item->decl)) != METHOD_TYPE)
        return return_false_with_msg ("DECL_CXX_CONSTURCTOR type mismatch");
      else if (!func_checker::compatible_polymorphic_types_p
		 (TYPE_METHOD_BASETYPE (TREE_TYPE (decl)),
		  TYPE_METHOD_BASETYPE (TREE_TYPE (item->decl)), false))
        return return_false_with_msg ("ctor polymorphic type mismatch");
    }

  /* Checking function TARGET and OPTIMIZATION flags.  */
  cl_target_option *tar1 = target_opts_for_fn (decl);
  cl_target_option *tar2 = target_opts_for_fn (item->decl);

  if (tar1 != tar2 && !cl_target_option_eq (tar1, tar2))
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "target flags difference");
	  cl_target_option_print_diff (dump_file, 2, tar1, tar2);
	}

      return return_false_with_msg ("Target flags are different");
    }

  cl_optimization *opt1 = opts_for_fn (decl);
  cl_optimization *opt2 = opts_for_fn (item->decl);

  if (opt1 != opt2 && !cl_optimization_option_eq (opt1, opt2))
    {
      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "optimization flags difference");
	  cl_optimization_print_diff (dump_file, 2, opt1, opt2);
	}

      return return_false_with_msg ("optimization flags are different");
    }

  /* Result type checking.  */
  if (!func_checker::compatible_types_p
	 (TREE_TYPE (TREE_TYPE (decl)),
	  TREE_TYPE (TREE_TYPE (m_compared_func->decl))))
    return return_false_with_msg ("result types are different");

  /* Checking types of arguments.  */
  tree list1 = TYPE_ARG_TYPES (TREE_TYPE (decl)),
       list2 = TYPE_ARG_TYPES (TREE_TYPE (m_compared_func->decl));
  for (unsigned i = 0; list1 && list2;
       list1 = TREE_CHAIN (list1), list2 = TREE_CHAIN (list2), i++)
    {
      tree parm1 = TREE_VALUE (list1);
      tree parm2 = TREE_VALUE (list2);

      /* This guard is here for function pointer with attributes (pr59927.c).  */
      if (!parm1 || !parm2)
	return return_false_with_msg ("NULL argument type");

      /* Verify that types are compatible to ensure that both functions
	 have same calling conventions.  */
      if (!types_compatible_p (parm1, parm2))
	return return_false_with_msg ("parameter types are not compatible");

      if (!param_used_p (i))
	continue;

      /* Perform additional checks for used parameters.  */
      if (!compatible_parm_types_p (parm1, parm2))
	return false;
    }

  if (list1 || list2)
    return return_false_with_msg ("Mismatched number of parameters");

  if (node->num_references () != item->node->num_references ())
    return return_false_with_msg ("different number of references");

  /* Checking function attributes.
     This is quadratic in number of attributes  */
  if (comp_type_attributes (TREE_TYPE (decl),
			    TREE_TYPE (item->decl)) != 1)
    return return_false_with_msg ("different type attributes");
  if (!attribute_list_equal (DECL_ATTRIBUTES (decl),
			     DECL_ATTRIBUTES (item->decl)))
    return return_false_with_msg ("different decl attributes");

  /* The type of THIS pointer type memory location for
     ipa-polymorphic-call-analysis.  */
  if (opt_for_fn (decl, flag_devirtualize)
      && (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
          || TREE_CODE (TREE_TYPE (item->decl)) == METHOD_TYPE)
      && param_used_p (0)
      && compare_polymorphic_p ())
    {
      if (TREE_CODE (TREE_TYPE (decl)) != TREE_CODE (TREE_TYPE (item->decl)))
	return return_false_with_msg ("METHOD_TYPE and FUNCTION_TYPE mismatch");
      if (!func_checker::compatible_polymorphic_types_p
	   (TYPE_METHOD_BASETYPE (TREE_TYPE (decl)),
	    TYPE_METHOD_BASETYPE (TREE_TYPE (item->decl)), false))
	return return_false_with_msg ("THIS pointer ODR type mismatch");
    }

  ipa_ref *ref = NULL, *ref2 = NULL;
  for (unsigned i = 0; node->iterate_reference (i, ref); i++)
    {
      item->node->iterate_reference (i, ref2);

      if (ref->use != ref2->use)
	return return_false_with_msg ("reference use mismatch");

      if (!compare_symbol_references (ignored_nodes, ref->referred,
				      ref2->referred,
				      ref->address_matters_p ()))
	return false;
    }

  cgraph_edge *e1 = dyn_cast <cgraph_node *> (node)->callees;
  cgraph_edge *e2 = dyn_cast <cgraph_node *> (item->node)->callees;

  while (e1 && e2)
    {
      if (!compare_symbol_references (ignored_nodes, e1->callee,
				      e2->callee, false))
	return false;
      if (!compare_edge_flags (e1, e2))
	return false;

      e1 = e1->next_callee;
      e2 = e2->next_callee;
    }

  if (e1 || e2)
    return return_false_with_msg ("different number of calls");

  e1 = dyn_cast <cgraph_node *> (node)->indirect_calls;
  e2 = dyn_cast <cgraph_node *> (item->node)->indirect_calls;

  while (e1 && e2)
    {
      if (!compare_edge_flags (e1, e2))
	return false;

      e1 = e1->next_callee;
      e2 = e2->next_callee;
    }

  if (e1 || e2)
    return return_false_with_msg ("different number of indirect calls");

  return true;
}

/* Update hash by address sensitive references. We iterate over all
   sensitive references (address_matters_p) and we hash ultime alias
   target of these nodes, which can improve a semantic item hash.

   Also hash in referenced symbols properties.  This can be done at any time
   (as the properties should not change), but it is convenient to do it here
   while we walk the references anyway.  */

void
sem_item::update_hash_by_addr_refs (hash_map <symtab_node *,
				    sem_item *> &m_symtab_node_map)
{
  ipa_ref* ref;
  inchash::hash hstate (get_hash ());

  for (unsigned i = 0; node->iterate_reference (i, ref); i++)
    {
      hstate.add_int (ref->use);
      hash_referenced_symbol_properties (ref->referred, hstate,
					 ref->use == IPA_REF_ADDR);
      if (ref->address_matters_p () || !m_symtab_node_map.get (ref->referred))
	hstate.add_int (ref->referred->ultimate_alias_target ()->order);
    }

  if (is_a <cgraph_node *> (node))
    {
      for (cgraph_edge *e = dyn_cast <cgraph_node *> (node)->callers; e;
	   e = e->next_caller)
	{
	  sem_item **result = m_symtab_node_map.get (e->callee);
	  hash_referenced_symbol_properties (e->callee, hstate, false);
	  if (!result)
	    hstate.add_int (e->callee->ultimate_alias_target ()->order);
	}
    }

  set_hash (hstate.end ());
}

/* Update hash by computed local hash values taken from different
   semantic items.
   TODO: stronger SCC based hashing would be desirable here.  */

void
sem_item::update_hash_by_local_refs (hash_map <symtab_node *,
				     sem_item *> &m_symtab_node_map)
{
  ipa_ref* ref;
  inchash::hash state (get_hash ());

  for (unsigned j = 0; node->iterate_reference (j, ref); j++)
    {
      sem_item **result = m_symtab_node_map.get (ref->referring);
      if (result)
	state.merge_hash ((*result)->get_hash ());
    }

  if (type == FUNC)
    {
      for (cgraph_edge *e = dyn_cast <cgraph_node *> (node)->callees; e;
	   e = e->next_callee)
	{
	  sem_item **result = m_symtab_node_map.get (e->caller);
	  if (result)
	    state.merge_hash ((*result)->get_hash ());
	}
    }

  global_hash = state.end ();
}

/* Returns true if the item equals to ITEM given as argument.  */

bool
sem_function::equals (sem_item *item,
		      hash_map <symtab_node *, sem_item *> &)
{
  gcc_assert (item->type == FUNC);
  bool eq = equals_private (item);

  if (m_checker != NULL)
    {
      delete m_checker;
      m_checker = NULL;
    }

  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file,
	     "Equals called for: %s:%s with result: %s\n\n",
	     node->dump_name (),
	     item->node->dump_name (),
	     eq ? "true" : "false");

  return eq;
}

/* Processes function equality comparison.  */

bool
sem_function::equals_private (sem_item *item)
{
  if (item->type != FUNC)
    return false;

  basic_block bb1, bb2;
  edge e1, e2;
  edge_iterator ei1, ei2;
  bool result = true;
  tree arg1, arg2;

  m_compared_func = static_cast<sem_function *> (item);

  gcc_assert (decl != item->decl);

  if (bb_sorted.length () != m_compared_func->bb_sorted.length ()
      || edge_count != m_compared_func->edge_count
      || cfg_checksum != m_compared_func->cfg_checksum)
    return return_false ();

  m_checker = new func_checker (decl, m_compared_func->decl,
				compare_polymorphic_p (),
				false,
				&refs_set,
				&m_compared_func->refs_set);
  arg1 = DECL_ARGUMENTS (decl);
  arg2 = DECL_ARGUMENTS (m_compared_func->decl);
  for (unsigned i = 0;
       arg1 && arg2; arg1 = DECL_CHAIN (arg1), arg2 = DECL_CHAIN (arg2), i++)
    {
      if (!types_compatible_p (TREE_TYPE (arg1), TREE_TYPE (arg2)))
	return return_false_with_msg ("argument types are not compatible");
      if (!param_used_p (i))
	continue;
      /* Perform additional checks for used parameters.  */
      if (!compatible_parm_types_p (TREE_TYPE (arg1), TREE_TYPE (arg2)))
	return false;
      if (!m_checker->compare_decl (arg1, arg2))
        return return_false ();
    }
  if (arg1 || arg2)
    return return_false_with_msg ("Mismatched number of arguments");

  if (!dyn_cast <cgraph_node *> (node)->has_gimple_body_p ())
    return true;

  /* Fill-up label dictionary.  */
  for (unsigned i = 0; i < bb_sorted.length (); ++i)
    {
      m_checker->parse_labels (bb_sorted[i]);
      m_checker->parse_labels (m_compared_func->bb_sorted[i]);
    }

  /* Checking all basic blocks.  */
  for (unsigned i = 0; i < bb_sorted.length (); ++i)
    if(!m_checker->compare_bb (bb_sorted[i], m_compared_func->bb_sorted[i]))
      return return_false();

  dump_message ("All BBs are equal\n");

  auto_vec <int> bb_dict;

  /* Basic block edges check.  */
  for (unsigned i = 0; i < bb_sorted.length (); ++i)
    {
      bb1 = bb_sorted[i]->bb;
      bb2 = m_compared_func->bb_sorted[i]->bb;

      ei2 = ei_start (bb2->preds);

      for (ei1 = ei_start (bb1->preds); ei_cond (ei1, &e1); ei_next (&ei1))
	{
	  ei_cond (ei2, &e2);

	  if (e1->flags != e2->flags)
	    return return_false_with_msg ("flags comparison returns false");

	  if (!bb_dict_test (&bb_dict, e1->src->index, e2->src->index))
	    return return_false_with_msg ("edge comparison returns false");

	  if (!bb_dict_test (&bb_dict, e1->dest->index, e2->dest->index))
	    return return_false_with_msg ("BB comparison returns false");

	  if (!m_checker->compare_edge (e1, e2))
	    return return_false_with_msg ("edge comparison returns false");

	  ei_next (&ei2);
	}
    }

  /* Basic block PHI nodes comparison.  */
  for (unsigned i = 0; i < bb_sorted.length (); i++)
    if (!compare_phi_node (bb_sorted[i]->bb, m_compared_func->bb_sorted[i]->bb))
      return return_false_with_msg ("PHI node comparison returns false");

  return result;
}

/* Set LOCAL_P of NODE to true if DATA is non-NULL.
   Helper for call_for_symbol_thunks_and_aliases.  */

static bool
set_local (cgraph_node *node, void *data)
{
  node->local.local = data != NULL;
  return false;
}

/* TREE_ADDRESSABLE of NODE to true.
   Helper for call_for_symbol_thunks_and_aliases.  */

static bool
set_addressable (varpool_node *node, void *)
{
  TREE_ADDRESSABLE (node->decl) = 1;
  return false;
}

/* Clear DECL_RTL of NODE. 
   Helper for call_for_symbol_thunks_and_aliases.  */

static bool
clear_decl_rtl (symtab_node *node, void *)
{
  SET_DECL_RTL (node->decl, NULL);
  return false;
}

/* Redirect all callers of N and its aliases to TO.  Remove aliases if
   possible.  Return number of redirections made.  */

static int
redirect_all_callers (cgraph_node *n, cgraph_node *to)
{
  int nredirected = 0;
  ipa_ref *ref;
  cgraph_edge *e = n->callers;

  while (e)
    {
      /* Redirecting thunks to interposable symbols or symbols in other sections
	 may not be supported by target output code.  Play safe for now and
	 punt on redirection.  */
      if (!e->caller->thunk.thunk_p)
	{
	  struct cgraph_edge *nexte = e->next_caller;
          e->redirect_callee (to);
	  e = nexte;
          nredirected++;
	}
      else
	e = e->next_callee;
    }
  for (unsigned i = 0; n->iterate_direct_aliases (i, ref);)
    {
      bool removed = false;
      cgraph_node *n_alias = dyn_cast <cgraph_node *> (ref->referring);

      if ((DECL_COMDAT_GROUP (n->decl)
	   && (DECL_COMDAT_GROUP (n->decl)
	       == DECL_COMDAT_GROUP (n_alias->decl)))
	  || (n_alias->get_availability () > AVAIL_INTERPOSABLE
	      && n->get_availability () > AVAIL_INTERPOSABLE))
	{
	  nredirected += redirect_all_callers (n_alias, to);
	  if (n_alias->can_remove_if_no_direct_calls_p ()
	      && !n_alias->call_for_symbol_and_aliases (cgraph_node::has_thunk_p,
							NULL, true)
	      && !n_alias->has_aliases_p ())
	    n_alias->remove ();
	}
      if (!removed)
	i++;
    }
  return nredirected;
}

/* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can
   be applied.  */

bool
sem_function::merge (sem_item *alias_item)
{
  gcc_assert (alias_item->type == FUNC);

  sem_function *alias_func = static_cast<sem_function *> (alias_item);

  cgraph_node *original = get_node ();
  cgraph_node *local_original = NULL;
  cgraph_node *alias = alias_func->get_node ();

  bool create_wrapper = false;
  bool create_alias = false;
  bool redirect_callers = false;
  bool remove = false;

  bool original_discardable = false;
  bool original_discarded = false;

  bool original_address_matters = original->address_matters_p ();
  bool alias_address_matters = alias->address_matters_p ();

  if (DECL_EXTERNAL (alias->decl))
    {
      if (dump_file)
	fprintf (dump_file, "Not unifying; alias is external.\n\n");
      return false;
    }

  if (DECL_NO_INLINE_WARNING_P (original->decl)
      != DECL_NO_INLINE_WARNING_P (alias->decl))
    {
      if (dump_file)
	fprintf (dump_file,
		 "Not unifying; "
		 "DECL_NO_INLINE_WARNING mismatch.\n\n");
      return false;
    }

  /* Do not attempt to mix functions from different user sections;
     we do not know what user intends with those.  */
  if (((DECL_SECTION_NAME (original->decl) && !original->implicit_section)
       || (DECL_SECTION_NAME (alias->decl) && !alias->implicit_section))
      && DECL_SECTION_NAME (original->decl) != DECL_SECTION_NAME (alias->decl))
    {
      if (dump_file)
	fprintf (dump_file,
		 "Not unifying; "
		 "original and alias are in different sections.\n\n");
      return false;
    }

  if (!original->in_same_comdat_group_p (alias)
      || original->comdat_local_p ())
    {
      if (dump_file)
	fprintf (dump_file,
		 "Not unifying; alias nor wrapper cannot be created; "
		 "across comdat group boundary\n\n");

      return false;
    }

  /* See if original is in a section that can be discarded if the main
     symbol is not used.  */

  if (original->can_be_discarded_p ())
    original_discardable = true;
  /* Also consider case where we have resolution info and we know that
     original's definition is not going to be used.  In this case we cannot
     create alias to original.  */
  if (node->resolution != LDPR_UNKNOWN
      && !decl_binds_to_current_def_p (node->decl))
    original_discardable = original_discarded = true;

  /* Creating a symtab alias is the optimal way to merge.
     It however cannot be used in the following cases:

     1) if ORIGINAL and ALIAS may be possibly compared for address equality.
     2) if ORIGINAL is in a section that may be discarded by linker or if
	it is an external functions where we cannot create an alias
	(ORIGINAL_DISCARDABLE)
     3) if target do not support symbol aliases.
     4) original and alias lie in different comdat groups.

     If we cannot produce alias, we will turn ALIAS into WRAPPER of ORIGINAL
     and/or redirect all callers from ALIAS to ORIGINAL.  */
  if ((original_address_matters && alias_address_matters)
      || (original_discardable
	  && (!DECL_COMDAT_GROUP (alias->decl)
	      || (DECL_COMDAT_GROUP (alias->decl)
		  != DECL_COMDAT_GROUP (original->decl))))
      || original_discarded
      || !sem_item::target_supports_symbol_aliases_p ()
      || DECL_COMDAT_GROUP (alias->decl) != DECL_COMDAT_GROUP (original->decl))
    {
      /* First see if we can produce wrapper.  */

      /* Symbol properties that matter for references must be preserved.
	 TODO: We can produce wrapper, but we need to produce alias of ORIGINAL
	 with proper properties.  */
      if (!sem_item::compare_referenced_symbol_properties (NULL, original, alias,
							   alias->address_taken))
        {
	  if (dump_file)
	    fprintf (dump_file,
		     "Wrapper cannot be created because referenced symbol "
		     "properties mismatch\n");
        }
      /* Do not turn function in one comdat group into wrapper to another
	 comdat group. Other compiler producing the body of the
	 another comdat group may make opossite decision and with unfortunate
	 linker choices this may close a loop.  */
      else if (DECL_COMDAT_GROUP (original->decl)
	       && DECL_COMDAT_GROUP (alias->decl)
	       && (DECL_COMDAT_GROUP (alias->decl)
		   != DECL_COMDAT_GROUP (original->decl)))
	{
	  if (dump_file)
	    fprintf (dump_file,
		     "Wrapper cannot be created because of COMDAT\n");
	}
      else if (DECL_STATIC_CHAIN (alias->decl)
	       || DECL_STATIC_CHAIN (original->decl))
        {
	  if (dump_file)
	    fprintf (dump_file,
		     "Cannot create wrapper of nested function.\n");
        }
      /* TODO: We can also deal with variadic functions never calling
	 VA_START.  */
      else if (stdarg_p (TREE_TYPE (alias->decl)))
	{
	  if (dump_file)
	    fprintf (dump_file,
		     "cannot create wrapper of stdarg function.\n");
	}
      else if (ipa_fn_summaries
	       && ipa_fn_summaries->get (alias) != NULL
	       && ipa_fn_summaries->get (alias)->self_size <= 2)
	{
	  if (dump_file)
	    fprintf (dump_file, "Wrapper creation is not "
		     "profitable (function is too small).\n");
	}
      /* If user paid attention to mark function noinline, assume it is
	 somewhat special and do not try to turn it into a wrapper that
	 cannot be undone by inliner.  */
      else if (lookup_attribute ("noinline", DECL_ATTRIBUTES (alias->decl)))
	{
	  if (dump_file)
	    fprintf (dump_file, "Wrappers are not created for noinline.\n");
	}
      else
        create_wrapper = true;

      /* We can redirect local calls in the case both alias and orignal
	 are not interposable.  */
      redirect_callers
	= alias->get_availability () > AVAIL_INTERPOSABLE
	  && original->get_availability () > AVAIL_INTERPOSABLE;
      /* TODO: We can redirect, but we need to produce alias of ORIGINAL
	 with proper properties.  */
      if (!sem_item::compare_referenced_symbol_properties (NULL, original, alias,
							   alias->address_taken))
	redirect_callers = false;

      if (!redirect_callers && !create_wrapper)
	{
	  if (dump_file)
	    fprintf (dump_file, "Not unifying; cannot redirect callers nor "
		     "produce wrapper\n\n");
	  return false;
	}

      /* Work out the symbol the wrapper should call.
	 If ORIGINAL is interposable, we need to call a local alias.
	 Also produce local alias (if possible) as an optimization.

	 Local aliases cannot be created inside comdat groups because that
	 prevents inlining.  */
      if (!original_discardable && !original->get_comdat_group ())
	{
	  local_original
	    = dyn_cast <cgraph_node *> (original->noninterposable_alias ());
	  if (!local_original
	      && original->get_availability () > AVAIL_INTERPOSABLE)
	    local_original = original;
	}
      /* If we cannot use local alias, fallback to the original
	 when possible.  */
      else if (original->get_availability () > AVAIL_INTERPOSABLE)
	local_original = original;

      /* If original is COMDAT local, we cannot really redirect calls outside
	 of its comdat group to it.  */
      if (original->comdat_local_p ())
        redirect_callers = false;
      if (!local_original)
	{
	  if (dump_file)
	    fprintf (dump_file, "Not unifying; "
		     "cannot produce local alias.\n\n");
	  return false;
	}

      if (!redirect_callers && !create_wrapper)
	{
	  if (dump_file)
	    fprintf (dump_file, "Not unifying; "
		     "cannot redirect callers nor produce a wrapper\n\n");
	  return false;
	}
      if (!create_wrapper
	  && !alias->call_for_symbol_and_aliases (cgraph_node::has_thunk_p,
						  NULL, true)
	  && !alias->can_remove_if_no_direct_calls_p ())
	{
	  if (dump_file)
	    fprintf (dump_file, "Not unifying; cannot make wrapper and "
		     "function has other uses than direct calls\n\n");
	  return false;
	}
    }
  else
    create_alias = true;

  if (redirect_callers)
    {
      int nredirected = redirect_all_callers (alias, local_original);

      if (nredirected)
	{
	  alias->icf_merged = true;
	  local_original->icf_merged = true;

	  if (dump_file && nredirected)
	    fprintf (dump_file, "%i local calls have been "
		     "redirected.\n", nredirected);
	}

      /* If all callers was redirected, do not produce wrapper.  */
      if (alias->can_remove_if_no_direct_calls_p ()
	  && !DECL_VIRTUAL_P (alias->decl)
	  && !alias->has_aliases_p ())
	{
	  create_wrapper = false;
	  remove = true;
	}
      gcc_assert (!create_alias);
    }
  else if (create_alias)
    {
      alias->icf_merged = true;

      /* Remove the function's body.  */
      ipa_merge_profiles (original, alias);
      alias->release_body (true);
      alias->reset ();
      /* Notice global symbol possibly produced RTL.  */
      ((symtab_node *)alias)->call_for_symbol_and_aliases (clear_decl_rtl,
							   NULL, true);

      /* Create the alias.  */
      cgraph_node::create_alias (alias_func->decl, decl);
      alias->resolve_alias (original);

      original->call_for_symbol_thunks_and_aliases
	 (set_local, (void *)(size_t) original->local_p (), true);

      if (dump_file)
	fprintf (dump_file, "Unified; Function alias has been created.\n\n");
    }
  if (create_wrapper)
    {
      gcc_assert (!create_alias);
      alias->icf_merged = true;
      local_original->icf_merged = true;

      /* FIXME update local_original counts.  */
      ipa_merge_profiles (original, alias, true);
      alias->create_wrapper (local_original);

      if (dump_file)
	fprintf (dump_file, "Unified; Wrapper has been created.\n\n");
    }

  /* It's possible that redirection can hit thunks that block
     redirection opportunities.  */
  gcc_assert (alias->icf_merged || remove || redirect_callers);
  original->icf_merged = true;

  /* We use merged flag to track cases where COMDAT function is known to be
     compatible its callers.  If we merged in non-COMDAT, we need to give up
     on this optimization.  */
  if (original->merged_comdat && !alias->merged_comdat)
    {
      if (dump_file)
	fprintf (dump_file, "Dropping merged_comdat flag.\n\n");
      if (local_original)
        local_original->merged_comdat = false;
      original->merged_comdat = false;
    }

  if (remove)
    {
      ipa_merge_profiles (original, alias);
      alias->release_body ();
      alias->reset ();
      alias->body_removed = true;
      alias->icf_merged = true;
      if (dump_file)
	fprintf (dump_file, "Unified; Function body was removed.\n");
    }

  return true;
}

/* Semantic item initialization function.  */

void
sem_function::init (void)
{
  if (in_lto_p)
    get_node ()->get_untransformed_body ();

  tree fndecl = node->decl;
  function *func = DECL_STRUCT_FUNCTION (fndecl);

  gcc_assert (func);
  gcc_assert (SSANAMES (func));

  ssa_names_size = SSANAMES (func)->length ();
  node = node;

  decl = fndecl;
  region_tree = func->eh->region_tree;

  /* iterating all function arguments.  */
  arg_count = count_formal_params (fndecl);

  edge_count = n_edges_for_fn (func);
  cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
  if (!cnode->thunk.thunk_p)
    {
      cfg_checksum = coverage_compute_cfg_checksum (func);

      inchash::hash hstate;

      basic_block bb;
      FOR_EACH_BB_FN (bb, func)
      {
	unsigned nondbg_stmt_count = 0;

	edge e;
	for (edge_iterator ei = ei_start (bb->preds); ei_cond (ei, &e);
	     ei_next (&ei))
	  cfg_checksum = iterative_hash_host_wide_int (e->flags,
			 cfg_checksum);

	for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
	     gsi_next (&gsi))
	  {
	    gimple *stmt = gsi_stmt (gsi);

	    if (gimple_code (stmt) != GIMPLE_DEBUG
		&& gimple_code (stmt) != GIMPLE_PREDICT)
	      {
		hash_stmt (stmt, hstate);
		nondbg_stmt_count++;
	      }
	  }

	hstate.commit_flag ();
	gcode_hash = hstate.end ();
	bb_sizes.safe_push (nondbg_stmt_count);

	/* Inserting basic block to hash table.  */
	sem_bb *semantic_bb = new sem_bb (bb, nondbg_stmt_count,
					  EDGE_COUNT (bb->preds)
					  + EDGE_COUNT (bb->succs));

	bb_sorted.safe_push (semantic_bb);
      }
    }
  else
    {
      cfg_checksum = 0;
      inchash::hash hstate;
      hstate.add_hwi (cnode->thunk.fixed_offset);
      hstate.add_hwi (cnode->thunk.virtual_value);
      hstate.add_flag (cnode->thunk.this_adjusting);
      hstate.add_flag (cnode->thunk.virtual_offset_p);
      gcode_hash = hstate.end ();
    }
}

/* Accumulate to HSTATE a hash of expression EXP.
   Identical to inchash::add_expr, but guaranteed to be stable across LTO
   and DECL equality classes.  */

void
sem_item::add_expr (const_tree exp, inchash::hash &hstate)
{
  if (exp == NULL_TREE)
    {
      hstate.merge_hash (0);
      return;
    }

  /* Handled component can be matched in a cureful way proving equivalence
     even if they syntactically differ.  Just skip them.  */
  STRIP_NOPS (exp);
  while (handled_component_p (exp))
    exp = TREE_OPERAND (exp, 0);

  enum tree_code code = TREE_CODE (exp);
  hstate.add_int (code);

  switch (code)
    {
    /* Use inchash::add_expr for everything that is LTO stable.  */
    case VOID_CST:
    case INTEGER_CST:
    case REAL_CST:
    case FIXED_CST:
    case STRING_CST:
    case COMPLEX_CST:
    case VECTOR_CST:
      inchash::add_expr (exp, hstate);
      break;
    case CONSTRUCTOR:
      {
	unsigned HOST_WIDE_INT idx;
	tree value;

	hstate.add_hwi (int_size_in_bytes (TREE_TYPE (exp)));

	FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, value)
	  if (value)
	    add_expr (value, hstate);
	break;
      }
    case ADDR_EXPR:
    case FDESC_EXPR:
      add_expr (get_base_address (TREE_OPERAND (exp, 0)), hstate);
      break;
    case SSA_NAME:
    case VAR_DECL:
    case CONST_DECL:
    case PARM_DECL:
      hstate.add_hwi (int_size_in_bytes (TREE_TYPE (exp)));
      break;
    case MEM_REF:
    case POINTER_PLUS_EXPR:
    case MINUS_EXPR:
    case RANGE_EXPR:
      add_expr (TREE_OPERAND (exp, 0), hstate);
      add_expr (TREE_OPERAND (exp, 1), hstate);
      break;
    case PLUS_EXPR:
      {
	inchash::hash one, two;
	add_expr (TREE_OPERAND (exp, 0), one);
	add_expr (TREE_OPERAND (exp, 1), two);
	hstate.add_commutative (one, two);
      }
      break;
    CASE_CONVERT:
      hstate.add_hwi (int_size_in_bytes (TREE_TYPE (exp)));
      return add_expr (TREE_OPERAND (exp, 0), hstate);
    default:
      break;
    }
}

/* Accumulate to HSTATE a hash of type t.
   TYpes that may end up being compatible after LTO type merging needs to have
   the same hash.  */

void
sem_item::add_type (const_tree type, inchash::hash &hstate)
{
  if (type == NULL_TREE)
    {
      hstate.merge_hash (0);
      return;
    }

  type = TYPE_MAIN_VARIANT (type);

  hstate.add_int (TYPE_MODE (type));

  if (TREE_CODE (type) == COMPLEX_TYPE)
    {
      hstate.add_int (COMPLEX_TYPE);
      sem_item::add_type (TREE_TYPE (type), hstate);
    }
  else if (INTEGRAL_TYPE_P (type))
    {
      hstate.add_int (INTEGER_TYPE);
      hstate.add_flag (TYPE_UNSIGNED (type));
      hstate.add_int (TYPE_PRECISION (type));
    }
  else if (VECTOR_TYPE_P (type))
    {
      hstate.add_int (VECTOR_TYPE);
      hstate.add_int (TYPE_PRECISION (type));
      sem_item::add_type (TREE_TYPE (type), hstate);
    }
  else if (TREE_CODE (type) == ARRAY_TYPE)
    {
      hstate.add_int (ARRAY_TYPE);
      /* Do not hash size, so complete and incomplete types can match.  */
      sem_item::add_type (TREE_TYPE (type), hstate);
    }
  else if (RECORD_OR_UNION_TYPE_P (type))
    {
      /* Incomplete types must be skipped here.  */
      if (!COMPLETE_TYPE_P (type))
	{
	  hstate.add_int (RECORD_TYPE);
	  return;
	}

      hashval_t *val = m_type_hash_cache.get (type);

      if (!val)
	{
	  inchash::hash hstate2;
	  unsigned nf;
	  tree f;
	  hashval_t hash;

	  hstate2.add_int (RECORD_TYPE);
	  for (f = TYPE_FIELDS (type), nf = 0; f; f = TREE_CHAIN (f))
	    if (TREE_CODE (f) == FIELD_DECL)
	      {
		add_type (TREE_TYPE (f), hstate2);
		nf++;
	      }

	  hstate2.add_int (nf);
	  hash = hstate2.end ();
	  hstate.add_hwi (hash);
	  m_type_hash_cache.put (type, hash);
	}
      else
        hstate.add_hwi (*val);
    }
}

/* Improve accumulated hash for HSTATE based on a gimple statement STMT.  */

void
sem_function::hash_stmt (gimple *stmt, inchash::hash &hstate)
{
  enum gimple_code code = gimple_code (stmt);

  hstate.add_int (code);

  switch (code)
    {
    case GIMPLE_SWITCH:
      add_expr (gimple_switch_index (as_a <gswitch *> (stmt)), hstate);
      break;
    case GIMPLE_ASSIGN:
      hstate.add_int (gimple_assign_rhs_code (stmt));
      if (commutative_tree_code (gimple_assign_rhs_code (stmt))
	  || commutative_ternary_tree_code (gimple_assign_rhs_code (stmt)))
	{
	  inchash::hash one, two;

	  add_expr (gimple_assign_rhs1 (stmt), one);
	  add_type (TREE_TYPE (gimple_assign_rhs1 (stmt)), one);
	  add_expr (gimple_assign_rhs2 (stmt), two);
	  hstate.add_commutative (one, two);
	  if (commutative_ternary_tree_code (gimple_assign_rhs_code (stmt)))
	    {
	      add_expr (gimple_assign_rhs3 (stmt), hstate);
	      add_type (TREE_TYPE (gimple_assign_rhs3 (stmt)), hstate);
	    }
	  add_expr (gimple_assign_lhs (stmt), hstate);
	  add_type (TREE_TYPE (gimple_assign_lhs (stmt)), two);
	  break;
	}
      /* fall through */
    case GIMPLE_CALL:
    case GIMPLE_ASM:
    case GIMPLE_COND:
    case GIMPLE_GOTO:
    case GIMPLE_RETURN:
      /* All these statements are equivalent if their operands are.  */
      for (unsigned i = 0; i < gimple_num_ops (stmt); ++i)
	{
	  add_expr (gimple_op (stmt, i), hstate);
	  if (gimple_op (stmt, i))
	    add_type (TREE_TYPE (gimple_op (stmt, i)), hstate);
	}
      /* Consider nocf_check attribute in hash as it affects code
 	 generation.  */
      if (code == GIMPLE_CALL
	  && flag_cf_protection & CF_BRANCH)
	hstate.add_flag (gimple_call_nocf_check_p (as_a <gcall *> (stmt)));
    default:
      break;
    }
}


/* Return true if polymorphic comparison must be processed.  */

bool
sem_function::compare_polymorphic_p (void)
{
  struct cgraph_edge *e;

  if (!opt_for_fn (get_node ()->decl, flag_devirtualize))
    return false;
  if (get_node ()->indirect_calls != NULL)
    return true;
  /* TODO: We can do simple propagation determining what calls may lead to
     a polymorphic call.  */
  for (e = get_node ()->callees; e; e = e->next_callee)
    if (e->callee->definition
	&& opt_for_fn (e->callee->decl, flag_devirtualize))
      return true;
  return false;
}

/* For a given call graph NODE, the function constructs new
   semantic function item.  */

sem_function *
sem_function::parse (cgraph_node *node, bitmap_obstack *stack)
{
  tree fndecl = node->decl;
  function *func = DECL_STRUCT_FUNCTION (fndecl);

  if (!func || (!node->has_gimple_body_p () && !node->thunk.thunk_p))
    return NULL;

  if (lookup_attribute_by_prefix ("omp ", DECL_ATTRIBUTES (node->decl)) != NULL)
    return NULL;

  if (lookup_attribute_by_prefix ("oacc ",
				  DECL_ATTRIBUTES (node->decl)) != NULL)
    return NULL;

  /* PR ipa/70306.  */
  if (DECL_STATIC_CONSTRUCTOR (node->decl)
      || DECL_STATIC_DESTRUCTOR (node->decl))
    return NULL;

  sem_function *f = new sem_function (node, stack);

  f->init ();

  return f;
}

/* For given basic blocks BB1 and BB2 (from functions FUNC1 and FUNC),
   return true if phi nodes are semantically equivalent in these blocks .  */

bool
sem_function::compare_phi_node (basic_block bb1, basic_block bb2)
{
  gphi_iterator si1, si2;
  gphi *phi1, *phi2;
  unsigned size1, size2, i;
  tree t1, t2;
  edge e1, e2;

  gcc_assert (bb1 != NULL);
  gcc_assert (bb2 != NULL);

  si2 = gsi_start_phis (bb2);
  for (si1 = gsi_start_phis (bb1); !gsi_end_p (si1);
       gsi_next (&si1))
    {
      gsi_next_nonvirtual_phi (&si1);
      gsi_next_nonvirtual_phi (&si2);

      if (gsi_end_p (si1) && gsi_end_p (si2))
	break;

      if (gsi_end_p (si1) || gsi_end_p (si2))
	return return_false();

      phi1 = si1.phi ();
      phi2 = si2.phi ();

      tree phi_result1 = gimple_phi_result (phi1);
      tree phi_result2 = gimple_phi_result (phi2);

      if (!m_checker->compare_operand (phi_result1, phi_result2))
	return return_false_with_msg ("PHI results are different");

      size1 = gimple_phi_num_args (phi1);
      size2 = gimple_phi_num_args (phi2);

      if (size1 != size2)
	return return_false ();

      for (i = 0; i < size1; ++i)
	{
	  t1 = gimple_phi_arg (phi1, i)->def;
	  t2 = gimple_phi_arg (phi2, i)->def;

	  if (!m_checker->compare_operand (t1, t2))
	    return return_false ();

	  e1 = gimple_phi_arg_edge (phi1, i);
	  e2 = gimple_phi_arg_edge (phi2, i);

	  if (!m_checker->compare_edge (e1, e2))
	    return return_false ();
	}

      gsi_next (&si2);
    }

  return true;
}

/* Returns true if tree T can be compared as a handled component.  */

bool
sem_function::icf_handled_component_p (tree t)
{
  tree_code tc = TREE_CODE (t);

  return (handled_component_p (t)
	  || tc == ADDR_EXPR || tc == MEM_REF || tc == OBJ_TYPE_REF);
}

/* Basic blocks dictionary BB_DICT returns true if SOURCE index BB
   corresponds to TARGET.  */

bool
sem_function::bb_dict_test (vec<int> *bb_dict, int source, int target)
{
  source++;
  target++;

  if (bb_dict->length () <= (unsigned)source)
    bb_dict->safe_grow_cleared (source + 1);

  if ((*bb_dict)[source] == 0)
    {
      (*bb_dict)[source] = target;
      return true;
    }
  else
    return (*bb_dict)[source] == target;
}

sem_variable::sem_variable (bitmap_obstack *stack): sem_item (VAR, stack)
{
}

sem_variable::sem_variable (varpool_node *node, bitmap_obstack *stack)
: sem_item (VAR, node, stack)
{
  gcc_checking_assert (node);
  gcc_checking_assert (get_node ());
}

/* Fast equality function based on knowledge known in WPA.  */

bool
sem_variable::equals_wpa (sem_item *item,
			  hash_map <symtab_node *, sem_item *> &ignored_nodes)
{
  gcc_assert (item->type == VAR);

  if (node->num_references () != item->node->num_references ())
    return return_false_with_msg ("different number of references");

  if (DECL_TLS_MODEL (decl) || DECL_TLS_MODEL (item->decl))
    return return_false_with_msg ("TLS model");

  /* DECL_ALIGN is safe to merge, because we will always chose the largest
     alignment out of all aliases.  */

  if (DECL_VIRTUAL_P (decl) != DECL_VIRTUAL_P (item->decl))
    return return_false_with_msg ("Virtual flag mismatch");

  if (DECL_SIZE (decl) != DECL_SIZE (item->decl)
      && ((!DECL_SIZE (decl) || !DECL_SIZE (item->decl))
	  || !operand_equal_p (DECL_SIZE (decl),
			       DECL_SIZE (item->decl), OEP_ONLY_CONST)))
    return return_false_with_msg ("size mismatch");

  /* Do not attempt to mix data from different user sections;
     we do not know what user intends with those.  */
  if (((DECL_SECTION_NAME (decl) && !node->implicit_section)
       || (DECL_SECTION_NAME (item->decl) && !item->node->implicit_section))
      && DECL_SECTION_NAME (decl) != DECL_SECTION_NAME (item->decl))
    return return_false_with_msg ("user section mismatch");

  if (DECL_IN_TEXT_SECTION (decl) != DECL_IN_TEXT_SECTION (item->decl))
    return return_false_with_msg ("text section");

  ipa_ref *ref = NULL, *ref2 = NULL;
  for (unsigned i = 0; node->iterate_reference (i, ref); i++)
    {
      item->node->iterate_reference (i, ref2);

      if (ref->use != ref2->use)
	return return_false_with_msg ("reference use mismatch");

      if (!compare_symbol_references (ignored_nodes,
				      ref->referred, ref2->referred,
				      ref->address_matters_p ()))
	return false;
    }

  return true;
}

/* Returns true if the item equals to ITEM given as argument.  */

bool
sem_variable::equals (sem_item *item,
		      hash_map <symtab_node *, sem_item *> &)
{
  gcc_assert (item->type == VAR);
  bool ret;

  if (DECL_INITIAL (decl) == error_mark_node && in_lto_p)
    dyn_cast <varpool_node *>(node)->get_constructor ();
  if (DECL_INITIAL (item->decl) == error_mark_node && in_lto_p)
    dyn_cast <varpool_node *>(item->node)->get_constructor ();

  /* As seen in PR ipa/65303 we have to compare variables types.  */
  if (!func_checker::compatible_types_p (TREE_TYPE (decl),
					 TREE_TYPE (item->decl)))
    return return_false_with_msg ("variables types are different");

  ret = sem_variable::equals (DECL_INITIAL (decl),
			      DECL_INITIAL (item->node->decl));
  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file,
	     "Equals called for vars: %s:%s with result: %s\n\n",
	     node->dump_name (), item->node->dump_name (),
	     ret ? "true" : "false");

  return ret;
}

/* Compares trees T1 and T2 for semantic equality.  */

bool
sem_variable::equals (tree t1, tree t2)
{
  if (!t1 || !t2)
    return return_with_debug (t1 == t2);
  if (t1 == t2)
    return true;
  tree_code tc1 = TREE_CODE (t1);
  tree_code tc2 = TREE_CODE (t2);

  if (tc1 != tc2)
    return return_false_with_msg ("TREE_CODE mismatch");

  switch (tc1)
    {
    case CONSTRUCTOR:
      {
	vec<constructor_elt, va_gc> *v1, *v2;
	unsigned HOST_WIDE_INT idx;

	enum tree_code typecode = TREE_CODE (TREE_TYPE (t1));
	if (typecode != TREE_CODE (TREE_TYPE (t2)))
	  return return_false_with_msg ("constructor type mismatch");

	if (typecode == ARRAY_TYPE)
	  {
	    HOST_WIDE_INT size_1 = int_size_in_bytes (TREE_TYPE (t1));
	    /* For arrays, check that the sizes all match.  */
	    if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2))
		|| size_1 == -1
		|| size_1 != int_size_in_bytes (TREE_TYPE (t2)))
	      return return_false_with_msg ("constructor array size mismatch");
	  }
	else if (!func_checker::compatible_types_p (TREE_TYPE (t1),
						    TREE_TYPE (t2)))
	  return return_false_with_msg ("constructor type incompatible");

	v1 = CONSTRUCTOR_ELTS (t1);
	v2 = CONSTRUCTOR_ELTS (t2);
	if (vec_safe_length (v1) != vec_safe_length (v2))
	  return return_false_with_msg ("constructor number of elts mismatch");

	for (idx = 0; idx < vec_safe_length (v1); ++idx)
	  {
	    constructor_elt *c1 = &(*v1)[idx];
	    constructor_elt *c2 = &(*v2)[idx];

	    /* Check that each value is the same...  */
	    if (!sem_variable::equals (c1->value, c2->value))
	      return false;
	    /* ... and that they apply to the same fields!  */
	    if (!sem_variable::equals (c1->index, c2->index))
	      return false;
	  }
	return true;
      }
    case MEM_REF:
      {
	tree x1 = TREE_OPERAND (t1, 0);
	tree x2 = TREE_OPERAND (t2, 0);
	tree y1 = TREE_OPERAND (t1, 1);
	tree y2 = TREE_OPERAND (t2, 1);

	if (!func_checker::compatible_types_p (TREE_TYPE (x1), TREE_TYPE (x2)))
	  return return_false ();

	/* Type of the offset on MEM_REF does not matter.  */
	return return_with_debug (sem_variable::equals (x1, x2)
			          && known_eq (wi::to_poly_offset (y1),
					       wi::to_poly_offset (y2)));
      }
    case ADDR_EXPR:
    case FDESC_EXPR:
      {
	tree op1 = TREE_OPERAND (t1, 0);
	tree op2 = TREE_OPERAND (t2, 0);
	return sem_variable::equals (op1, op2);
      }
    /* References to other vars/decls are compared using ipa-ref.  */
    case FUNCTION_DECL:
    case VAR_DECL:
      if (decl_in_symtab_p (t1) && decl_in_symtab_p (t2))
	return true;
      return return_false_with_msg ("Declaration mismatch");
    case CONST_DECL:
      /* TODO: We can check CONST_DECL by its DECL_INITIAL, but for that we
	 need to process its VAR/FUNCTION references without relying on ipa-ref
	 compare.  */
    case FIELD_DECL:
    case LABEL_DECL:
      return return_false_with_msg ("Declaration mismatch");
    case INTEGER_CST:
      /* Integer constants are the same only if the same width of type.  */
      if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2)))
        return return_false_with_msg ("INTEGER_CST precision mismatch");
      if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2)))
        return return_false_with_msg ("INTEGER_CST mode mismatch");
      return return_with_debug (tree_int_cst_equal (t1, t2));
    case STRING_CST:
      if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2)))
        return return_false_with_msg ("STRING_CST mode mismatch");
      if (TREE_STRING_LENGTH (t1) != TREE_STRING_LENGTH (t2))
	return return_false_with_msg ("STRING_CST length mismatch");
      if (memcmp (TREE_STRING_POINTER (t1), TREE_STRING_POINTER (t2),
		    TREE_STRING_LENGTH (t1)))
	return return_false_with_msg ("STRING_CST mismatch");
      return true;
    case FIXED_CST:
      /* Fixed constants are the same only if the same width of type.  */
      if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2)))
        return return_false_with_msg ("FIXED_CST precision mismatch");

      return return_with_debug (FIXED_VALUES_IDENTICAL (TREE_FIXED_CST (t1),
							TREE_FIXED_CST (t2)));
    case COMPLEX_CST:
      return (sem_variable::equals (TREE_REALPART (t1), TREE_REALPART (t2))
	      && sem_variable::equals (TREE_IMAGPART (t1), TREE_IMAGPART (t2)));
    case REAL_CST:
      /* Real constants are the same only if the same width of type.  */
      if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2)))
        return return_false_with_msg ("REAL_CST precision mismatch");
      return return_with_debug (real_identical (&TREE_REAL_CST (t1),
						&TREE_REAL_CST (t2)));
    case VECTOR_CST:
      {
	if (maybe_ne (VECTOR_CST_NELTS (t1), VECTOR_CST_NELTS (t2)))
	  return return_false_with_msg ("VECTOR_CST nelts mismatch");

	unsigned int count
	  = tree_vector_builder::binary_encoded_nelts (t1, t2);
	for (unsigned int i = 0; i < count; ++i)
	  if (!sem_variable::equals (VECTOR_CST_ENCODED_ELT (t1, i),
				     VECTOR_CST_ENCODED_ELT (t2, i)))
	    return false;

	return true;
      }
    case ARRAY_REF:
    case ARRAY_RANGE_REF:
      {
	tree x1 = TREE_OPERAND (t1, 0);
	tree x2 = TREE_OPERAND (t2, 0);
	tree y1 = TREE_OPERAND (t1, 1);
	tree y2 = TREE_OPERAND (t2, 1);

	if (!sem_variable::equals (x1, x2) || !sem_variable::equals (y1, y2))
	  return false;
	if (!sem_variable::equals (array_ref_low_bound (t1),
				   array_ref_low_bound (t2)))
	  return false;
        if (!sem_variable::equals (array_ref_element_size (t1),
			           array_ref_element_size (t2)))
	  return false;
	return true;
      }
     
    case COMPONENT_REF:
    case POINTER_PLUS_EXPR:
    case PLUS_EXPR:
    case MINUS_EXPR:
    case RANGE_EXPR:
      {
	tree x1 = TREE_OPERAND (t1, 0);
	tree x2 = TREE_OPERAND (t2, 0);
	tree y1 = TREE_OPERAND (t1, 1);
	tree y2 = TREE_OPERAND (t2, 1);

	return sem_variable::equals (x1, x2) && sem_variable::equals (y1, y2);
      }

    CASE_CONVERT:
    case VIEW_CONVERT_EXPR:
      if (!func_checker::compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2)))
	  return return_false ();
      return sem_variable::equals (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
    case ERROR_MARK:
      return return_false_with_msg ("ERROR_MARK");
    default:
      return return_false_with_msg ("Unknown TREE code reached");
    }
}

/* Parser function that visits a varpool NODE.  */

sem_variable *
sem_variable::parse (varpool_node *node, bitmap_obstack *stack)
{
  if (TREE_THIS_VOLATILE (node->decl) || DECL_HARD_REGISTER (node->decl)
      || node->alias)
    return NULL;

  sem_variable *v = new sem_variable (node, stack);

  v->init ();

  return v;
}

/* References independent hash function.  */

hashval_t
sem_variable::get_hash (void)
{
  if (m_hash_set)
    return m_hash;

  /* All WPA streamed in symbols should have their hashes computed at compile
     time.  At this point, the constructor may not be in memory at all.
     DECL_INITIAL (decl) would be error_mark_node in that case.  */
  gcc_assert (!node->lto_file_data);
  tree ctor = DECL_INITIAL (decl);
  inchash::hash hstate;

  hstate.add_int (456346417);
  if (DECL_SIZE (decl) && tree_fits_shwi_p (DECL_SIZE (decl)))
    hstate.add_hwi (tree_to_shwi (DECL_SIZE (decl)));
  add_expr (ctor, hstate);
  set_hash (hstate.end ());

  return m_hash;
}

/* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can
   be applied.  */

bool
sem_variable::merge (sem_item *alias_item)
{
  gcc_assert (alias_item->type == VAR);

  if (!sem_item::target_supports_symbol_aliases_p ())
    {
      if (dump_file)
	fprintf (dump_file, "Not unifying; "
		 "Symbol aliases are not supported by target\n\n");
      return false;
    }

  if (DECL_EXTERNAL (alias_item->decl))
    {
      if (dump_file)
	fprintf (dump_file, "Not unifying; alias is external.\n\n");
      return false;
    }

  sem_variable *alias_var = static_cast<sem_variable *> (alias_item);

  varpool_node *original = get_node ();
  varpool_node *alias = alias_var->get_node ();
  bool original_discardable = false;

  bool alias_address_matters = alias->address_matters_p ();

  /* See if original is in a section that can be discarded if the main
     symbol is not used.
     Also consider case where we have resolution info and we know that
     original's definition is not going to be used.  In this case we cannot
     create alias to original.  */
  if (original->can_be_discarded_p ()
      || (node->resolution != LDPR_UNKNOWN
	  && !decl_binds_to_current_def_p (node->decl)))
    original_discardable = true;

  gcc_assert (!TREE_ASM_WRITTEN (alias->decl));

  /* Constant pool machinery is not quite ready for aliases.
     TODO: varasm code contains logic for merging DECL_IN_CONSTANT_POOL.
     For LTO merging does not happen that is an important missing feature.
     We can enable merging with LTO if the DECL_IN_CONSTANT_POOL
     flag is dropped and non-local symbol name is assigned.  */
  if (DECL_IN_CONSTANT_POOL (alias->decl)
      || DECL_IN_CONSTANT_POOL (original->decl))
    {
      if (dump_file)
	fprintf (dump_file,
		 "Not unifying; constant pool variables.\n\n");
      return false;
    }

  /* Do not attempt to mix functions from different user sections;
     we do not know what user intends with those.  */
  if (((DECL_SECTION_NAME (original->decl) && !original->implicit_section)
       || (DECL_SECTION_NAME (alias->decl) && !alias->implicit_section))
      && DECL_SECTION_NAME (original->decl) != DECL_SECTION_NAME (alias->decl))
    {
      if (dump_file)
	fprintf (dump_file,
		 "Not unifying; "
		 "original and alias are in different sections.\n\n");
      return false;
    }

  /* We cannot merge if address comparsion metters.  */
  if (alias_address_matters && flag_merge_constants < 2)
    {
      if (dump_file)
	fprintf (dump_file,
		 "Not unifying; address of original may be compared.\n\n");
      return false;
    }

  if (DECL_ALIGN (original->decl) < DECL_ALIGN (alias->decl))
    {
      if (dump_file)
	fprintf (dump_file, "Not unifying; "
		 "original and alias have incompatible alignments\n\n");

      return false;
    }

  if (DECL_COMDAT_GROUP (original->decl) != DECL_COMDAT_GROUP (alias->decl))
    {
      if (dump_file)
	fprintf (dump_file, "Not unifying; alias cannot be created; "
		 "across comdat group boundary\n\n");

      return false;
    }

  if (original_discardable)
    {
      if (dump_file)
	fprintf (dump_file, "Not unifying; alias cannot be created; "
		 "target is discardable\n\n");

      return false;
    }
  else
    {
      gcc_assert (!original->alias);
      gcc_assert (!alias->alias);

      alias->analyzed = false;

      DECL_INITIAL (alias->decl) = NULL;
      ((symtab_node *)alias)->call_for_symbol_and_aliases (clear_decl_rtl,
							   NULL, true);
      alias->remove_all_references ();
      if (TREE_ADDRESSABLE (alias->decl))
        original->call_for_symbol_and_aliases (set_addressable, NULL, true);

      varpool_node::create_alias (alias_var->decl, decl);
      alias->resolve_alias (original);

      if (dump_file)
	fprintf (dump_file, "Unified; Variable alias has been created.\n");

      return true;
    }
}

/* Dump symbol to FILE.  */

void
sem_variable::dump_to_file (FILE *file)
{
  gcc_assert (file);

  print_node (file, "", decl, 0);
  fprintf (file, "\n\n");
}

unsigned int sem_item_optimizer::class_id = 0;

sem_item_optimizer::sem_item_optimizer ()
: worklist (0), m_classes (0), m_classes_count (0), m_cgraph_node_hooks (NULL),
  m_varpool_node_hooks (NULL), m_merged_variables ()
{
  m_items.create (0);
  bitmap_obstack_initialize (&m_bmstack);
}

sem_item_optimizer::~sem_item_optimizer ()
{
  for (unsigned int i = 0; i < m_items.length (); i++)
    delete m_items[i];


  for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
       it != m_classes.end (); ++it)
    {
      for (unsigned int i = 0; i < (*it)->classes.length (); i++)
	delete (*it)->classes[i];

      (*it)->classes.release ();
      free (*it);
    }

  m_items.release ();

  bitmap_obstack_release (&m_bmstack);
  m_merged_variables.release ();
}

/* Write IPA ICF summary for symbols.  */

void
sem_item_optimizer::write_summary (void)
{
  unsigned int count = 0;

  output_block *ob = create_output_block (LTO_section_ipa_icf);
  lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
  ob->symbol = NULL;

  /* Calculate number of symbols to be serialized.  */
  for (lto_symtab_encoder_iterator lsei = lsei_start_in_partition (encoder);
       !lsei_end_p (lsei);
       lsei_next_in_partition (&lsei))
    {
      symtab_node *node = lsei_node (lsei);

      if (m_symtab_node_map.get (node))
	count++;
    }

  streamer_write_uhwi (ob, count);

  /* Process all of the symbols.  */
  for (lto_symtab_encoder_iterator lsei = lsei_start_in_partition (encoder);
       !lsei_end_p (lsei);
       lsei_next_in_partition (&lsei))
    {
      symtab_node *node = lsei_node (lsei);

      sem_item **item = m_symtab_node_map.get (node);

      if (item && *item)
	{
	  int node_ref = lto_symtab_encoder_encode (encoder, node);
	  streamer_write_uhwi_stream (ob->main_stream, node_ref);

	  streamer_write_uhwi (ob, (*item)->get_hash ());
	}
    }

  streamer_write_char_stream (ob->main_stream, 0);
  produce_asm (ob, NULL);
  destroy_output_block (ob);
}

/* Reads a section from LTO stream file FILE_DATA. Input block for DATA
   contains LEN bytes.  */

void
sem_item_optimizer::read_section (lto_file_decl_data *file_data,
				  const char *data, size_t len)
{
  const lto_function_header *header
    = (const lto_function_header *) data;
  const int cfg_offset = sizeof (lto_function_header);
  const int main_offset = cfg_offset + header->cfg_size;
  const int string_offset = main_offset + header->main_size;
  data_in *data_in;
  unsigned int i;
  unsigned int count;

  lto_input_block ib_main ((const char *) data + main_offset, 0,
			   header->main_size, file_data->mode_table);

  data_in
    = lto_data_in_create (file_data, (const char *) data + string_offset,
			  header->string_size, vNULL);

  count = streamer_read_uhwi (&ib_main);

  for (i = 0; i < count; i++)
    {
      unsigned int index;
      symtab_node *node;
      lto_symtab_encoder_t encoder;

      index = streamer_read_uhwi (&ib_main);
      encoder = file_data->symtab_node_encoder;
      node = lto_symtab_encoder_deref (encoder, index);

      hashval_t hash = streamer_read_uhwi (&ib_main);

      gcc_assert (node->definition);

      if (dump_file)
	fprintf (dump_file, "Symbol added: %s (tree: %p)\n",
		 node->dump_asm_name (), (void *) node->decl);

      if (is_a<cgraph_node *> (node))
	{
	  cgraph_node *cnode = dyn_cast <cgraph_node *> (node);

	  sem_function *fn = new sem_function (cnode, &m_bmstack);
	  fn->set_hash (hash);
	  m_items.safe_push (fn);
	}
      else
	{
	  varpool_node *vnode = dyn_cast <varpool_node *> (node);

	  sem_variable *var = new sem_variable (vnode, &m_bmstack);
	  var->set_hash (hash);
	  m_items.safe_push (var);
	}
    }

  lto_free_section_data (file_data, LTO_section_ipa_icf, NULL, data,
			 len);
  lto_data_in_delete (data_in);
}

/* Read IPA ICF summary for symbols.  */

void
sem_item_optimizer::read_summary (void)
{
  lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
  lto_file_decl_data *file_data;
  unsigned int j = 0;

  while ((file_data = file_data_vec[j++]))
    {
      size_t len;
      const char *data = lto_get_section_data (file_data,
			 LTO_section_ipa_icf, NULL, &len);

      if (data)
	read_section (file_data, data, len);
    }
}

/* Register callgraph and varpool hooks.  */

void
sem_item_optimizer::register_hooks (void)
{
  if (!m_cgraph_node_hooks)
    m_cgraph_node_hooks = symtab->add_cgraph_removal_hook
			  (&sem_item_optimizer::cgraph_removal_hook, this);

  if (!m_varpool_node_hooks)
    m_varpool_node_hooks = symtab->add_varpool_removal_hook
			   (&sem_item_optimizer::varpool_removal_hook, this);
}

/* Unregister callgraph and varpool hooks.  */

void
sem_item_optimizer::unregister_hooks (void)
{
  if (m_cgraph_node_hooks)
    symtab->remove_cgraph_removal_hook (m_cgraph_node_hooks);

  if (m_varpool_node_hooks)
    symtab->remove_varpool_removal_hook (m_varpool_node_hooks);
}

/* Adds a CLS to hashtable associated by hash value.  */

void
sem_item_optimizer::add_class (congruence_class *cls)
{
  gcc_assert (cls->members.length ());

  congruence_class_group *group
    = get_group_by_hash (cls->members[0]->get_hash (),
			 cls->members[0]->type);
  group->classes.safe_push (cls);
}

/* Gets a congruence class group based on given HASH value and TYPE.  */

congruence_class_group *
sem_item_optimizer::get_group_by_hash (hashval_t hash, sem_item_type type)
{
  congruence_class_group *item = XNEW (congruence_class_group);
  item->hash = hash;
  item->type = type;

  congruence_class_group **slot = m_classes.find_slot (item, INSERT);

  if (*slot)
    free (item);
  else
    {
      item->classes.create (1);
      *slot = item;
    }

  return *slot;
}

/* Callgraph removal hook called for a NODE with a custom DATA.  */

void
sem_item_optimizer::cgraph_removal_hook (cgraph_node *node, void *data)
{
  sem_item_optimizer *optimizer = (sem_item_optimizer *) data;
  optimizer->remove_symtab_node (node);
}

/* Varpool removal hook called for a NODE with a custom DATA.  */

void
sem_item_optimizer::varpool_removal_hook (varpool_node *node, void *data)
{
  sem_item_optimizer *optimizer = (sem_item_optimizer *) data;
  optimizer->remove_symtab_node (node);
}

/* Remove symtab NODE triggered by symtab removal hooks.  */

void
sem_item_optimizer::remove_symtab_node (symtab_node *node)
{
  gcc_assert (!m_classes.elements ());

  m_removed_items_set.add (node);
}

void
sem_item_optimizer::remove_item (sem_item *item)
{
  if (m_symtab_node_map.get (item->node))
    m_symtab_node_map.remove (item->node);
  delete item;
}

/* Removes all callgraph and varpool nodes that are marked by symtab
   as deleted.  */

void
sem_item_optimizer::filter_removed_items (void)
{
  auto_vec <sem_item *> filtered;

  for (unsigned int i = 0; i < m_items.length(); i++)
    {
      sem_item *item = m_items[i];

      if (m_removed_items_set.contains (item->node))
        {
	  remove_item (item);
	  continue;
        }

      if (item->type == FUNC)
        {
	  cgraph_node *cnode = static_cast <sem_function *>(item)->get_node ();

	  if (in_lto_p && (cnode->alias || cnode->body_removed))
	    remove_item (item);
	  else
	    filtered.safe_push (item);
        }
      else /* VAR.  */
        {
	  if (!flag_ipa_icf_variables)
	    remove_item (item);
	  else
	    {
	      /* Filter out non-readonly variables.  */
	      tree decl = item->decl;
	      if (TREE_READONLY (decl))
		filtered.safe_push (item);
	      else
		remove_item (item);
	    }
        }
    }

  /* Clean-up of released semantic items.  */

  m_items.release ();
  for (unsigned int i = 0; i < filtered.length(); i++)
    m_items.safe_push (filtered[i]);
}

/* Optimizer entry point which returns true in case it processes
   a merge operation. True is returned if there's a merge operation
   processed.  */

bool
sem_item_optimizer::execute (void)
{
  filter_removed_items ();
  unregister_hooks ();

  build_graph ();
  update_hash_by_addr_refs ();
  build_hash_based_classes ();

  if (dump_file)
    fprintf (dump_file, "Dump after hash based groups\n");
  dump_cong_classes ();

  for (unsigned int i = 0; i < m_items.length(); i++)
    m_items[i]->init_wpa ();

  subdivide_classes_by_equality (true);

  if (dump_file)
    fprintf (dump_file, "Dump after WPA based types groups\n");

  dump_cong_classes ();

  process_cong_reduction ();
  checking_verify_classes ();

  if (dump_file)
    fprintf (dump_file, "Dump after callgraph-based congruence reduction\n");

  dump_cong_classes ();

  parse_nonsingleton_classes ();
  subdivide_classes_by_equality ();

  if (dump_file)
    fprintf (dump_file, "Dump after full equality comparison of groups\n");

  dump_cong_classes ();

  unsigned int prev_class_count = m_classes_count;

  process_cong_reduction ();
  dump_cong_classes ();
  checking_verify_classes ();
  bool merged_p = merge_classes (prev_class_count);

  if (dump_file && (dump_flags & TDF_DETAILS))
    symtab->dump (dump_file);

  return merged_p;
}

/* Function responsible for visiting all potential functions and
   read-only variables that can be merged.  */

void
sem_item_optimizer::parse_funcs_and_vars (void)
{
  cgraph_node *cnode;

  if (flag_ipa_icf_functions)
    FOR_EACH_DEFINED_FUNCTION (cnode)
    {
      sem_function *f = sem_function::parse (cnode, &m_bmstack);
      if (f)
	{
	  m_items.safe_push (f);
	  m_symtab_node_map.put (cnode, f);

	  if (dump_file)
	    fprintf (dump_file, "Parsed function:%s\n", f->node->asm_name ());

	  if (dump_file && (dump_flags & TDF_DETAILS))
	    f->dump_to_file (dump_file);
	}
      else if (dump_file)
	fprintf (dump_file, "Not parsed function:%s\n", cnode->asm_name ());
    }

  varpool_node *vnode;

  if (flag_ipa_icf_variables)
    FOR_EACH_DEFINED_VARIABLE (vnode)
    {
      sem_variable *v = sem_variable::parse (vnode, &m_bmstack);

      if (v)
	{
	  m_items.safe_push (v);
	  m_symtab_node_map.put (vnode, v);
	}
    }
}

/* Makes pairing between a congruence class CLS and semantic ITEM.  */

void
sem_item_optimizer::add_item_to_class (congruence_class *cls, sem_item *item)
{
  item->index_in_class = cls->members.length ();
  cls->members.safe_push (item);
  item->cls = cls;
}

/* For each semantic item, append hash values of references.  */

void
sem_item_optimizer::update_hash_by_addr_refs ()
{
  /* First, append to hash sensitive references and class type if it need to
     be matched for ODR.  */
  for (unsigned i = 0; i < m_items.length (); i++)
    {
      m_items[i]->update_hash_by_addr_refs (m_symtab_node_map);
      if (m_items[i]->type == FUNC)
	{
	  if (TREE_CODE (TREE_TYPE (m_items[i]->decl)) == METHOD_TYPE
	      && contains_polymorphic_type_p
		   (TYPE_METHOD_BASETYPE (TREE_TYPE (m_items[i]->decl)))
	      && (DECL_CXX_CONSTRUCTOR_P (m_items[i]->decl)
		  || (static_cast<sem_function *> (m_items[i])->param_used_p (0)
		      && static_cast<sem_function *> (m_items[i])
			   ->compare_polymorphic_p ())))
	     {
	        tree class_type
		  = TYPE_METHOD_BASETYPE (TREE_TYPE (m_items[i]->decl));
		inchash::hash hstate (m_items[i]->get_hash ());

		if (TYPE_NAME (class_type)
		     && DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (class_type)))
		  hstate.add_hwi
		    (IDENTIFIER_HASH_VALUE
		       (DECL_ASSEMBLER_NAME (TYPE_NAME (class_type))));

		m_items[i]->set_hash (hstate.end ());
	     }
	}
    }

  /* Once all symbols have enhanced hash value, we can append
     hash values of symbols that are seen by IPA ICF and are
     references by a semantic item. Newly computed values
     are saved to global_hash member variable.  */
  for (unsigned i = 0; i < m_items.length (); i++)
    m_items[i]->update_hash_by_local_refs (m_symtab_node_map);

  /* Global hash value replace current hash values.  */
  for (unsigned i = 0; i < m_items.length (); i++)
    m_items[i]->set_hash (m_items[i]->global_hash);
}

/* Congruence classes are built by hash value.  */

void
sem_item_optimizer::build_hash_based_classes (void)
{
  for (unsigned i = 0; i < m_items.length (); i++)
    {
      sem_item *item = m_items[i];

      congruence_class_group *group
	= get_group_by_hash (item->get_hash (), item->type);

      if (!group->classes.length ())
	{
	  m_classes_count++;
	  group->classes.safe_push (new congruence_class (class_id++));
	}

      add_item_to_class (group->classes[0], item);
    }
}

/* Build references according to call graph.  */

void
sem_item_optimizer::build_graph (void)
{
  for (unsigned i = 0; i < m_items.length (); i++)
    {
      sem_item *item = m_items[i];
      m_symtab_node_map.put (item->node, item);

      /* Initialize hash values if we are not in LTO mode.  */
      if (!in_lto_p)
	item->get_hash ();
    }

  for (unsigned i = 0; i < m_items.length (); i++)
    {
      sem_item *item = m_items[i];

      if (item->type == FUNC)
	{
	  cgraph_node *cnode = dyn_cast <cgraph_node *> (item->node);

	  cgraph_edge *e = cnode->callees;
	  while (e)
	    {
	      sem_item **slot = m_symtab_node_map.get
		(e->callee->ultimate_alias_target ());
	      if (slot)
		item->add_reference (*slot);

	      e = e->next_callee;
	    }
	}

      ipa_ref *ref = NULL;
      for (unsigned i = 0; item->node->iterate_reference (i, ref); i++)
	{
	  sem_item **slot = m_symtab_node_map.get
	    (ref->referred->ultimate_alias_target ());
	  if (slot)
	    item->add_reference (*slot);
	}
    }
}

/* Semantic items in classes having more than one element and initialized.
   In case of WPA, we load function body.  */

void
sem_item_optimizer::parse_nonsingleton_classes (void)
{
  unsigned int init_called_count = 0;

  for (unsigned i = 0; i < m_items.length (); i++)
    if (m_items[i]->cls->members.length () > 1)
      {
	m_items[i]->init ();
	init_called_count++;
      }

  if (dump_file)
    fprintf (dump_file, "Init called for %u items (%.2f%%).\n",
	     init_called_count,
	     m_items.length () ? 100.0f * init_called_count / m_items.length ()
			       : 0.0f);
}

/* Equality function for semantic items is used to subdivide existing
   classes. If IN_WPA, fast equality function is invoked.  */

void
sem_item_optimizer::subdivide_classes_by_equality (bool in_wpa)
{
  for (hash_table <congruence_class_hash>::iterator it = m_classes.begin ();
       it != m_classes.end (); ++it)
    {
      unsigned int class_count = (*it)->classes.length ();

      for (unsigned i = 0; i < class_count; i++)
	{
	  congruence_class *c = (*it)->classes[i];

	  if (c->members.length() > 1)
	    {
	      auto_vec <sem_item *> new_vector;

	      sem_item *first = c->members[0];
	      new_vector.safe_push (first);

	      unsigned class_split_first = (*it)->classes.length ();

	      for (unsigned j = 1; j < c->members.length (); j++)
		{
		  sem_item *item = c->members[j];

		  bool equals
		    = in_wpa ? first->equals_wpa (item, m_symtab_node_map)
			     : first->equals (item, m_symtab_node_map);

		  if (equals)
		    new_vector.safe_push (item);
		  else
		    {
		      bool integrated = false;

		      for (unsigned k = class_split_first;
			   k < (*it)->classes.length (); k++)
			{
			  sem_item *x = (*it)->classes[k]->members[0];
			  bool equals
			    = in_wpa ? x->equals_wpa (item, m_symtab_node_map)
				     : x->equals (item, m_symtab_node_map);

			  if (equals)
			    {
			      integrated = true;
			      add_item_to_class ((*it)->classes[k], item);

			      break;
			    }
			}

		      if (!integrated)
			{
			  congruence_class *c
			    = new congruence_class (class_id++);
			  m_classes_count++;
			  add_item_to_class (c, item);

			  (*it)->classes.safe_push (c);
			}
		    }
		}

	      // We replace newly created new_vector for the class we've just
	      // splitted.
	      c->members.release ();
	      c->members.create (new_vector.length ());

	      for (unsigned int j = 0; j < new_vector.length (); j++)
		add_item_to_class (c, new_vector[j]);
	    }
	}
    }

  checking_verify_classes ();
}

/* Subdivide classes by address references that members of the class
   reference. Example can be a pair of functions that have an address
   taken from a function. If these addresses are different the class
   is split.  */

unsigned
sem_item_optimizer::subdivide_classes_by_sensitive_refs ()
{
  typedef hash_map <symbol_compare_hash, vec <sem_item *> > subdivide_hash_map;

  unsigned newly_created_classes = 0;

  for (hash_table <congruence_class_hash>::iterator it = m_classes.begin ();
       it != m_classes.end (); ++it)
    {
      unsigned int class_count = (*it)->classes.length ();
      auto_vec<congruence_class *> new_classes;

      for (unsigned i = 0; i < class_count; i++)
	{
	  congruence_class *c = (*it)->classes[i];

	  if (c->members.length() > 1)
	    {
	      subdivide_hash_map split_map;

	      for (unsigned j = 0; j < c->members.length (); j++)
	        {
		  sem_item *source_node = c->members[j];

		  symbol_compare_collection *collection
		    = new symbol_compare_collection (source_node->node);

		  bool existed;
		  vec <sem_item *> *slot
		    = &split_map.get_or_insert (collection, &existed);
		  gcc_checking_assert (slot);

		  slot->safe_push (source_node);

		  if (existed)
		    delete collection;
	        }

	       /* If the map contains more than one key, we have to split
		  the map appropriately.  */
	      if (split_map.elements () != 1)
	        {
		  bool first_class = true;

		  for (subdivide_hash_map::iterator it2 = split_map.begin ();
		       it2 != split_map.end (); ++it2)
		    {
		      congruence_class *new_cls;
		      new_cls = new congruence_class (class_id++);

		      for (unsigned k = 0; k < (*it2).second.length (); k++)
			add_item_to_class (new_cls, (*it2).second[k]);

		      worklist_push (new_cls);
		      newly_created_classes++;

		      if (first_class)
		        {
			  (*it)->classes[i] = new_cls;
			  first_class = false;
			}
		      else
		        {
		          new_classes.safe_push (new_cls);
			  m_classes_count++;
		        }
		    }
		}

	      /* Release memory.  */
	      for (subdivide_hash_map::iterator it2 = split_map.begin ();
		   it2 != split_map.end (); ++it2)
		{
		  delete (*it2).first;
		  (*it2).second.release ();
		}
	    }
	  }

	for (unsigned i = 0; i < new_classes.length (); i++)
	  (*it)->classes.safe_push (new_classes[i]);
    }

  return newly_created_classes;
}

/* Verify congruence classes, if checking is enabled.  */

void
sem_item_optimizer::checking_verify_classes (void)
{
  if (flag_checking)
    verify_classes ();
}

/* Verify congruence classes.  */

void
sem_item_optimizer::verify_classes (void)
{
  for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
       it != m_classes.end (); ++it)
    {
      for (unsigned int i = 0; i < (*it)->classes.length (); i++)
	{
	  congruence_class *cls = (*it)->classes[i];

	  gcc_assert (cls);
	  gcc_assert (cls->members.length () > 0);

	  for (unsigned int j = 0; j < cls->members.length (); j++)
	    {
	      sem_item *item = cls->members[j];

	      gcc_assert (item);
	      gcc_assert (item->cls == cls);

	      for (unsigned k = 0; k < item->usages.length (); k++)
		{
		  sem_usage_pair *usage = item->usages[k];
		  gcc_assert (usage->item->index_in_class
			      < usage->item->cls->members.length ());
		}
	    }
	}
    }
}

/* Disposes split map traverse function. CLS_PTR is pointer to congruence
   class, BSLOT is bitmap slot we want to release. DATA is mandatory,
   but unused argument.  */

bool
sem_item_optimizer::release_split_map (congruence_class * const &,
				       bitmap const &b, traverse_split_pair *)
{
  bitmap bmp = b;

  BITMAP_FREE (bmp);

  return true;
}

/* Process split operation for a class given as pointer CLS_PTR,
   where bitmap B splits congruence class members. DATA is used
   as argument of split pair.  */

bool
sem_item_optimizer::traverse_congruence_split (congruence_class * const &cls,
					       bitmap const &b,
					       traverse_split_pair *pair)
{
  sem_item_optimizer *optimizer = pair->optimizer;
  const congruence_class *splitter_cls = pair->cls;

  /* If counted bits are greater than zero and less than the number of members
     a group will be splitted.  */
  unsigned popcount = bitmap_count_bits (b);

  if (popcount > 0 && popcount < cls->members.length ())
    {
      auto_vec <congruence_class *, 2> newclasses;
      newclasses.quick_push (new congruence_class (class_id++));
      newclasses.quick_push (new congruence_class (class_id++));

      for (unsigned int i = 0; i < cls->members.length (); i++)
	{
	  int target = bitmap_bit_p (b, i);
	  congruence_class *tc = newclasses[target];

	  add_item_to_class (tc, cls->members[i]);
	}

      if (flag_checking)
	{
	  for (unsigned int i = 0; i < 2; i++)
	    gcc_assert (newclasses[i]->members.length ());
	}

      if (splitter_cls == cls)
	optimizer->splitter_class_removed = true;

      /* Remove old class from worklist if presented.  */
      bool in_worklist = cls->in_worklist;

      if (in_worklist)
	cls->in_worklist = false;

      congruence_class_group g;
      g.hash = cls->members[0]->get_hash ();
      g.type = cls->members[0]->type;

      congruence_class_group *slot = optimizer->m_classes.find (&g);

      for (unsigned int i = 0; i < slot->classes.length (); i++)
	if (slot->classes[i] == cls)
	  {
	    slot->classes.ordered_remove (i);
	    break;
	  }

      /* New class will be inserted and integrated to work list.  */
      for (unsigned int i = 0; i < 2; i++)
	optimizer->add_class (newclasses[i]);

      /* Two classes replace one, so that increment just by one.  */
      optimizer->m_classes_count++;

      /* If OLD class was presented in the worklist, we remove the class
         and replace it will both newly created classes.  */
      if (in_worklist)
	for (unsigned int i = 0; i < 2; i++)
	  optimizer->worklist_push (newclasses[i]);
      else /* Just smaller class is inserted.  */
	{
	  unsigned int smaller_index
	    = (newclasses[0]->members.length ()
	       < newclasses[1]->members.length ()
	       ? 0 : 1);
	  optimizer->worklist_push (newclasses[smaller_index]);
	}

      if (dump_file && (dump_flags & TDF_DETAILS))
	{
	  fprintf (dump_file, "  congruence class splitted:\n");
	  cls->dump (dump_file, 4);

	  fprintf (dump_file, "  newly created groups:\n");
	  for (unsigned int i = 0; i < 2; i++)
	    newclasses[i]->dump (dump_file, 4);
	}

      /* Release class if not presented in work list.  */
      if (!in_worklist)
	delete cls;
    }


  return true;
}

/* Compare function for sorting pairs in do_congruence_step_f.  */

int
sem_item_optimizer::sort_congruence_split (const void *a_, const void *b_)
{
  const std::pair<congruence_class *, bitmap> *a
    = (const std::pair<congruence_class *, bitmap> *)a_;
  const std::pair<congruence_class *, bitmap> *b
    = (const std::pair<congruence_class *, bitmap> *)b_;
  if (a->first->id < b->first->id)
    return -1;
  else if (a->first->id > b->first->id)
    return 1;
  return 0;
}

/* Tests if a class CLS used as INDEXth splits any congruence classes.
   Bitmap stack BMSTACK is used for bitmap allocation.  */

void
sem_item_optimizer::do_congruence_step_for_index (congruence_class *cls,
						  unsigned int index)
{
  hash_map <congruence_class *, bitmap> split_map;

  for (unsigned int i = 0; i < cls->members.length (); i++)
    {
      sem_item *item = cls->members[i];

      /* Iterate all usages that have INDEX as usage of the item.  */
      for (unsigned int j = 0; j < item->usages.length (); j++)
	{
	  sem_usage_pair *usage = item->usages[j];

	  if (usage->index != index)
	    continue;

	  bitmap *slot = split_map.get (usage->item->cls);
	  bitmap b;

	  if(!slot)
	    {
	      b = BITMAP_ALLOC (&m_bmstack);
	      split_map.put (usage->item->cls, b);
	    }
	  else
	    b = *slot;

	  gcc_checking_assert (usage->item->cls);
	  gcc_checking_assert (usage->item->index_in_class
			       < usage->item->cls->members.length ());

	  bitmap_set_bit (b, usage->item->index_in_class);
	}
    }

  auto_vec<std::pair<congruence_class *, bitmap> > to_split;
  to_split.reserve_exact (split_map.elements ());
  for (hash_map <congruence_class *, bitmap>::iterator i = split_map.begin ();
       i != split_map.end (); ++i)
    to_split.safe_push (*i);
  to_split.qsort (sort_congruence_split);

  traverse_split_pair pair;
  pair.optimizer = this;
  pair.cls = cls;

  splitter_class_removed = false;
  for (unsigned i = 0; i < to_split.length (); ++i)
    traverse_congruence_split (to_split[i].first, to_split[i].second, &pair);

  /* Bitmap clean-up.  */
  split_map.traverse <traverse_split_pair *,
		      sem_item_optimizer::release_split_map> (NULL);
}

/* Every usage of a congruence class CLS is a candidate that can split the
   collection of classes. Bitmap stack BMSTACK is used for bitmap
   allocation.  */

void
sem_item_optimizer::do_congruence_step (congruence_class *cls)
{
  bitmap_iterator bi;
  unsigned int i;

  bitmap usage = BITMAP_ALLOC (&m_bmstack);

  for (unsigned int i = 0; i < cls->members.length (); i++)
    bitmap_ior_into (usage, cls->members[i]->usage_index_bitmap);

  EXECUTE_IF_SET_IN_BITMAP (usage, 0, i, bi)
  {
    if (dump_file && (dump_flags & TDF_DETAILS))
      fprintf (dump_file, "  processing congruence step for class: %u, "
	       "index: %u\n", cls->id, i);

    do_congruence_step_for_index (cls, i);

    if (splitter_class_removed)
      break;
  }

  BITMAP_FREE (usage);
}

/* Adds a newly created congruence class CLS to worklist.  */

void
sem_item_optimizer::worklist_push (congruence_class *cls)
{
  /* Return if the class CLS is already presented in work list.  */
  if (cls->in_worklist)
    return;

  cls->in_worklist = true;
  worklist.push_back (cls);
}

/* Pops a class from worklist. */

congruence_class *
sem_item_optimizer::worklist_pop (void)
{
  congruence_class *cls;

  while (!worklist.empty ())
    {
      cls = worklist.front ();
      worklist.pop_front ();
      if (cls->in_worklist)
	{
	  cls->in_worklist = false;

	  return cls;
	}
      else
	{
	  /* Work list item was already intended to be removed.
	     The only reason for doing it is to split a class.
	     Thus, the class CLS is deleted.  */
	  delete cls;
	}
    }

  return NULL;
}

/* Iterative congruence reduction function.  */

void
sem_item_optimizer::process_cong_reduction (void)
{
  for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
       it != m_classes.end (); ++it)
    for (unsigned i = 0; i < (*it)->classes.length (); i++)
      if ((*it)->classes[i]->is_class_used ())
	worklist_push ((*it)->classes[i]);

  if (dump_file)
    fprintf (dump_file, "Worklist has been filled with: %lu\n",
	     (unsigned long) worklist.size ());

  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "Congruence class reduction\n");

  congruence_class *cls;

  /* Process complete congruence reduction.  */
  while ((cls = worklist_pop ()) != NULL)
    do_congruence_step (cls);

  /* Subdivide newly created classes according to references.  */
  unsigned new_classes = subdivide_classes_by_sensitive_refs ();

  if (dump_file)
    fprintf (dump_file, "Address reference subdivision created: %u "
	     "new classes.\n", new_classes);
}

/* Debug function prints all informations about congruence classes.  */

void
sem_item_optimizer::dump_cong_classes (void)
{
  if (!dump_file)
    return;

  fprintf (dump_file,
	   "Congruence classes: %u (unique hash values: %lu), with total: "
	   "%u items\n", m_classes_count,
	   (unsigned long) m_classes.elements (), m_items.length ());

  /* Histogram calculation.  */
  unsigned int max_index = 0;
  unsigned int* histogram = XCNEWVEC (unsigned int, m_items.length () + 1);

  for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
       it != m_classes.end (); ++it)
    for (unsigned i = 0; i < (*it)->classes.length (); i++)
      {
	unsigned int c = (*it)->classes[i]->members.length ();
	histogram[c]++;

	if (c > max_index)
	  max_index = c;
      }

  fprintf (dump_file,
	   "Class size histogram [num of members]: number of classe number "
	   "of classess\n");

  for (unsigned int i = 0; i <= max_index; i++)
    if (histogram[i])
      fprintf (dump_file, "[%u]: %u classes\n", i, histogram[i]);

  fprintf (dump_file, "\n\n");

  if (dump_flags & TDF_DETAILS)
  for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
       it != m_classes.end (); ++it)
      {
	fprintf (dump_file, "  group: with %u classes:\n",
		 (*it)->classes.length ());

	for (unsigned i = 0; i < (*it)->classes.length (); i++)
	  {
	    (*it)->classes[i]->dump (dump_file, 4);

	    if (i < (*it)->classes.length () - 1)
	      fprintf (dump_file, " ");
	  }
      }

  free (histogram);
}

/* Sort pair of sem_items A and B by DECL_UID.  */

static int
sort_sem_items_by_decl_uid (const void *a, const void *b)
{
  const sem_item *i1 = *(const sem_item * const *)a;
  const sem_item *i2 = *(const sem_item * const *)b;

  int uid1 = DECL_UID (i1->decl);
  int uid2 = DECL_UID (i2->decl);

  if (uid1 < uid2)
    return -1;
  else if (uid1 > uid2)
    return 1;
  else
    return 0;
}

/* Sort pair of congruence_classes A and B by DECL_UID of the first member.  */

static int
sort_congruence_classes_by_decl_uid (const void *a, const void *b)
{
  const congruence_class *c1 = *(const congruence_class * const *)a;
  const congruence_class *c2 = *(const congruence_class * const *)b;

  int uid1 = DECL_UID (c1->members[0]->decl);
  int uid2 = DECL_UID (c2->members[0]->decl);

  if (uid1 < uid2)
    return -1;
  else if (uid1 > uid2)
    return 1;
  else
    return 0;
}

/* Sort pair of congruence_class_groups A and B by
   DECL_UID of the first member of a first group.  */

static int
sort_congruence_class_groups_by_decl_uid (const void *a, const void *b)
{
  const congruence_class_group *g1
    = *(const congruence_class_group * const *)a;
  const congruence_class_group *g2
    = *(const congruence_class_group * const *)b;

  int uid1 = DECL_UID (g1->classes[0]->members[0]->decl);
  int uid2 = DECL_UID (g2->classes[0]->members[0]->decl);

  if (uid1 < uid2)
    return -1;
  else if (uid1 > uid2)
    return 1;
  else
    return 0;
}

/* After reduction is done, we can declare all items in a group
   to be equal. PREV_CLASS_COUNT is start number of classes
   before reduction. True is returned if there's a merge operation
   processed. */

bool
sem_item_optimizer::merge_classes (unsigned int prev_class_count)
{
  unsigned int item_count = m_items.length ();
  unsigned int class_count = m_classes_count;
  unsigned int equal_items = item_count - class_count;

  unsigned int non_singular_classes_count = 0;
  unsigned int non_singular_classes_sum = 0;

  bool merged_p = false;

  /* PR lto/78211
     Sort functions in congruence classes by DECL_UID and do the same
     for the classes to not to break -fcompare-debug.  */

  for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
       it != m_classes.end (); ++it)
    {
      for (unsigned int i = 0; i < (*it)->classes.length (); i++)
	{
	  congruence_class *c = (*it)->classes[i];
	  c->members.qsort (sort_sem_items_by_decl_uid);
	}

      (*it)->classes.qsort (sort_congruence_classes_by_decl_uid);
    }

  for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
       it != m_classes.end (); ++it)
    for (unsigned int i = 0; i < (*it)->classes.length (); i++)
      {
	congruence_class *c = (*it)->classes[i];
	if (c->members.length () > 1)
	  {
	    non_singular_classes_count++;
	    non_singular_classes_sum += c->members.length ();
	  }
      }

  auto_vec <congruence_class_group *> classes (m_classes.elements ());
  for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
       it != m_classes.end (); ++it)
    classes.quick_push (*it);

  classes.qsort (sort_congruence_class_groups_by_decl_uid);

  if (dump_file)
    {
      fprintf (dump_file, "\nItem count: %u\n", item_count);
      fprintf (dump_file, "Congruent classes before: %u, after: %u\n",
	       prev_class_count, class_count);
      fprintf (dump_file, "Average class size before: %.2f, after: %.2f\n",
	       prev_class_count ? 1.0f * item_count / prev_class_count : 0.0f,
	       class_count ? 1.0f * item_count / class_count : 0.0f);
      fprintf (dump_file, "Average non-singular class size: %.2f, count: %u\n",
	       non_singular_classes_count ? 1.0f * non_singular_classes_sum /
	       non_singular_classes_count : 0.0f,
	       non_singular_classes_count);
      fprintf (dump_file, "Equal symbols: %u\n", equal_items);
      fprintf (dump_file, "Fraction of visited symbols: %.2f%%\n\n",
	       item_count ? 100.0f * equal_items / item_count : 0.0f);
    }

  unsigned int l;
  congruence_class_group *it;
  FOR_EACH_VEC_ELT (classes, l, it)
    for (unsigned int i = 0; i < it->classes.length (); i++)
      {
	congruence_class *c = it->classes[i];

	if (c->members.length () == 1)
	  continue;

	sem_item *source = c->members[0];

	if (DECL_NAME (source->decl)
	    && MAIN_NAME_P (DECL_NAME (source->decl)))
	  /* If merge via wrappers, picking main as the target can be
	     problematic.  */
	  source = c->members[1];

	for (unsigned int j = 0; j < c->members.length (); j++)
	  {
	    sem_item *alias = c->members[j];

	    if (alias == source)
	      continue;

	    if (dump_file)
	      {
		fprintf (dump_file, "Semantic equality hit:%s->%s\n",
			 xstrdup_for_dump (source->node->name ()),
			 xstrdup_for_dump (alias->node->name ()));
		fprintf (dump_file, "Assembler symbol names:%s->%s\n",
			 xstrdup_for_dump (source->node->asm_name ()),
			 xstrdup_for_dump (alias->node->asm_name ()));
	      }

	    if (lookup_attribute ("no_icf", DECL_ATTRIBUTES (alias->decl)))
	      {
	        if (dump_file)
		  fprintf (dump_file,
			   "Merge operation is skipped due to no_icf "
			   "attribute.\n\n");

		continue;
	      }

	    if (dump_file && (dump_flags & TDF_DETAILS))
	      {
		source->dump_to_file (dump_file);
		alias->dump_to_file (dump_file);
	      }

	    if (dbg_cnt (merged_ipa_icf))
	      {
		bool merged = source->merge (alias);
		merged_p |= merged;

		if (merged && alias->type == VAR)
		  {
		    symtab_pair p = symtab_pair (source->node, alias->node);
		    m_merged_variables.safe_push (p);
		  }
	      }
	  }
      }

  if (!m_merged_variables.is_empty ())
    fixup_points_to_sets ();

  return merged_p;
}

/* Fixup points to set PT.  */

void
sem_item_optimizer::fixup_pt_set (struct pt_solution *pt)
{
  if (pt->vars == NULL)
    return;

  unsigned i;
  symtab_pair *item;
  FOR_EACH_VEC_ELT (m_merged_variables, i, item)
    if (bitmap_bit_p (pt->vars, DECL_UID (item->second->decl)))
      bitmap_set_bit (pt->vars, DECL_UID (item->first->decl));
}

/* Set all points-to UIDs of aliases pointing to node N as UID.  */

static void
set_alias_uids (symtab_node *n, int uid)
{
  ipa_ref *ref;
  FOR_EACH_ALIAS (n, ref)
    {
      if (dump_file)
	fprintf (dump_file, "  Setting points-to UID of [%s] as %d\n",
		 xstrdup_for_dump (ref->referring->asm_name ()), uid);

      SET_DECL_PT_UID (ref->referring->decl, uid);
      set_alias_uids (ref->referring, uid);
    }
}

/* Fixup points to analysis info.  */

void
sem_item_optimizer::fixup_points_to_sets (void)
{
  /* TODO: remove in GCC 9 and trigger PTA re-creation after IPA passes.  */
  cgraph_node *cnode;

  FOR_EACH_DEFINED_FUNCTION (cnode)
    {
      tree name;
      unsigned i;
      function *fn = DECL_STRUCT_FUNCTION (cnode->decl);
      if (!gimple_in_ssa_p (fn))
	continue;

      FOR_EACH_SSA_NAME (i, name, fn)
	if (POINTER_TYPE_P (TREE_TYPE (name))
	    && SSA_NAME_PTR_INFO (name))
	  fixup_pt_set (&SSA_NAME_PTR_INFO (name)->pt);
      fixup_pt_set (&fn->gimple_df->escaped);

       /* The above get's us to 99% I guess, at least catching the
	  address compares.  Below also gets us aliasing correct
	  but as said we're giving leeway to the situation with
	  readonly vars anyway, so ... */
       basic_block bb;
       FOR_EACH_BB_FN (bb, fn)
	for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
	     gsi_next (&gsi))
	  {
	    gcall *call = dyn_cast<gcall *> (gsi_stmt (gsi));
	    if (call)
	      {
		fixup_pt_set (gimple_call_use_set (call));
		fixup_pt_set (gimple_call_clobber_set (call));
	      }
	  }
    }

  unsigned i;
  symtab_pair *item;
  FOR_EACH_VEC_ELT (m_merged_variables, i, item)
    set_alias_uids (item->first, DECL_UID (item->first->decl));
}

/* Dump function prints all class members to a FILE with an INDENT.  */

void
congruence_class::dump (FILE *file, unsigned int indent) const
{
  FPRINTF_SPACES (file, indent, "class with id: %u, hash: %u, items: %u\n",
		  id, members[0]->get_hash (), members.length ());

  FPUTS_SPACES (file, indent + 2, "");
  for (unsigned i = 0; i < members.length (); i++)
    fprintf (file, "%s ", members[i]->node->dump_asm_name ());

  fprintf (file, "\n");
}

/* Returns true if there's a member that is used from another group.  */

bool
congruence_class::is_class_used (void)
{
  for (unsigned int i = 0; i < members.length (); i++)
    if (members[i]->usages.length ())
      return true;

  return false;
}

/* Generate pass summary for IPA ICF pass.  */

static void
ipa_icf_generate_summary (void)
{
  if (!optimizer)
    optimizer = new sem_item_optimizer ();

  optimizer->register_hooks ();
  optimizer->parse_funcs_and_vars ();
}

/* Write pass summary for IPA ICF pass.  */

static void
ipa_icf_write_summary (void)
{
  gcc_assert (optimizer);

  optimizer->write_summary ();
}

/* Read pass summary for IPA ICF pass.  */

static void
ipa_icf_read_summary (void)
{
  if (!optimizer)
    optimizer = new sem_item_optimizer ();

  optimizer->read_summary ();
  optimizer->register_hooks ();
}

/* Semantic equality exection function.  */

static unsigned int
ipa_icf_driver (void)
{
  gcc_assert (optimizer);

  bool merged_p = optimizer->execute ();

  delete optimizer;
  optimizer = NULL;

  return merged_p ? TODO_remove_functions : 0;
}

const pass_data pass_data_ipa_icf =
{
  IPA_PASS,		    /* type */
  "icf",		    /* name */
  OPTGROUP_IPA,             /* optinfo_flags */
  TV_IPA_ICF,		    /* tv_id */
  0,                        /* properties_required */
  0,                        /* properties_provided */
  0,                        /* properties_destroyed */
  0,                        /* todo_flags_start */
  0,                        /* todo_flags_finish */
};

class pass_ipa_icf : public ipa_opt_pass_d
{
public:
  pass_ipa_icf (gcc::context *ctxt)
    : ipa_opt_pass_d (pass_data_ipa_icf, ctxt,
		      ipa_icf_generate_summary, /* generate_summary */
		      ipa_icf_write_summary, /* write_summary */
		      ipa_icf_read_summary, /* 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 *)
  {
    return in_lto_p || flag_ipa_icf_variables || flag_ipa_icf_functions;
  }

  virtual unsigned int execute (function *)
  {
    return ipa_icf_driver();
  }
}; // class pass_ipa_icf

} // ipa_icf namespace

ipa_opt_pass_d *
make_pass_ipa_icf (gcc::context *ctxt)
{
  return new ipa_icf::pass_ipa_icf (ctxt);
}
