/* Generic routines for manipulating SSA_NAME expressions
   Copyright (C) 2003-2022 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "gimple.h"
#include "tree-pass.h"
#include "ssa.h"
#include "gimple-iterator.h"
#include "stor-layout.h"
#include "tree-into-ssa.h"
#include "tree-ssa.h"
#include "cfgloop.h"
#include "tree-scalar-evolution.h"
#include "value-query.h"

/* Rewriting a function into SSA form can create a huge number of SSA_NAMEs,
   many of which may be thrown away shortly after their creation if jumps
   were threaded through PHI nodes.

   While our garbage collection mechanisms will handle this situation, it
   is extremely wasteful to create nodes and throw them away, especially
   when the nodes can be reused.

   For PR 8361, we can significantly reduce the number of nodes allocated
   and thus the total amount of memory allocated by managing SSA_NAMEs a
   little.  This additionally helps reduce the amount of work done by the
   garbage collector.  Similar results have been seen on a wider variety
   of tests (such as the compiler itself).

   Right now we maintain our free list on a per-function basis.  It may
   or may not make sense to maintain the free list for the duration of
   a compilation unit.

   External code should rely solely upon HIGHEST_SSA_VERSION and the
   externally defined functions.  External code should not know about
   the details of the free list management.

   External code should also not assume the version number on nodes is
   monotonically increasing.  We reuse the version number when we
   reuse an SSA_NAME expression.  This helps keep arrays and bitmaps
   more compact.  */


/* Version numbers with special meanings.  We start allocating new version
   numbers after the special ones.  */
#define UNUSED_NAME_VERSION 0

unsigned int ssa_name_nodes_reused;
unsigned int ssa_name_nodes_created;

#define FREE_SSANAMES(fun) (fun)->gimple_df->free_ssanames
#define FREE_SSANAMES_QUEUE(fun) (fun)->gimple_df->free_ssanames_queue


/* Initialize management of SSA_NAMEs to default SIZE.  If SIZE is
   zero use default.  */

void
init_ssanames (struct function *fn, int size)
{
  if (!size)
    vec_alloc (SSANAMES (fn), 50);
  else
    vec_safe_reserve (SSANAMES (fn), size, true);

  /* Version 0 is special, so reserve the first slot in the table.  Though
     currently unused, we may use version 0 in alias analysis as part of
     the heuristics used to group aliases when the alias sets are too
     large.

     We use vec::quick_push here because we know that SSA_NAMES has at
     least 50 elements reserved in it.  */
  SSANAMES (fn)->quick_push (NULL_TREE);
  FREE_SSANAMES (fn) = NULL;
  FREE_SSANAMES_QUEUE (fn) = NULL;

  fn->gimple_df->ssa_renaming_needed = 0;
  fn->gimple_df->rename_vops = 0;
}

/* Finalize management of SSA_NAMEs.  */

void
fini_ssanames (struct function *fn)
{
  unsigned i;
  tree name;
  /* Some SSA names leak into global tree data structures so we can't simply
     ggc_free them.  But make sure to clear references to stmts since we now
     ggc_free the CFG itself.  */
  FOR_EACH_VEC_SAFE_ELT (SSANAMES (fn), i, name)
    if (name)
      SSA_NAME_DEF_STMT (name) = NULL;
  vec_free (SSANAMES (fn));
  vec_free (FREE_SSANAMES (fn));
  vec_free (FREE_SSANAMES_QUEUE (fn));
}

/* Dump some simple statistics regarding the re-use of SSA_NAME nodes.  */

void
ssanames_print_statistics (void)
{
  fprintf (stderr, "%-32s" PRsa (11) "\n", "SSA_NAME nodes allocated:",
	   SIZE_AMOUNT (ssa_name_nodes_created));
  fprintf (stderr, "%-32s" PRsa (11) "\n", "SSA_NAME nodes reused:",
	   SIZE_AMOUNT (ssa_name_nodes_reused));
}

/* Verify the state of the SSA_NAME lists.

   There must be no duplicates on the free list.
   Every name on the free list must be marked as on the free list.
   Any name on the free list must not appear in the IL.
   No names can be leaked.  */

DEBUG_FUNCTION void
verify_ssaname_freelists (struct function *fun)
{
  if (!gimple_in_ssa_p (fun))
    return;

  auto_bitmap names_in_il;

  /* Walk the entire IL noting every SSA_NAME we see.  */
  basic_block bb;
  FOR_EACH_BB_FN (bb, fun)
    {
      tree t;
      /* First note the result and arguments of PHI nodes.  */
      for (gphi_iterator gsi = gsi_start_phis (bb);
	   !gsi_end_p (gsi);
	   gsi_next (&gsi))
	{
	  gphi *phi = gsi.phi ();
	  t = gimple_phi_result (phi);
	  bitmap_set_bit (names_in_il, SSA_NAME_VERSION (t));

	  for (unsigned int i = 0; i < gimple_phi_num_args (phi); i++)
	    {
	      t = gimple_phi_arg_def (phi, i);
	      if (TREE_CODE (t) == SSA_NAME)
		bitmap_set_bit (names_in_il, SSA_NAME_VERSION (t));
	    }
	}

      /* Then note the operands of each statement.  */
      for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
	   !gsi_end_p (gsi);
	   gsi_next (&gsi))
	{
	  ssa_op_iter iter;
	  gimple *stmt = gsi_stmt (gsi);
	  FOR_EACH_SSA_TREE_OPERAND (t, stmt, iter, SSA_OP_ALL_OPERANDS)
	    bitmap_set_bit (names_in_il, SSA_NAME_VERSION (t));
	}
    }

  /* Now walk the free list noting what we find there and verifying
     there are no duplicates.  */
  auto_bitmap names_in_freelists;
  if (FREE_SSANAMES (fun))
    {
      for (unsigned int i = 0; i < FREE_SSANAMES (fun)->length (); i++)
	{
	  tree t = (*FREE_SSANAMES (fun))[i];

	  /* Verify that the name is marked as being in the free list.  */
	  gcc_assert (SSA_NAME_IN_FREE_LIST (t));

	  /* Verify the name has not already appeared in the free list and
	     note it in the list of names found in the free list.  */
	  gcc_assert (!bitmap_bit_p (names_in_freelists, SSA_NAME_VERSION (t)));
	  bitmap_set_bit (names_in_freelists, SSA_NAME_VERSION (t));
	}
    }

  /* Similarly for the names in the pending free list.  */
  if (FREE_SSANAMES_QUEUE (fun))
    {
      for (unsigned int i = 0; i < FREE_SSANAMES_QUEUE (fun)->length (); i++)
	{
	  tree t = (*FREE_SSANAMES_QUEUE (fun))[i];

	  /* Verify that the name is marked as being in the free list.  */
	  gcc_assert (SSA_NAME_IN_FREE_LIST (t));

	  /* Verify the name has not already appeared in the free list and
	     note it in the list of names found in the free list.  */
	  gcc_assert (!bitmap_bit_p (names_in_freelists, SSA_NAME_VERSION (t)));
	  bitmap_set_bit (names_in_freelists, SSA_NAME_VERSION (t));
	}
    }

  /* If any name appears in both the IL and the freelists, then
     something horrible has happened.  */
  bool intersect_p = bitmap_intersect_p (names_in_il, names_in_freelists);
  gcc_assert (!intersect_p);

  /* Names can be queued up for release if there is an ssa update
     pending.  Pretend we saw them in the IL.  */
  if (names_to_release)
    bitmap_ior_into (names_in_il, names_to_release);

  /* Function splitting can "lose" SSA_NAMEs in an effort to ensure that
     debug/non-debug compilations have the same SSA_NAMEs.  So for each
     lost SSA_NAME, see if it's likely one from that wart.  These will always
     be marked as default definitions.  So we loosely assume that anything
     marked as a default definition isn't leaked by pretending they are
     in the IL.  */
  for (unsigned int i = UNUSED_NAME_VERSION + 1; i < num_ssa_names; i++)
    if (ssa_name (i) && SSA_NAME_IS_DEFAULT_DEF (ssa_name (i)))
      bitmap_set_bit (names_in_il, i);

  unsigned int i;
  bitmap_iterator bi;
  auto_bitmap all_names;
  bitmap_set_range (all_names, UNUSED_NAME_VERSION + 1, num_ssa_names - 1);
  bitmap_ior_into (names_in_il, names_in_freelists);

  /* Any name not mentioned in the IL and not in the feelists
     has been leaked.  */
  EXECUTE_IF_AND_COMPL_IN_BITMAP(all_names, names_in_il,
				 UNUSED_NAME_VERSION + 1, i, bi)
    gcc_assert (!ssa_name (i));
}

/* Move all SSA_NAMEs from FREE_SSA_NAMES_QUEUE to FREE_SSA_NAMES.

   We do not, but should have a mode to verify the state of the SSA_NAMEs
   lists.  In particular at this point every name must be in the IL,
   on the free list or in the queue.  Anything else is an error.  */

void
flush_ssaname_freelist (void)
{
  /* If there were any SSA names released reset the SCEV cache.  */
  if (! vec_safe_is_empty (FREE_SSANAMES_QUEUE (cfun)))
    scev_reset_htab ();
  vec_safe_splice (FREE_SSANAMES (cfun), FREE_SSANAMES_QUEUE (cfun));
  vec_safe_truncate (FREE_SSANAMES_QUEUE (cfun), 0);
}

/* Initialize SSA_NAME_IMM_USE_NODE of a SSA NAME.  */

void
init_ssa_name_imm_use (tree name)
{
  use_operand_p imm;
  imm = &(SSA_NAME_IMM_USE_NODE (name));
  imm->use = NULL;
  imm->prev = imm;
  imm->next = imm;
  imm->loc.ssa_name = name;
}

/* Return an SSA_NAME node for variable VAR defined in statement STMT
   in function FN.  STMT may be an empty statement for artificial
   references (e.g., default definitions created when a variable is
   used without a preceding definition).  If VERISON is not zero then
   allocate the SSA name with that version.  */

tree
make_ssa_name_fn (struct function *fn, tree var, gimple *stmt,
		  unsigned int version)
{
  tree t;
  gcc_assert (VAR_P (var)
	      || TREE_CODE (var) == PARM_DECL
	      || TREE_CODE (var) == RESULT_DECL
	      || (TYPE_P (var) && is_gimple_reg_type (var)));

  /* Get the specified SSA name version.  */
  if (version != 0)
    {
      t = make_node (SSA_NAME);
      SSA_NAME_VERSION (t) = version;
      if (version >= SSANAMES (fn)->length ())
	vec_safe_grow_cleared (SSANAMES (fn), version + 1, true);
      gcc_assert ((*SSANAMES (fn))[version] == NULL);
      (*SSANAMES (fn))[version] = t;
      ssa_name_nodes_created++;
    }
  /* If our free list has an element, then use it.  */
  else if (!vec_safe_is_empty (FREE_SSANAMES (fn)))
    {
      t = FREE_SSANAMES (fn)->pop ();
      ssa_name_nodes_reused++;

      /* The node was cleared out when we put it on the free list, so
	 there is no need to do so again here.  */
      gcc_assert ((*SSANAMES (fn))[SSA_NAME_VERSION (t)] == NULL);
      (*SSANAMES (fn))[SSA_NAME_VERSION (t)] = t;
    }
  else
    {
      t = make_node (SSA_NAME);
      SSA_NAME_VERSION (t) = SSANAMES (fn)->length ();
      vec_safe_push (SSANAMES (fn), t);
      ssa_name_nodes_created++;
    }

  if (TYPE_P (var))
    {
      TREE_TYPE (t) = TYPE_MAIN_VARIANT (var);
      SET_SSA_NAME_VAR_OR_IDENTIFIER (t, NULL_TREE);
    }
  else
    {
      TREE_TYPE (t) = TREE_TYPE (var);
      SET_SSA_NAME_VAR_OR_IDENTIFIER (t, var);
    }
  SSA_NAME_DEF_STMT (t) = stmt;
  if (POINTER_TYPE_P (TREE_TYPE (t)))
    SSA_NAME_PTR_INFO (t) = NULL;
  else
    SSA_NAME_RANGE_INFO (t) = NULL;

  SSA_NAME_IN_FREE_LIST (t) = 0;
  SSA_NAME_IS_DEFAULT_DEF (t) = 0;
  init_ssa_name_imm_use (t);

  return t;
}

/* Helper function for set_range_info.

   Store range information RANGE_TYPE, MIN, and MAX to tree ssa_name
   NAME.  */

void
set_range_info_raw (tree name, enum value_range_kind range_type,
		    const wide_int_ref &min, const wide_int_ref &max)
{
  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
  gcc_assert (range_type == VR_RANGE || range_type == VR_ANTI_RANGE);
  range_info_def *ri = SSA_NAME_RANGE_INFO (name);
  unsigned int precision = TYPE_PRECISION (TREE_TYPE (name));

  /* Allocate if not available.  */
  if (ri == NULL)
    {
      size_t size = (sizeof (range_info_def)
		     + trailing_wide_ints <3>::extra_size (precision));
      ri = static_cast<range_info_def *> (ggc_internal_alloc (size));
      ri->ints.set_precision (precision);
      SSA_NAME_RANGE_INFO (name) = ri;
      ri->set_nonzero_bits (wi::shwi (-1, precision));
    }

  /* Record the range type.  */
  if (SSA_NAME_RANGE_TYPE (name) != range_type)
    SSA_NAME_ANTI_RANGE_P (name) = (range_type == VR_ANTI_RANGE);

  /* Set the values.  */
  ri->set_min (min);
  ri->set_max (max);

  /* If it is a range, try to improve nonzero_bits from the min/max.  */
  if (range_type == VR_RANGE)
    {
      wide_int xorv = ri->get_min () ^ ri->get_max ();
      if (xorv != 0)
	xorv = wi::mask (precision - wi::clz (xorv), false, precision);
      ri->set_nonzero_bits (ri->get_nonzero_bits () & (ri->get_min () | xorv));
    }
}

/* Store range information RANGE_TYPE, MIN, and MAX to tree ssa_name
   NAME while making sure we don't store useless range info.  */

void
set_range_info (tree name, enum value_range_kind range_type,
		const wide_int_ref &min, const wide_int_ref &max)
{
  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));

  /* A range of the entire domain is really no range at all.  */
  tree type = TREE_TYPE (name);
  if (min == wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type))
      && max == wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type)))
    {
      range_info_def *ri = SSA_NAME_RANGE_INFO (name);
      if (ri == NULL)
	return;
      if (ri->get_nonzero_bits () == -1)
	{
	  ggc_free (ri);
	  SSA_NAME_RANGE_INFO (name) = NULL;
	  return;
	}
    }

  set_range_info_raw (name, range_type, min, max);
}

/* Store range information for NAME from a value_range.  */

void
set_range_info (tree name, const value_range &vr)
{
  wide_int min = wi::to_wide (vr.min ());
  wide_int max = wi::to_wide (vr.max ());
  set_range_info (name, vr.kind (), min, max);
}

/* Set nonnull attribute to pointer NAME.  */

void
set_ptr_nonnull (tree name)
{
  gcc_assert (POINTER_TYPE_P (TREE_TYPE (name)));
  struct ptr_info_def *pi = get_ptr_info (name);
  pi->pt.null = 0;
}

/* Change non-zero bits bitmask of NAME.  */

void
set_nonzero_bits (tree name, const wide_int_ref &mask)
{
  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
  if (SSA_NAME_RANGE_INFO (name) == NULL)
    {
      if (mask == -1)
	return;
      set_range_info_raw (name, VR_RANGE,
			  wi::to_wide (TYPE_MIN_VALUE (TREE_TYPE (name))),
			  wi::to_wide (TYPE_MAX_VALUE (TREE_TYPE (name))));
    }
  range_info_def *ri = SSA_NAME_RANGE_INFO (name);
  ri->set_nonzero_bits (mask);
}

/* Return a widest_int with potentially non-zero bits in SSA_NAME
   NAME, the constant for INTEGER_CST, or -1 if unknown.  */

wide_int
get_nonzero_bits (const_tree name)
{
  if (TREE_CODE (name) == INTEGER_CST)
    return wi::to_wide (name);

  /* Use element_precision instead of TYPE_PRECISION so complex and
     vector types get a non-zero precision.  */
  unsigned int precision = element_precision (TREE_TYPE (name));
  if (POINTER_TYPE_P (TREE_TYPE (name)))
    {
      struct ptr_info_def *pi = SSA_NAME_PTR_INFO (name);
      if (pi && pi->align)
	return wi::shwi (-(HOST_WIDE_INT) pi->align
			 | (HOST_WIDE_INT) pi->misalign, precision);
      return wi::shwi (-1, precision);
    }

  range_info_def *ri = SSA_NAME_RANGE_INFO (name);
  if (!ri)
    return wi::shwi (-1, precision);

  return ri->get_nonzero_bits ();
}

/* Return TRUE is OP, an SSA_NAME has a range of values [0..1], false
   otherwise.

   This can be because it is a boolean type, any unsigned integral
   type with a single bit of precision, or has known range of [0..1]
   via range analysis.  */

bool
ssa_name_has_boolean_range (tree op)
{
  gcc_assert (TREE_CODE (op) == SSA_NAME);

  /* Boolean types always have a range [0..1].  */
  if (TREE_CODE (TREE_TYPE (op)) == BOOLEAN_TYPE)
    return true;

  /* An integral type with a single bit of precision.  */
  if (INTEGRAL_TYPE_P (TREE_TYPE (op))
      && TYPE_UNSIGNED (TREE_TYPE (op))
      && TYPE_PRECISION (TREE_TYPE (op)) == 1)
    return true;

  /* An integral type with more precision, but the object
     only takes on values [0..1] as determined by range
     analysis.  */
  if (INTEGRAL_TYPE_P (TREE_TYPE (op))
      && (TYPE_PRECISION (TREE_TYPE (op)) > 1))
    {
      int_range<2> onezero (build_zero_cst (TREE_TYPE (op)),
			    build_one_cst (TREE_TYPE (op)));
      int_range<2> r;
      if (get_range_query (cfun)->range_of_expr (r, op) && r == onezero)
	return true;

      if (wi::eq_p (get_nonzero_bits (op), 1))
	return true;
    }

  return false;
}

/* We no longer need the SSA_NAME expression VAR, release it so that
   it may be reused.

   Note it is assumed that no calls to make_ssa_name will be made
   until all uses of the ssa name are released and that the only
   use of the SSA_NAME expression is to check its SSA_NAME_VAR.  All
   other fields must be assumed clobbered.  */

void
release_ssa_name_fn (struct function *fn, tree var)
{
  if (!var)
    return;

  /* Never release the default definition for a symbol.  It's a
     special SSA name that should always exist once it's created.  */
  if (SSA_NAME_IS_DEFAULT_DEF (var))
    return;

  /* If VAR has been registered for SSA updating, don't remove it.
     After update_ssa has run, the name will be released.  */
  if (name_registered_for_update_p (var))
    {
      release_ssa_name_after_update_ssa (var);
      return;
    }

  /* release_ssa_name can be called multiple times on a single SSA_NAME.
     However, it should only end up on our free list one time.   We
     keep a status bit in the SSA_NAME node itself to indicate it has
     been put on the free list.

     Note that once on the freelist you cannot reference the SSA_NAME's
     defining statement.  */
  if (! SSA_NAME_IN_FREE_LIST (var))
    {
      int saved_ssa_name_version = SSA_NAME_VERSION (var);
      use_operand_p imm = &(SSA_NAME_IMM_USE_NODE (var));

      if (MAY_HAVE_DEBUG_BIND_STMTS)
	insert_debug_temp_for_var_def (NULL, var);

      if (flag_checking)
	verify_imm_links (stderr, var);
      while (imm->next != imm)
	delink_imm_use (imm->next);

      (*SSANAMES (fn))[SSA_NAME_VERSION (var)] = NULL_TREE;
      memset (var, 0, tree_size (var));

      imm->prev = imm;
      imm->next = imm;
      imm->loc.ssa_name = var;

      /* First put back the right tree node so that the tree checking
	 macros do not complain.  */
      TREE_SET_CODE (var, SSA_NAME);

      /* Restore the version number.  */
      SSA_NAME_VERSION (var) = saved_ssa_name_version;

      /* Note this SSA_NAME is now in the first list.  */
      SSA_NAME_IN_FREE_LIST (var) = 1;

      /* Put in a non-NULL TREE_TYPE so dumping code will not ICE
         if it happens to come along a released SSA name and tries
	 to inspect its type.  */
      TREE_TYPE (var) = error_mark_node;

      /* And finally queue it so that it will be put on the free list.  */
      vec_safe_push (FREE_SSANAMES_QUEUE (fn), var);
    }
}

/* If the alignment of the pointer described by PI is known, return true and
   store the alignment and the deviation from it into *ALIGNP and *MISALIGNP
   respectively.  Otherwise return false.  */

bool
get_ptr_info_alignment (struct ptr_info_def *pi, unsigned int *alignp,
			unsigned int *misalignp)
{
  if (pi->align)
    {
      *alignp = pi->align;
      *misalignp = pi->misalign;
      return true;
    }
  else
    return false;
}

/* State that the pointer described by PI has unknown alignment.  */

void
mark_ptr_info_alignment_unknown (struct ptr_info_def *pi)
{
  pi->align = 0;
  pi->misalign = 0;
}

/* Store the power-of-two byte alignment and the deviation from that
   alignment of pointer described by PI to ALIOGN and MISALIGN
   respectively.  */

void
set_ptr_info_alignment (struct ptr_info_def *pi, unsigned int align,
			    unsigned int misalign)
{
  gcc_checking_assert (align != 0);
  gcc_assert ((align & (align - 1)) == 0);
  gcc_assert ((misalign & ~(align - 1)) == 0);

  pi->align = align;
  pi->misalign = misalign;
}

/* If pointer described by PI has known alignment, increase its known
   misalignment by INCREMENT modulo its current alignment.  */

void
adjust_ptr_info_misalignment (struct ptr_info_def *pi, poly_uint64 increment)
{
  if (pi->align != 0)
    {
      increment += pi->misalign;
      if (!known_misalignment (increment, pi->align, &pi->misalign))
	{
	  pi->align = known_alignment (increment);
	  pi->misalign = 0;
	}
    }
}

/* Return the alias information associated with pointer T.  It creates a
   new instance if none existed.  */

struct ptr_info_def *
get_ptr_info (tree t)
{
  struct ptr_info_def *pi;

  gcc_assert (POINTER_TYPE_P (TREE_TYPE (t)));

  pi = SSA_NAME_PTR_INFO (t);
  if (pi == NULL)
    {
      pi = ggc_cleared_alloc<ptr_info_def> ();
      pt_solution_reset (&pi->pt);
      mark_ptr_info_alignment_unknown (pi);
      SSA_NAME_PTR_INFO (t) = pi;
    }

  return pi;
}


/* Creates a new SSA name using the template NAME tobe defined by
   statement STMT in function FN.  */

tree
copy_ssa_name_fn (struct function *fn, tree name, gimple *stmt)
{
  tree new_name;

  if (SSA_NAME_VAR (name))
    new_name = make_ssa_name_fn (fn, SSA_NAME_VAR (name), stmt);
  else
    {
      new_name = make_ssa_name_fn (fn, TREE_TYPE (name), stmt);
      SET_SSA_NAME_VAR_OR_IDENTIFIER (new_name, SSA_NAME_IDENTIFIER (name));
    }

  return new_name;
}


/* Creates a duplicate of the ptr_info_def at PTR_INFO for use by
   the SSA name NAME.  */

void
duplicate_ssa_name_ptr_info (tree name, struct ptr_info_def *ptr_info)
{
  struct ptr_info_def *new_ptr_info;

  gcc_assert (POINTER_TYPE_P (TREE_TYPE (name)));
  gcc_assert (!SSA_NAME_PTR_INFO (name));

  if (!ptr_info)
    return;

  new_ptr_info = ggc_alloc<ptr_info_def> ();
  *new_ptr_info = *ptr_info;

  SSA_NAME_PTR_INFO (name) = new_ptr_info;
}

/* Creates a duplicate of the range_info_def at RANGE_INFO of type
   RANGE_TYPE for use by the SSA name NAME.  */
void
duplicate_ssa_name_range_info (tree name, enum value_range_kind range_type,
			       struct range_info_def *range_info)
{
  struct range_info_def *new_range_info;

  gcc_assert (!POINTER_TYPE_P (TREE_TYPE (name)));
  gcc_assert (!SSA_NAME_RANGE_INFO (name));

  if (!range_info)
    return;

  unsigned int precision = TYPE_PRECISION (TREE_TYPE (name));
  size_t size = (sizeof (range_info_def)
		 + trailing_wide_ints <3>::extra_size (precision));
  new_range_info = static_cast<range_info_def *> (ggc_internal_alloc (size));
  memcpy (new_range_info, range_info, size);

  gcc_assert (range_type == VR_RANGE || range_type == VR_ANTI_RANGE);
  SSA_NAME_ANTI_RANGE_P (name) = (range_type == VR_ANTI_RANGE);
  SSA_NAME_RANGE_INFO (name) = new_range_info;
}



/* Creates a duplicate of a ssa name NAME tobe defined by statement STMT
   in function FN.  */

tree
duplicate_ssa_name_fn (struct function *fn, tree name, gimple *stmt)
{
  tree new_name = copy_ssa_name_fn (fn, name, stmt);
  if (POINTER_TYPE_P (TREE_TYPE (name)))
    {
      struct ptr_info_def *old_ptr_info = SSA_NAME_PTR_INFO (name);

      if (old_ptr_info)
	duplicate_ssa_name_ptr_info (new_name, old_ptr_info);
    }
  else
    {
      struct range_info_def *old_range_info = SSA_NAME_RANGE_INFO (name);

      if (old_range_info)
	duplicate_ssa_name_range_info (new_name, SSA_NAME_RANGE_TYPE (name),
				       old_range_info);
    }

  return new_name;
}


/* Reset all flow sensitive data on NAME such as range-info, nonzero
   bits and alignment.  */

void
reset_flow_sensitive_info (tree name)
{
  if (POINTER_TYPE_P (TREE_TYPE (name)))
    {
      /* points-to info is not flow-sensitive.  */
      if (SSA_NAME_PTR_INFO (name))
	{
	  /* [E]VRP can derive context sensitive alignment info and
	     non-nullness properties.  We must reset both.  */
	  mark_ptr_info_alignment_unknown (SSA_NAME_PTR_INFO (name));
	  SSA_NAME_PTR_INFO (name)->pt.null = 1;
	}
    }
  else
    SSA_NAME_RANGE_INFO (name) = NULL;
}

/* Clear all flow sensitive data from all statements and PHI definitions
   in BB.  */

void
reset_flow_sensitive_info_in_bb (basic_block bb)
{
  for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
       gsi_next (&gsi))
    {
      gimple *stmt = gsi_stmt (gsi);
      ssa_op_iter i;
      tree op;
      FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_DEF)
	reset_flow_sensitive_info (op);
    }

  for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
       gsi_next (&gsi))
    {
      tree phi_def = gimple_phi_result (gsi.phi ());
      reset_flow_sensitive_info (phi_def);
    }
}

/* Release all the SSA_NAMEs created by STMT.  */

void
release_defs (gimple *stmt)
{
  tree def;
  ssa_op_iter iter;

  FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
    if (TREE_CODE (def) == SSA_NAME)
      release_ssa_name (def);
}


/* Replace the symbol associated with SSA_NAME with SYM.  */

void
replace_ssa_name_symbol (tree ssa_name, tree sym)
{
  SET_SSA_NAME_VAR_OR_IDENTIFIER (ssa_name, sym);
  TREE_TYPE (ssa_name) = TREE_TYPE (sym);
}

/* Release the vector of free SSA_NAMEs and compact the vector of SSA_NAMEs
   that are live.  */

static void
release_free_names_and_compact_live_names (function *fun)
{
  unsigned i, j;
  int n = vec_safe_length (FREE_SSANAMES (fun));

  /* Now release the freelist.  */
  vec_free (FREE_SSANAMES (fun));

  /* And compact the SSA number space.  We make sure to not change the
     relative order of SSA versions.  */
  for (i = 1, j = 1; i < fun->gimple_df->ssa_names->length (); ++i)
    {
      tree name = ssa_name (i);
      if (name)
	{
	  if (i != j)
	    {
	      SSA_NAME_VERSION (name) = j;
	      (*fun->gimple_df->ssa_names)[j] = name;
	    }
	  j++;
	}
    }
  fun->gimple_df->ssa_names->truncate (j);

  statistics_counter_event (fun, "SSA names released", n);
  statistics_counter_event (fun, "SSA name holes removed", i - j);
  if (dump_file)
    fprintf (dump_file, "Released %i names, %.2f%%, removed %i holes\n",
	     n, n * 100.0 / num_ssa_names, i - j);
}

/* Return SSA names that are unused to GGC memory and compact the SSA
   version namespace.  This is used to keep footprint of compiler during
   interprocedural optimization.  */

namespace {

const pass_data pass_data_release_ssa_names =
{
  GIMPLE_PASS, /* type */
  "release_ssa", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_TREE_SSA_OTHER, /* tv_id */
  PROP_ssa, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  TODO_remove_unused_locals, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_release_ssa_names : public gimple_opt_pass
{
public:
  pass_release_ssa_names (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_release_ssa_names, ctxt)
  {}

  /* opt_pass methods: */
  virtual unsigned int execute (function *);

}; // class pass_release_ssa_names

unsigned int
pass_release_ssa_names::execute (function *fun)
{
  release_free_names_and_compact_live_names (fun);
  return 0;
}

} // anon namespace

gimple_opt_pass *
make_pass_release_ssa_names (gcc::context *ctxt)
{
  return new pass_release_ssa_names (ctxt);
}
