/* Liveness for SSA trees.
   Copyright (C) 2003-2022 Free Software Foundation, Inc.
   Contributed by Andrew MacLeod <amacleod@redhat.com>

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 "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "timevar.h"
#include "ssa.h"
#include "cgraph.h"
#include "gimple-pretty-print.h"
#include "diagnostic-core.h"
#include "gimple-iterator.h"
#include "tree-dfa.h"
#include "dumpfile.h"
#include "tree-ssa-live.h"
#include "debug.h"
#include "tree-ssa.h"
#include "ipa-utils.h"
#include "cfgloop.h"
#include "stringpool.h"
#include "attribs.h"
#include "optinfo.h"
#include "gimple-walk.h"
#include "cfganal.h"

static void verify_live_on_entry (tree_live_info_p);


/* VARMAP maintains a mapping from SSA version number to real variables.

   All SSA_NAMES are divided into partitions.  Initially each ssa_name is the
   only member of it's own partition.  Coalescing will attempt to group any
   ssa_names which occur in a copy or in a PHI node into the same partition.

   At the end of out-of-ssa, each partition becomes a "real" variable and is
   rewritten as a compiler variable.

   The var_map data structure is used to manage these partitions.  It allows
   partitions to be combined, and determines which partition belongs to what
   ssa_name or variable, and vice versa.  */


/* Remove the base table in MAP.  */

static void
var_map_base_fini (var_map map)
{
  /* Free the basevar info if it is present.  */
  if (map->partition_to_base_index != NULL)
    {
      free (map->partition_to_base_index);
      map->partition_to_base_index = NULL;
      map->num_basevars = 0;
    }
}
/* Create a variable partition map of SIZE for region, initialize and return
   it.  Region is a loop if LOOP is non-NULL, otherwise is the current
   function.  */

var_map
init_var_map (int size, class loop *loop)
{
  var_map map;

  map = (var_map) xmalloc (sizeof (struct _var_map));
  map->var_partition = partition_new (size);

  map->partition_to_view = NULL;
  map->view_to_partition = NULL;
  map->num_partitions = size;
  map->partition_size = size;
  map->num_basevars = 0;
  map->partition_to_base_index = NULL;
  map->vec_bbs = vNULL;
  if (loop)
    {
      map->bmp_bbs = BITMAP_ALLOC (NULL);
      map->outofssa_p = false;
      basic_block *bbs = get_loop_body_in_dom_order (loop);
      for (unsigned i = 0; i < loop->num_nodes; ++i)
	{
	  bitmap_set_bit (map->bmp_bbs, bbs[i]->index);
	  map->vec_bbs.safe_push (bbs[i]);
	}
      free (bbs);
    }
  else
    {
      map->bmp_bbs = NULL;
      map->outofssa_p = true;
      basic_block bb;
      FOR_EACH_BB_FN (bb, cfun)
	map->vec_bbs.safe_push (bb);
    }
  return map;
}


/* Free memory associated with MAP.  */

void
delete_var_map (var_map map)
{
  var_map_base_fini (map);
  partition_delete (map->var_partition);
  free (map->partition_to_view);
  free (map->view_to_partition);
  if (map->bmp_bbs)
    BITMAP_FREE (map->bmp_bbs);
  map->vec_bbs.release ();
  free (map);
}


/* This function will combine the partitions in MAP for VAR1 and VAR2.  It
   Returns the partition which represents the new partition.  If the two
   partitions cannot be combined, NO_PARTITION is returned.  */

int
var_union (var_map map, tree var1, tree var2)
{
  int p1, p2, p3;

  gcc_assert (TREE_CODE (var1) == SSA_NAME);
  gcc_assert (TREE_CODE (var2) == SSA_NAME);

  /* This is independent of partition_to_view. If partition_to_view is
     on, then whichever one of these partitions is absorbed will never have a
     dereference into the partition_to_view array any more.  */

  p1 = partition_find (map->var_partition, SSA_NAME_VERSION (var1));
  p2 = partition_find (map->var_partition, SSA_NAME_VERSION (var2));

  gcc_assert (p1 != NO_PARTITION);
  gcc_assert (p2 != NO_PARTITION);

  if (p1 == p2)
    p3 = p1;
  else
    p3 = partition_union (map->var_partition, p1, p2);

  if (map->partition_to_view)
    p3 = map->partition_to_view[p3];

  return p3;
}


/* Compress the partition numbers in MAP such that they fall in the range
   0..(num_partitions-1) instead of wherever they turned out during
   the partitioning exercise.  This removes any references to unused
   partitions, thereby allowing bitmaps and other vectors to be much
   denser.

   This is implemented such that compaction doesn't affect partitioning.
   Ie., once partitions are created and possibly merged, running one
   or more different kind of compaction will not affect the partitions
   themselves.  Their index might change, but all the same variables will
   still be members of the same partition group.  This allows work on reduced
   sets, and no loss of information when a larger set is later desired.

   In particular, coalescing can work on partitions which have 2 or more
   definitions, and then 'recompact' later to include all the single
   definitions for assignment to program variables.  */


/* Set MAP back to the initial state of having no partition view.  Return a
   bitmap which has a bit set for each partition number which is in use in the
   varmap.  */

static bitmap
partition_view_init (var_map map)
{
  bitmap used;
  int tmp;
  unsigned int x;

  used = BITMAP_ALLOC (NULL);

  /* Already in a view? Abandon the old one.  */
  if (map->partition_to_view)
    {
      free (map->partition_to_view);
      map->partition_to_view = NULL;
    }
  if (map->view_to_partition)
    {
      free (map->view_to_partition);
      map->view_to_partition = NULL;
    }

  /* Find out which partitions are actually referenced.  */
  for (x = 0; x < map->partition_size; x++)
    {
      tmp = partition_find (map->var_partition, x);
      if (ssa_name (tmp) != NULL_TREE && !virtual_operand_p (ssa_name (tmp))
	  && (!has_zero_uses (ssa_name (tmp))
	      || !SSA_NAME_IS_DEFAULT_DEF (ssa_name (tmp))
	      || (SSA_NAME_VAR (ssa_name (tmp))
		  && !VAR_P (SSA_NAME_VAR (ssa_name (tmp))))))
	bitmap_set_bit (used, tmp);
    }

  map->num_partitions = map->partition_size;
  return used;
}


/* This routine will finalize the view data for MAP based on the partitions
   set in SELECTED.  This is either the same bitmap returned from
   partition_view_init, or a trimmed down version if some of those partitions
   were not desired in this view.  SELECTED is freed before returning.  */

static void
partition_view_fini (var_map map, bitmap selected)
{
  bitmap_iterator bi;
  unsigned count, i, x, limit;

  gcc_assert (selected);

  count = bitmap_count_bits (selected);
  limit = map->partition_size;

  /* If its a one-to-one ratio, we don't need any view compaction.  */
  if (count < limit)
    {
      map->partition_to_view = (int *)xmalloc (limit * sizeof (int));
      memset (map->partition_to_view, 0xff, (limit * sizeof (int)));
      map->view_to_partition = (int *)xmalloc (count * sizeof (int));

      i = 0;
      /* Give each selected partition an index.  */
      EXECUTE_IF_SET_IN_BITMAP (selected, 0, x, bi)
	{
	  map->partition_to_view[x] = i;
	  map->view_to_partition[i] = x;
	  i++;
	}
      gcc_assert (i == count);
      map->num_partitions = i;
    }

  BITMAP_FREE (selected);
}


/* Create a partition view which includes all the used partitions in MAP.  */

void
partition_view_normal (var_map map)
{
  bitmap used;

  used = partition_view_init (map);
  partition_view_fini (map, used);

  var_map_base_fini (map);
}


/* Create a partition view in MAP which includes just partitions which occur in
   the bitmap ONLY. If WANT_BASES is true, create the base variable map
   as well.  */

void
partition_view_bitmap (var_map map, bitmap only)
{
  bitmap used;
  bitmap new_partitions = BITMAP_ALLOC (NULL);
  unsigned x, p;
  bitmap_iterator bi;

  used = partition_view_init (map);
  EXECUTE_IF_SET_IN_BITMAP (only, 0, x, bi)
    {
      p = partition_find (map->var_partition, x);
      gcc_assert (bitmap_bit_p (used, p));
      bitmap_set_bit (new_partitions, p);
    }
  partition_view_fini (map, new_partitions);

  var_map_base_fini (map);
}


static bitmap usedvars;

/* Mark VAR as used, so that it'll be preserved during rtl expansion.
   Returns true if VAR wasn't marked before.  */

static inline bool
set_is_used (tree var)
{
  return bitmap_set_bit (usedvars, DECL_UID (var));
}

/* Return true if VAR is marked as used.  */

static inline bool
is_used_p (tree var)
{
  return bitmap_bit_p (usedvars, DECL_UID (var));
}

static inline void mark_all_vars_used (tree *);

/* Helper function for mark_all_vars_used, called via walk_tree.  */

static tree
mark_all_vars_used_1 (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
{
  tree t = *tp;
  enum tree_code_class c = TREE_CODE_CLASS (TREE_CODE (t));
  tree b;

  if (TREE_CODE (t) == SSA_NAME)
    {
      *walk_subtrees = 0;
      t = SSA_NAME_VAR (t);
      if (!t)
	return NULL;
    }

  if (IS_EXPR_CODE_CLASS (c)
      && (b = TREE_BLOCK (t)) != NULL)
    TREE_USED (b) = true;

  /* Ignore TMR_OFFSET and TMR_STEP for TARGET_MEM_REFS, as those
     fields do not contain vars.  */
  if (TREE_CODE (t) == TARGET_MEM_REF)
    {
      mark_all_vars_used (&TMR_BASE (t));
      mark_all_vars_used (&TMR_INDEX (t));
      mark_all_vars_used (&TMR_INDEX2 (t));
      *walk_subtrees = 0;
      return NULL;
    }

  /* Only need to mark VAR_DECLS; parameters and return results are not
     eliminated as unused.  */
  if (VAR_P (t))
    {
      /* When a global var becomes used for the first time also walk its
         initializer (non global ones don't have any).  */
      if (set_is_used (t) && is_global_var (t)
	  && DECL_CONTEXT (t) == current_function_decl)
	mark_all_vars_used (&DECL_INITIAL (t));
    }
  /* remove_unused_scope_block_p requires information about labels
     which are not DECL_IGNORED_P to tell if they might be used in the IL.  */
  else if (TREE_CODE (t) == LABEL_DECL)
    /* Although the TREE_USED values that the frontend uses would be
       acceptable (albeit slightly over-conservative) for our purposes,
       init_vars_expansion clears TREE_USED for LABEL_DECLs too, so we
       must re-compute it here.  */
    TREE_USED (t) = 1;

  if (IS_TYPE_OR_DECL_P (t))
    *walk_subtrees = 0;

  return NULL;
}

/* Mark the scope block SCOPE and its subblocks unused when they can be
   possibly eliminated if dead.  */

static void
mark_scope_block_unused (tree scope)
{
  tree t;
  TREE_USED (scope) = false;
  if (!(*debug_hooks->ignore_block) (scope))
    TREE_USED (scope) = true;
  for (t = BLOCK_SUBBLOCKS (scope); t ; t = BLOCK_CHAIN (t))
    mark_scope_block_unused (t);
}

/* Look if the block is dead (by possibly eliminating its dead subblocks)
   and return true if so.
   Block is declared dead if:
     1) No statements are associated with it.
     2) Declares no live variables
     3) All subblocks are dead
	or there is precisely one subblocks and the block
	has same abstract origin as outer block and declares
	no variables, so it is pure wrapper.
   When we are not outputting full debug info, we also eliminate dead variables
   out of scope blocks to let them to be recycled by GGC and to save copying work
   done by the inliner.  */

static bool
remove_unused_scope_block_p (tree scope, bool in_ctor_dtor_block)
{
  tree *t, *next;
  bool unused = !TREE_USED (scope);
  int nsubblocks = 0;

  /* For ipa-polymorphic-call.cc purposes, preserve blocks:
     1) with BLOCK_ABSTRACT_ORIGIN of a ctor/dtor or their clones  */
  if (inlined_polymorphic_ctor_dtor_block_p (scope, true))
    {
      in_ctor_dtor_block = true;
      unused = false;
    }
  /* 2) inside such blocks, the outermost block with block_ultimate_origin
     being a FUNCTION_DECL.  */
  else if (in_ctor_dtor_block)
    {
      tree fn = block_ultimate_origin (scope);
      if (fn && TREE_CODE (fn) == FUNCTION_DECL)
	{
	  in_ctor_dtor_block = false;
	  unused = false;
	}
    }

  for (t = &BLOCK_VARS (scope); *t; t = next)
    {
      next = &DECL_CHAIN (*t);

      /* Debug info of nested function refers to the block of the
	 function.  We might stil call it even if all statements
	 of function it was nested into was elliminated.

	 TODO: We can actually look into cgraph to see if function
	 will be output to file.  */
      if (TREE_CODE (*t) == FUNCTION_DECL)
	unused = false;

      /* If a decl has a value expr, we need to instantiate it
	 regardless of debug info generation, to avoid codegen
	 differences in memory overlap tests.  update_equiv_regs() may
	 indirectly call validate_equiv_mem() to test whether a
	 SET_DEST overlaps with others, and if the value expr changes
	 by virtual register instantiation, we may get end up with
	 different results.  */
      else if (VAR_P (*t) && DECL_HAS_VALUE_EXPR_P (*t))
	unused = false;

      /* Remove everything we don't generate debug info for.  */
      else if (DECL_IGNORED_P (*t))
	{
	  *t = DECL_CHAIN (*t);
	  next = t;
	}

      /* When we are outputting debug info, we usually want to output
	 info about optimized-out variables in the scope blocks.
	 Exception are the scope blocks not containing any instructions
	 at all so user can't get into the scopes at first place.  */
      else if (is_used_p (*t))
	unused = false;
      else if (TREE_CODE (*t) == LABEL_DECL && TREE_USED (*t))
	/* For labels that are still used in the IL, the decision to
	   preserve them must not depend DEBUG_INFO_LEVEL, otherwise we
	   risk having different ordering in debug vs.  non-debug builds
	   during inlining or versioning.
	   A label appearing here (we have already checked DECL_IGNORED_P)
	   should not be used in the IL unless it has been explicitly used
	   before, so we use TREE_USED as an approximation.  */
	/* In principle, we should do the same here as for the debug case
	   below, however, when debugging, there might be additional nested
	   levels that keep an upper level with a label live, so we have to
	   force this block to be considered used, too.  */
	unused = false;

      /* When we are not doing full debug info, we however can keep around
	 only the used variables for cfgexpand's memory packing saving quite
	 a lot of memory.

	 For sake of -g3, we keep around those vars but we don't count this as
	 use of block, so innermost block with no used vars and no instructions
	 can be considered dead.  We only want to keep around blocks user can
	 breakpoint into and ask about value of optimized out variables.

	 Similarly we need to keep around types at least until all
	 variables of all nested blocks are gone.  We track no
	 information on whether given type is used or not, so we have
	 to keep them even when not emitting debug information,
	 otherwise we may end up remapping variables and their (local)
	 types in different orders depending on whether debug
	 information is being generated.  */

      else if (TREE_CODE (*t) == TYPE_DECL
	       || debug_info_level == DINFO_LEVEL_NORMAL
	       || debug_info_level == DINFO_LEVEL_VERBOSE)
	;
      else
	{
	  *t = DECL_CHAIN (*t);
	  next = t;
	}
    }

  for (t = &BLOCK_SUBBLOCKS (scope); *t ;)
    if (remove_unused_scope_block_p (*t, in_ctor_dtor_block))
      {
	if (BLOCK_SUBBLOCKS (*t))
	  {
	    tree next = BLOCK_CHAIN (*t);
	    tree supercontext = BLOCK_SUPERCONTEXT (*t);

	    *t = BLOCK_SUBBLOCKS (*t);
	    while (BLOCK_CHAIN (*t))
	      {
	        BLOCK_SUPERCONTEXT (*t) = supercontext;
	        t = &BLOCK_CHAIN (*t);
	      }
	    BLOCK_CHAIN (*t) = next;
	    BLOCK_SUPERCONTEXT (*t) = supercontext;
	    t = &BLOCK_CHAIN (*t);
	    nsubblocks ++;
	  }
	else
	  *t = BLOCK_CHAIN (*t);
      }
    else
      {
        t = &BLOCK_CHAIN (*t);
	nsubblocks ++;
      }


   if (!unused)
     ;
   /* Outer scope is always used.  */
   else if (!BLOCK_SUPERCONTEXT (scope)
            || TREE_CODE (BLOCK_SUPERCONTEXT (scope)) == FUNCTION_DECL)
     unused = false;
   /* Innermost blocks with no live variables nor statements can be always
      eliminated.  */
   else if (!nsubblocks)
     ;
   /* When not generating debug info we can eliminate info on unused
      variables.  */
   else if (!flag_auto_profile
	    && debug_info_level == DINFO_LEVEL_NONE
	    && !optinfo_wants_inlining_info_p ())
     {
       /* Even for -g0 don't prune outer scopes from inlined functions,
	  otherwise late diagnostics from such functions will not be
	  emitted or suppressed properly.  */
       if (inlined_function_outer_scope_p (scope))
	 {
	   gcc_assert (TREE_CODE (BLOCK_ORIGIN (scope)) == FUNCTION_DECL);
	   unused = false;
	 }
     }
   else if (BLOCK_VARS (scope) || BLOCK_NUM_NONLOCALIZED_VARS (scope))
     unused = false;
   /* See if this block is important for representation of inlined
      function.  Inlined functions are always represented by block
      with block_ultimate_origin being set to FUNCTION_DECL and
      DECL_SOURCE_LOCATION set, unless they expand to nothing...  */
   else if (inlined_function_outer_scope_p (scope))
     unused = false;
   else
   /* Verfify that only blocks with source location set
      are entry points to the inlined functions.  */
     gcc_assert (LOCATION_LOCUS (BLOCK_SOURCE_LOCATION (scope))
		 == UNKNOWN_LOCATION);

   TREE_USED (scope) = !unused;
   return unused;
}

/* Mark all VAR_DECLS under *EXPR_P as used, so that they won't be
   eliminated during the tree->rtl conversion process.  */

static inline void
mark_all_vars_used (tree *expr_p)
{
  walk_tree (expr_p, mark_all_vars_used_1, NULL, NULL);
}

/* Helper function for clear_unused_block_pointer, called via walk_tree.  */

static tree
clear_unused_block_pointer_1 (tree *tp, int *, void *)
{
  if (EXPR_P (*tp) && TREE_BLOCK (*tp)
      && !TREE_USED (TREE_BLOCK (*tp)))
    TREE_SET_BLOCK (*tp, NULL);
  return NULL_TREE;
}

/* Set all block pointer in debug or clobber stmt to NULL if the block
   is unused, so that they will not be streamed out.  */

static void
clear_unused_block_pointer (void)
{
  basic_block bb;
  gimple_stmt_iterator gsi;

  FOR_EACH_BB_FN (bb, cfun)
    for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
      {
	unsigned i;
	tree b;
	gimple *stmt;

      next:
	stmt = gsi_stmt (gsi);
	if (!is_gimple_debug (stmt) && !gimple_clobber_p (stmt))
	  continue;
	b = gimple_block (stmt);
	if (b && !TREE_USED (b))
	  {
	    /* Elide debug marker stmts that have an associated BLOCK from an
	       inline instance removed with also the outermost scope BLOCK of
	       said inline instance removed.  If the outermost scope BLOCK of
	       said inline instance is preserved use that in place of the
	       removed BLOCK.  That keeps the marker associated to the correct
	       inline instance (or no inline instance in case it was not from
	       an inline instance).  */
	    if (gimple_debug_nonbind_marker_p (stmt)
		&& BLOCK_ABSTRACT_ORIGIN (b))
	      {
		while (TREE_CODE (b) == BLOCK
		       && !inlined_function_outer_scope_p (b))
		  b = BLOCK_SUPERCONTEXT (b);
		if (TREE_CODE (b) == BLOCK)
		  {
		    if (TREE_USED (b))
		      {
			gimple_set_block (stmt, b);
			continue;
		      }
		    gsi_remove (&gsi, true);
		    if (gsi_end_p (gsi))
		      break;
		    goto next;
		  }
	      }
	    gimple_set_block (stmt, NULL);
	  }
	for (i = 0; i < gimple_num_ops (stmt); i++)
	  walk_tree (gimple_op_ptr (stmt, i), clear_unused_block_pointer_1,
		     NULL, NULL);
      }
}

/* Dump scope blocks starting at SCOPE to FILE.  INDENT is the
   indentation level and FLAGS is as in print_generic_expr.  */

static void
dump_scope_block (FILE *file, int indent, tree scope, dump_flags_t flags)
{
  tree var, t;
  unsigned int i;

  fprintf (file, "\n%*s{ Scope block #%i%s",indent, "" , BLOCK_NUMBER (scope),
  	   TREE_USED (scope) ? "" : " (unused)");
  if (LOCATION_LOCUS (BLOCK_SOURCE_LOCATION (scope)) != UNKNOWN_LOCATION)
    {
      expanded_location s = expand_location (BLOCK_SOURCE_LOCATION (scope));
      fprintf (file, " %s:%i", s.file, s.line);
    }
  if (BLOCK_ABSTRACT_ORIGIN (scope))
    {
      tree origin = block_ultimate_origin (scope);
      if (origin)
	{
	  fprintf (file, " Originating from :");
	  if (DECL_P (origin))
	    print_generic_decl (file, origin, flags);
	  else
	    fprintf (file, "#%i", BLOCK_NUMBER (origin));
	}
    }
  if (BLOCK_FRAGMENT_ORIGIN (scope))
    fprintf (file, " Fragment of : #%i",
	     BLOCK_NUMBER (BLOCK_FRAGMENT_ORIGIN (scope)));
  else if (BLOCK_FRAGMENT_CHAIN (scope))
    {
      fprintf (file, " Fragment chain :");
      for (t = BLOCK_FRAGMENT_CHAIN (scope); t ;
	   t = BLOCK_FRAGMENT_CHAIN (t))
	fprintf (file, " #%i", BLOCK_NUMBER (t));
    }
  fprintf (file, " \n");
  for (var = BLOCK_VARS (scope); var; var = DECL_CHAIN (var))
    {
      fprintf (file, "%*s", indent, "");
      print_generic_decl (file, var, flags);
      fprintf (file, "\n");
    }
  for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (scope); i++)
    {
      fprintf (file, "%*s",indent, "");
      print_generic_decl (file, BLOCK_NONLOCALIZED_VAR (scope, i),
      			  flags);
      fprintf (file, " (nonlocalized)\n");
    }
  for (t = BLOCK_SUBBLOCKS (scope); t ; t = BLOCK_CHAIN (t))
    dump_scope_block (file, indent + 2, t, flags);
  fprintf (file, "\n%*s}\n",indent, "");
}

/* Dump the tree of lexical scopes starting at SCOPE to stderr.  FLAGS
   is as in print_generic_expr.  */

DEBUG_FUNCTION void
debug_scope_block (tree scope, dump_flags_t flags)
{
  dump_scope_block (stderr, 0, scope, flags);
}


/* Dump the tree of lexical scopes of current_function_decl to FILE.
   FLAGS is as in print_generic_expr.  */

void
dump_scope_blocks (FILE *file, dump_flags_t flags)
{
  dump_scope_block (file, 0, DECL_INITIAL (current_function_decl), flags);
}


/* Dump the tree of lexical scopes of current_function_decl to stderr.
   FLAGS is as in print_generic_expr.  */

DEBUG_FUNCTION void
debug_scope_blocks (dump_flags_t flags)
{
  dump_scope_blocks (stderr, flags);
}

/* Remove local variables that are not referenced in the IL.  */

void
remove_unused_locals (void)
{
  basic_block bb;
  tree var;
  unsigned srcidx, dstidx, num;
  bool have_local_clobbers = false;

  /* Removing declarations from lexical blocks when not optimizing is
     not only a waste of time, it actually causes differences in stack
     layout.  */
  if (!optimize)
    return;

  timevar_push (TV_REMOVE_UNUSED);

  mark_scope_block_unused (DECL_INITIAL (current_function_decl));

  usedvars = BITMAP_ALLOC (NULL);
  auto_bitmap useddebug;

  /* Walk the CFG marking all referenced symbols.  */
  FOR_EACH_BB_FN (bb, cfun)
    {
      gimple_stmt_iterator gsi;
      size_t i;
      edge_iterator ei;
      edge e;

      /* Walk the statements.  */
      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
	{
	  gimple *stmt = gsi_stmt (gsi);
	  tree b = gimple_block (stmt);

	  /* If we wanted to mark the block referenced by the inline
	     entry point marker as used, this would be a good spot to
	     do it.  If the block is not otherwise used, the stmt will
	     be cleaned up in clean_unused_block_pointer.  */
	  if (is_gimple_debug (stmt))
	    {
	      if (gimple_debug_bind_p (stmt))
		{
		  tree var = gimple_debug_bind_get_var  (stmt);
		  if (VAR_P (var))
		    {
		      if (!gimple_debug_bind_get_value (stmt))
			/* Run the 2nd phase.  */
			have_local_clobbers = true;
		      else
			bitmap_set_bit (useddebug, DECL_UID (var));
		    }
		}
	      continue;
	    }

	  if (gimple_clobber_p (stmt))
	    {
	      have_local_clobbers = true;
	      continue;
	    }

	  if (b)
	    TREE_USED (b) = true;

	  for (i = 0; i < gimple_num_ops (stmt); i++)
	    mark_all_vars_used (gimple_op_ptr (gsi_stmt (gsi), i));
	}

      for (gphi_iterator gpi = gsi_start_phis (bb);
	   !gsi_end_p (gpi);
	   gsi_next (&gpi))
        {
          use_operand_p arg_p;
          ssa_op_iter i;
	  tree def;
	  gphi *phi = gpi.phi ();

	  if (virtual_operand_p (gimple_phi_result (phi)))
	    continue;

	  def = gimple_phi_result (phi);
	  mark_all_vars_used (&def);

          FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_ALL_USES)
            {
	      tree arg = USE_FROM_PTR (arg_p);
	      int index = PHI_ARG_INDEX_FROM_USE (arg_p);
	      tree block =
		LOCATION_BLOCK (gimple_phi_arg_location (phi, index));
	      if (block != NULL)
		TREE_USED (block) = true;
	      mark_all_vars_used (&arg);
            }
        }

      FOR_EACH_EDGE (e, ei, bb->succs)
	if (LOCATION_BLOCK (e->goto_locus) != NULL)
	  TREE_USED (LOCATION_BLOCK (e->goto_locus)) = true;
    }

  /* We do a two-pass approach about the out-of-scope clobbers.  We want
     to remove them if they are the only references to a local variable,
     but we want to retain them when there's any other.  So the first pass
     ignores them, and the second pass (if there were any) tries to remove
     them.  */
  if (have_local_clobbers)
    FOR_EACH_BB_FN (bb, cfun)
      {
	gimple_stmt_iterator gsi;

	for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
	  {
	    gimple *stmt = gsi_stmt (gsi);
	    tree b = gimple_block (stmt);

	    if (gimple_clobber_p (stmt))
	      {
		tree lhs = gimple_assign_lhs (stmt);
		tree base = get_base_address (lhs);
		/* Remove clobbers referencing unused vars, or clobbers
		   with MEM_REF lhs referencing uninitialized pointers.  */
		if ((VAR_P (base) && !is_used_p (base))
		    || (TREE_CODE (lhs) == MEM_REF
			&& TREE_CODE (TREE_OPERAND (lhs, 0)) == SSA_NAME
			&& SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (lhs, 0))
			&& (TREE_CODE (SSA_NAME_VAR (TREE_OPERAND (lhs, 0)))
			    != PARM_DECL)))
		  {
		    unlink_stmt_vdef (stmt);
		    gsi_remove (&gsi, true);
		    release_defs (stmt);
		    continue;
		  }
		if (b)
		  TREE_USED (b) = true;
	      }
	    else if (gimple_debug_bind_p (stmt))
	      {
		tree var = gimple_debug_bind_get_var (stmt);
		if (VAR_P (var)
		    && !bitmap_bit_p (useddebug, DECL_UID (var))
		    && !is_used_p (var))
		  {
		    if (dump_file && (dump_flags & TDF_DETAILS))
		      fprintf (dump_file, "Dead debug bind reset to %u\n",
			       DECL_UID (var));
		    gsi_remove (&gsi, true);
		    continue;
		  }
	      }
	    gsi_next (&gsi);
	  }
      }

  if (cfun->has_simduid_loops)
    {
      for (auto loop : loops_list (cfun, 0))
	if (loop->simduid && !is_used_p (loop->simduid))
	  loop->simduid = NULL_TREE;
    }

  cfun->has_local_explicit_reg_vars = false;

  /* Remove unmarked local and global vars from local_decls.  */
  num = vec_safe_length (cfun->local_decls);
  for (srcidx = 0, dstidx = 0; srcidx < num; srcidx++)
    {
      var = (*cfun->local_decls)[srcidx];
      if (VAR_P (var))
	{
	  if (!is_used_p (var))
	    {
	      tree def;
	      if (cfun->nonlocal_goto_save_area
		  && TREE_OPERAND (cfun->nonlocal_goto_save_area, 0) == var)
		cfun->nonlocal_goto_save_area = NULL;
	      /* Release any default def associated with var.  */
	      if ((def = ssa_default_def (cfun, var)) != NULL_TREE)
		{
		  set_ssa_default_def (cfun, var, NULL_TREE);
		  release_ssa_name (def);
		}
	      continue;
	    }
	}
      if (VAR_P (var) && DECL_HARD_REGISTER (var) && !is_global_var (var))
	cfun->has_local_explicit_reg_vars = true;

      if (srcidx != dstidx)
	(*cfun->local_decls)[dstidx] = var;
      dstidx++;
    }
  if (dstidx != num)
    {
      statistics_counter_event (cfun, "unused VAR_DECLs removed", num - dstidx);
      cfun->local_decls->truncate (dstidx);
    }

  remove_unused_scope_block_p (DECL_INITIAL (current_function_decl),
			       polymorphic_ctor_dtor_p (current_function_decl,
							true) != NULL_TREE);
  clear_unused_block_pointer ();

  BITMAP_FREE (usedvars);

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Scope blocks after cleanups:\n");
      dump_scope_blocks (dump_file, dump_flags);
    }

  timevar_pop (TV_REMOVE_UNUSED);
}

/* Allocate and return a new live range information object base on MAP.  */

static tree_live_info_p
new_tree_live_info (var_map map)
{
  tree_live_info_p live;
  basic_block bb;

  live = XNEW (struct tree_live_info_d);
  live->map = map;
  live->num_blocks = last_basic_block_for_fn (cfun);

  bitmap_obstack_initialize (&live->livein_obstack);
  bitmap_obstack_initialize (&live->liveout_obstack);

  live->livein = XCNEWVEC (bitmap_head, last_basic_block_for_fn (cfun));
  live->liveout = XCNEWVEC (bitmap_head, last_basic_block_for_fn (cfun));
  for (unsigned i = 0; map->vec_bbs.iterate (i, &bb); ++i)
    {
      bitmap_initialize (&live->livein[bb->index], &live->livein_obstack);
      bitmap_initialize (&live->liveout[bb->index], &live->liveout_obstack);
    }

  live->work_stack = XNEWVEC (int, last_basic_block_for_fn (cfun));
  live->stack_top = live->work_stack;

  live->global = BITMAP_ALLOC (NULL);
  return live;
}


/* Free storage for live range info object LIVE.  */

void
delete_tree_live_info (tree_live_info_p live)
{
  if (live->livein)
    {
      bitmap_obstack_release (&live->livein_obstack);
      free (live->livein);
    }
  if (live->liveout)
    {
      bitmap_obstack_release (&live->liveout_obstack);
      free (live->liveout);
    }
  BITMAP_FREE (live->global);
  free (live->work_stack);
  free (live);
}


/* Visit basic block BB and propagate any required live on entry bits from
   LIVE into the predecessors.  VISITED is the bitmap of visited blocks.
   TMP is a temporary work bitmap which is passed in to avoid reallocating
   it each time.  */

static void
loe_visit_block (tree_live_info_p live, basic_block bb, sbitmap visited)
{
  edge e;
  bool change;
  edge_iterator ei;
  basic_block pred_bb;
  bitmap loe;

  gcc_checking_assert (!bitmap_bit_p (visited, bb->index));
  bitmap_set_bit (visited, bb->index);

  loe = live_on_entry (live, bb);

  FOR_EACH_EDGE (e, ei, bb->preds)
    {
      pred_bb = e->src;
      if (!region_contains_p (live->map, pred_bb))
	continue;
      /* Variables live-on-entry from BB that aren't defined in the
	 predecessor block.  This should be the live on entry vars to pred.
	 Note that liveout is the DEFs in a block while live on entry is
	 being calculated.
	 Add these bits to live-on-entry for the pred. if there are any
	 changes, and pred_bb has been visited already, add it to the
	 revisit stack.  */
      change = bitmap_ior_and_compl_into (live_on_entry (live, pred_bb),
					  loe, &live->liveout[pred_bb->index]);
      if (change
	  && bitmap_bit_p (visited, pred_bb->index))
	{
	  bitmap_clear_bit (visited, pred_bb->index);
	  *(live->stack_top)++ = pred_bb->index;
	}
    }
}


/* Using LIVE, fill in all the live-on-entry blocks between the defs and uses
   of all the variables.  */

static void
live_worklist (tree_live_info_p live)
{
  unsigned b;
  basic_block bb;
  auto_sbitmap visited (last_basic_block_for_fn (cfun) + 1);

  bitmap_clear (visited);

  /* Visit region's blocks in reverse order and propagate live on entry values
     into the predecessors blocks.  */
  for (unsigned i = live->map->vec_bbs.length () - 1;
       live->map->vec_bbs.iterate (i, &bb); --i)
    loe_visit_block (live, bb, visited);

  /* Process any blocks which require further iteration.  */
  while (live->stack_top != live->work_stack)
    {
      b = *--(live->stack_top);
      loe_visit_block (live, BASIC_BLOCK_FOR_FN (cfun, b), visited);
    }
}


/* Calculate the initial live on entry vector for SSA_NAME using immediate_use
   links.  Set the live on entry fields in LIVE.  Def's are marked temporarily
   in the liveout vector.  */

static void
set_var_live_on_entry (tree ssa_name, tree_live_info_p live)
{
  int p;
  gimple *stmt;
  use_operand_p use;
  basic_block def_bb = NULL;
  imm_use_iterator imm_iter;
  bool global = false;

  p = var_to_partition (live->map, ssa_name);
  if (p == NO_PARTITION)
    return;

  stmt = SSA_NAME_DEF_STMT (ssa_name);
  if (stmt)
    {
      def_bb = gimple_bb (stmt);
      /* Mark defs in liveout bitmap temporarily.  */
      if (def_bb && region_contains_p (live->map, def_bb))
	bitmap_set_bit (&live->liveout[def_bb->index], p);
    }
  else
    def_bb = ENTRY_BLOCK_PTR_FOR_FN (cfun);

  /* An undefined local variable does not need to be very alive.  */
  if (ssa_undefined_value_p (ssa_name, false))
    return;

  /* Visit each use of SSA_NAME and if it isn't in the same block as the def,
     add it to the list of live on entry blocks.  */
  FOR_EACH_IMM_USE_FAST (use, imm_iter, ssa_name)
    {
      gimple *use_stmt = USE_STMT (use);
      basic_block add_block = NULL;

      if (gimple_code (use_stmt) == GIMPLE_PHI)
        {
	  /* Uses in PHI's are considered to be live at exit of the SRC block
	     as this is where a copy would be inserted.  Check to see if it is
	     defined in that block, or whether its live on entry.  */
	  int index = PHI_ARG_INDEX_FROM_USE (use);
	  edge e = gimple_phi_arg_edge (as_a <gphi *> (use_stmt), index);
	  if (e->src != def_bb && region_contains_p (live->map, e->src))
	    add_block = e->src;
	}
      else if (is_gimple_debug (use_stmt))
	continue;
      else
        {
	  /* If its not defined in this block, its live on entry.  */
	  basic_block use_bb = gimple_bb (use_stmt);
	  if (use_bb != def_bb && region_contains_p (live->map, use_bb))
	    add_block = use_bb;
	}

      /* If there was a live on entry use, set the bit.  */
      if (add_block)
        {
	  global = true;
	  bitmap_set_bit (&live->livein[add_block->index], p);
	}
    }

  /* If SSA_NAME is live on entry to at least one block, fill in all the live
     on entry blocks between the def and all the uses.  */
  if (global)
    bitmap_set_bit (live->global, p);
}


/* Calculate the live on exit vectors based on the entry info in LIVEINFO.  */

static void
calculate_live_on_exit (tree_live_info_p liveinfo)
{
  basic_block bb;
  edge e;
  edge_iterator ei;

  /* live on entry calculations used liveout vectors for defs, clear them.  */
  for (unsigned i = 0; liveinfo->map->vec_bbs.iterate (i, &bb); ++i)
    bitmap_clear (&liveinfo->liveout[bb->index]);

  /* Set all the live-on-exit bits for uses in PHIs.  */
  FOR_EACH_BB_FN (bb, cfun)
    {
      gphi_iterator gsi;
      size_t i;

      /* Mark the PHI arguments which are live on exit to the pred block.  */
      for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
	{
	  gphi *phi = gsi.phi ();
	  if (virtual_operand_p (gimple_phi_result (phi)))
	    continue;
	  for (i = 0; i < gimple_phi_num_args (phi); i++)
	    {
	      tree t = PHI_ARG_DEF (phi, i);
	      int p;

	      if (TREE_CODE (t) != SSA_NAME)
		continue;

	      p = var_to_partition (liveinfo->map, t);
	      if (p == NO_PARTITION)
		continue;
	      e = gimple_phi_arg_edge (phi, i);
	      if (region_contains_p (liveinfo->map, e->src))
		bitmap_set_bit (&liveinfo->liveout[e->src->index], p);
	    }
	}

      if (!region_contains_p (liveinfo->map, bb))
	continue;

      /* Add each successors live on entry to this bock live on exit.  */
      FOR_EACH_EDGE (e, ei, bb->succs)
	if (region_contains_p (liveinfo->map, e->dest))
	  bitmap_ior_into (&liveinfo->liveout[bb->index],
			   live_on_entry (liveinfo, e->dest));
    }
}


/* Given partition map MAP, calculate all the live on entry bitmaps for
   each partition.  Return a new live info object.  */

tree_live_info_p
calculate_live_ranges (var_map map, bool want_livein)
{
  tree var;
  unsigned i;
  tree_live_info_p live;

  live = new_tree_live_info (map);
  for (i = 0; i < num_var_partitions (map); i++)
    {
      var = partition_to_var (map, i);
      if (var != NULL_TREE)
	set_var_live_on_entry (var, live);
    }

  live_worklist (live);

  if (flag_checking)
    verify_live_on_entry (live);

  calculate_live_on_exit (live);

  if (!want_livein)
    {
      bitmap_obstack_release (&live->livein_obstack);
      free (live->livein);
      live->livein = NULL;
    }

  return live;
}

/* Data structure for compute_live_vars* functions.  */

struct compute_live_vars_data {
  /* Vector of bitmaps for live vars indices at the end of basic blocks,
     indexed by bb->index.  ACTIVE[ENTRY_BLOCK] must be empty bitmap,
     ACTIVE[EXIT_BLOCK] is used for STOP_AFTER.  */
  vec<bitmap_head> active;
  /* Work bitmap of currently live variables.  */
  bitmap work;
  /* Set of interesting variables.  Variables with uids not in this
     hash_map are not tracked.  */
  live_vars_map *vars;
};

/* Callback for walk_stmt_load_store_addr_ops.  If OP is a VAR_DECL with
   uid set in DATA->vars, enter its corresponding index into bitmap
   DATA->work.  */

static bool
compute_live_vars_visit (gimple *, tree op, tree, void *pdata)
{
  compute_live_vars_data *data = (compute_live_vars_data *) pdata;
  op = get_base_address (op);
  if (op && VAR_P (op))
    if (unsigned int *v = data->vars->get (DECL_UID (op)))
      bitmap_set_bit (data->work, *v);
  return false;
}

/* Helper routine for compute_live_vars, calculating the sets of live
   variables at the end of BB, leaving the result in DATA->work.
   If STOP_AFTER is non-NULL, stop processing after that stmt.  */

static void
compute_live_vars_1 (basic_block bb, compute_live_vars_data *data,
		     gimple *stop_after)
{
  edge e;
  edge_iterator ei;
  gimple_stmt_iterator gsi;
  walk_stmt_load_store_addr_fn visit = compute_live_vars_visit;

  bitmap_clear (data->work);
  FOR_EACH_EDGE (e, ei, bb->preds)
    bitmap_ior_into (data->work, &data->active[e->src->index]);

  for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    walk_stmt_load_store_addr_ops (gsi_stmt (gsi), data, NULL, NULL, visit);
  for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    {
      gimple *stmt = gsi_stmt (gsi);

      if (gimple_clobber_p (stmt))
	{
	  tree lhs = gimple_assign_lhs (stmt);
	  if (VAR_P (lhs))
	    if (unsigned int *v = data->vars->get (DECL_UID (lhs)))
	      bitmap_clear_bit (data->work, *v);
	}
      else if (!is_gimple_debug (stmt))
	walk_stmt_load_store_addr_ops (stmt, data, visit, visit, visit);
      if (stmt == stop_after)
	break;
    }
}

/* For function FN and live_vars_map (hash map from DECL_UIDs to a dense set of
   indexes of automatic variables VARS, compute which of those variables are
   (might be) live at the end of each basic block.  */

vec<bitmap_head>
compute_live_vars (struct function *fn, live_vars_map *vars)
{
  vec<bitmap_head> active;

  /* We approximate the live range of a stack variable by taking the first
     mention of its name as starting point(s), and by the end-of-scope
     death clobber added by gimplify as ending point(s) of the range.
     This overapproximates in the case we for instance moved an address-taken
     operation upward, without also moving a dereference to it upwards.
     But it's conservatively correct as a variable never can hold values
     before its name is mentioned at least once.

     We then do a mostly classical bitmap liveness algorithm.  */

  active.create (last_basic_block_for_fn (fn));
  active.quick_grow (last_basic_block_for_fn (fn));
  for (int i = 0; i < last_basic_block_for_fn (fn); i++)
    bitmap_initialize (&active[i], &bitmap_default_obstack);

  bitmap work = BITMAP_ALLOC (NULL);

  int *rpo = XNEWVEC (int, last_basic_block_for_fn (fn));
  int n_bbs = pre_and_rev_post_order_compute_fn (fn, NULL, rpo, false);

  bool changed = true;
  compute_live_vars_data data = { active, work, vars };
  while (changed)
    {
      int i;
      changed = false;
      for (i = 0; i < n_bbs; i++)
	{
	  basic_block bb = BASIC_BLOCK_FOR_FN (fn, rpo[i]);
	  compute_live_vars_1 (bb, &data, NULL);
	  if (bitmap_ior_into (&active[bb->index], work))
	    changed = true;
	}
    }

  free (rpo);
  BITMAP_FREE (work);

  return active;
}

/* For ACTIVE computed by compute_live_vars, compute a bitmap of variables
   live after the STOP_AFTER statement and return that bitmap.  */

bitmap
live_vars_at_stmt (vec<bitmap_head> &active, live_vars_map *vars,
		   gimple *stop_after)
{
  bitmap work = BITMAP_ALLOC (NULL);
  compute_live_vars_data data = { active, work, vars };
  basic_block bb = gimple_bb (stop_after);
  compute_live_vars_1 (bb, &data, stop_after);
  return work;
}

/* Destroy what compute_live_vars has returned when it is no longer needed.  */

void
destroy_live_vars (vec<bitmap_head> &active)
{
  unsigned len = active.length ();
  for (unsigned i = 0; i < len; i++)
    bitmap_clear (&active[i]);

  active.release ();
}

/* Output partition map MAP to file F.  */

void
dump_var_map (FILE *f, var_map map)
{
  int t;
  unsigned x, y;
  int p;

  fprintf (f, "\nPartition map \n\n");

  for (x = 0; x < map->num_partitions; x++)
    {
      if (map->view_to_partition != NULL)
	p = map->view_to_partition[x];
      else
	p = x;

      if (ssa_name (p) == NULL_TREE
	  || virtual_operand_p (ssa_name (p)))
        continue;

      t = 0;
      for (y = 1; y < num_ssa_names; y++)
        {
	  p = partition_find (map->var_partition, y);
	  if (map->partition_to_view)
	    p = map->partition_to_view[p];
	  if (p == (int)x)
	    {
	      if (t++ == 0)
	        {
		  fprintf (f, "Partition %d (", x);
		  print_generic_expr (f, partition_to_var (map, p), TDF_SLIM);
		  fprintf (f, " - ");
		}
	      fprintf (f, "%d ", y);
	    }
	}
      if (t != 0)
	fprintf (f, ")\n");
    }
  fprintf (f, "\n");
}


/* Generic dump for the above.  */

DEBUG_FUNCTION void
debug (_var_map &ref)
{
  dump_var_map (stderr, &ref);
}

DEBUG_FUNCTION void
debug (_var_map *ptr)
{
  if (ptr)
    debug (*ptr);
  else
    fprintf (stderr, "<nil>\n");
}


/* Output live range info LIVE to file F, controlled by FLAG.  */

void
dump_live_info (FILE *f, tree_live_info_p live, int flag)
{
  basic_block bb;
  unsigned i;
  var_map map = live->map;
  bitmap_iterator bi;

  if ((flag & LIVEDUMP_ENTRY) && live->livein)
    {
      FOR_EACH_BB_FN (bb, cfun)
	{
	  fprintf (f, "\nLive on entry to BB%d : ", bb->index);
	  EXECUTE_IF_SET_IN_BITMAP (&live->livein[bb->index], 0, i, bi)
	    {
	      print_generic_expr (f, partition_to_var (map, i), TDF_SLIM);
	      fprintf (f, "  ");
	    }
	  fprintf (f, "\n");
	}
    }

  if ((flag & LIVEDUMP_EXIT) && live->liveout)
    {
      FOR_EACH_BB_FN (bb, cfun)
	{
	  fprintf (f, "\nLive on exit from BB%d : ", bb->index);
	  EXECUTE_IF_SET_IN_BITMAP (&live->liveout[bb->index], 0, i, bi)
	    {
	      print_generic_expr (f, partition_to_var (map, i), TDF_SLIM);
	      fprintf (f, "  ");
	    }
	  fprintf (f, "\n");
	}
    }
}


/* Generic dump for the above.  */

DEBUG_FUNCTION void
debug (tree_live_info_d &ref)
{
  dump_live_info (stderr, &ref, 0);
}

DEBUG_FUNCTION void
debug (tree_live_info_d *ptr)
{
  if (ptr)
    debug (*ptr);
  else
    fprintf (stderr, "<nil>\n");
}


/* Verify that the info in LIVE matches the current cfg.  */

static void
verify_live_on_entry (tree_live_info_p live)
{
  unsigned i;
  tree var;
  gimple *stmt;
  basic_block bb;
  edge e;
  int num;
  edge_iterator ei;
  var_map map = live->map;

   /* Check for live on entry partitions and report those with a DEF in
      the program. This will typically mean an optimization has done
      something wrong.  */
  bb = ENTRY_BLOCK_PTR_FOR_FN (cfun);
  num = 0;
  FOR_EACH_EDGE (e, ei, bb->succs)
    {
      int entry_block = e->dest->index;
      if (!region_contains_p (live->map, e->dest))
        continue;
      for (i = 0; i < (unsigned)num_var_partitions (map); i++)
	{
	  basic_block tmp;
	  tree d = NULL_TREE;
	  bitmap loe;
	  var = partition_to_var (map, i);
	  stmt = SSA_NAME_DEF_STMT (var);
	  tmp = gimple_bb (stmt);
	  if (SSA_NAME_VAR (var))
	    d = ssa_default_def (cfun, SSA_NAME_VAR (var));

	  loe = live_on_entry (live, e->dest);
	  if (loe && bitmap_bit_p (loe, i))
	    {
	      if (!gimple_nop_p (stmt))
		{
		  num++;
		  print_generic_expr (stderr, var, TDF_SLIM);
		  fprintf (stderr, " is defined ");
		  if (tmp)
		    fprintf (stderr, " in BB%d, ", tmp->index);
		  fprintf (stderr, "by:\n");
		  print_gimple_stmt (stderr, stmt, 0, TDF_SLIM);
		  fprintf (stderr, "\nIt is also live-on-entry to entry BB %d",
			   entry_block);
		  fprintf (stderr, " So it appears to have multiple defs.\n");
		}
	      else
	        {
		  if (d != var)
		    {
		      num++;
		      print_generic_expr (stderr, var, TDF_SLIM);
		      fprintf (stderr, " is live-on-entry to BB%d ",
			       entry_block);
		      if (d)
		        {
			  fprintf (stderr, " but is not the default def of ");
			  print_generic_expr (stderr, d, TDF_SLIM);
			  fprintf (stderr, "\n");
			}
		      else
			fprintf (stderr, " and there is no default def.\n");
		    }
		}
	    }
	  else
	    if (d == var)
	      {
		/* An undefined local variable does not need to be very
		   alive.  */
		if (ssa_undefined_value_p (var, false))
		  continue;

		/* The only way this var shouldn't be marked live on entry is
		   if it occurs in a PHI argument of the block.  */
		size_t z;
		bool ok = false;
		gphi_iterator gsi;
		for (gsi = gsi_start_phis (e->dest);
		     !gsi_end_p (gsi) && !ok;
		     gsi_next (&gsi))
		  {
		    gphi *phi = gsi.phi ();
		    if (virtual_operand_p (gimple_phi_result (phi)))
		      continue;
		    for (z = 0; z < gimple_phi_num_args (phi); z++)
		      if (var == gimple_phi_arg_def (phi, z))
			{
			  ok = true;
			  break;
			}
		  }
		if (ok)
		  continue;
		/* Expand adds unused default defs for PARM_DECLs and
		   RESULT_DECLs.  They're ok.  */
		if (has_zero_uses (var)
		    && SSA_NAME_VAR (var)
		    && !VAR_P (SSA_NAME_VAR (var)))
		  continue;
	        num++;
		print_generic_expr (stderr, var, TDF_SLIM);
		fprintf (stderr, " is not marked live-on-entry to entry BB%d ",
			 entry_block);
		fprintf (stderr, "but it is a default def so it should be.\n");
	      }
	}
    }
  gcc_assert (num <= 0);
}
