/* Infrastructure for tracking user variable locations and values
   throughout compilation.
   Copyright (C) 2010-2020 Free Software Foundation, Inc.
   Contributed by Alexandre Oliva <aoliva@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 "df.h"
#include "valtrack.h"
#include "regs.h"
#include "memmodel.h"
#include "emit-rtl.h"
#include "rtl-iter.h"

/* gen_lowpart_no_emit hook implementation for DEBUG_INSNs.  In DEBUG_INSNs,
   all lowpart SUBREGs are valid, despite what the machine requires for
   instructions.  */

static rtx
gen_lowpart_for_debug (machine_mode mode, rtx x)
{
  rtx result = gen_lowpart_if_possible (mode, x);
  if (result)
    return result;

  if (GET_MODE (x) != VOIDmode)
    return gen_rtx_raw_SUBREG (mode, x,
			       subreg_lowpart_offset (mode, GET_MODE (x)));

  return NULL_RTX;
}

/* Replace auto-increment addressing modes with explicit operations to access
   the same addresses without modifying the corresponding registers.  */

static rtx
cleanup_auto_inc_dec (rtx src, machine_mode mem_mode ATTRIBUTE_UNUSED)
{
  rtx x = src;

  const RTX_CODE code = GET_CODE (x);
  int i;
  const char *fmt;

  switch (code)
    {
    case REG:
    CASE_CONST_ANY:
    case SYMBOL_REF:
    case CODE_LABEL:
    case PC:
    case CC0:
    case SCRATCH:
      /* SCRATCH must be shared because they represent distinct values.  */
      return x;
    case CLOBBER:
      /* Share clobbers of hard registers (like cc0), but do not share pseudo reg
         clobbers or clobbers of hard registers that originated as pseudos.
         This is needed to allow safe register renaming.  */
      if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
	  && ORIGINAL_REGNO (XEXP (x, 0)) == REGNO (XEXP (x, 0)))
	return x;
      break;

    case CONST:
      if (shared_const_p (x))
	return x;
      break;

    case MEM:
      mem_mode = GET_MODE (x);
      break;

    case PRE_INC:
    case PRE_DEC:
      {
	gcc_assert (mem_mode != VOIDmode && mem_mode != BLKmode);
	poly_int64 offset = GET_MODE_SIZE (mem_mode);
	if (code == PRE_DEC)
	  offset = -offset;
	return gen_rtx_PLUS (GET_MODE (x),
			     cleanup_auto_inc_dec (XEXP (x, 0), mem_mode),
			     gen_int_mode (offset, GET_MODE (x)));
      }

    case POST_INC:
    case POST_DEC:
    case PRE_MODIFY:
    case POST_MODIFY:
      return cleanup_auto_inc_dec (code == PRE_MODIFY
				   ? XEXP (x, 1) : XEXP (x, 0),
				   mem_mode);

    default:
      break;
    }

  /* Copy the various flags, fields, and other information.  We assume
     that all fields need copying, and then clear the fields that should
     not be copied.  That is the sensible default behavior, and forces
     us to explicitly document why we are *not* copying a flag.  */
  x = shallow_copy_rtx (x);

  /* We do not copy FRAME_RELATED for INSNs.  */
  if (INSN_P (x))
    RTX_FLAG (x, frame_related) = 0;

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    if (fmt[i] == 'e')
      XEXP (x, i) = cleanup_auto_inc_dec (XEXP (x, i), mem_mode);
    else if (fmt[i] == 'E' || fmt[i] == 'V')
      {
	int j;
	XVEC (x, i) = rtvec_alloc (XVECLEN (x, i));
	for (j = 0; j < XVECLEN (x, i); j++)
	  XVECEXP (x, i, j)
	    = cleanup_auto_inc_dec (XVECEXP (src, i, j), mem_mode);
      }

  return x;
}

/* Auxiliary data structure for propagate_for_debug_stmt.  */

struct rtx_subst_pair
{
  rtx to;
  bool adjusted;
  rtx_insn *insn;
};

/* DATA points to an rtx_subst_pair.  Return the value that should be
   substituted.  */

static rtx
propagate_for_debug_subst (rtx from, const_rtx old_rtx, void *data)
{
  struct rtx_subst_pair *pair = (struct rtx_subst_pair *)data;

  if (!rtx_equal_p (from, old_rtx))
    return NULL_RTX;
  if (!pair->adjusted)
    {
      pair->adjusted = true;
      pair->to = cleanup_auto_inc_dec (pair->to, VOIDmode);
      pair->to = make_compound_operation (pair->to, SET);
      /* Avoid propagation from growing DEBUG_INSN expressions too much.  */
      int cnt = 0;
      subrtx_iterator::array_type array;
      FOR_EACH_SUBRTX (iter, array, pair->to, ALL)
	if (REG_P (*iter) && ++cnt > 1)
	  {
	    rtx dval = make_debug_expr_from_rtl (old_rtx);
	    rtx to = pair->to;
	    if (volatile_insn_p (to))
	      to = gen_rtx_UNKNOWN_VAR_LOC ();
	    /* Emit a debug bind insn.  */
	    rtx bind
	      = gen_rtx_VAR_LOCATION (GET_MODE (old_rtx),
				      DEBUG_EXPR_TREE_DECL (dval), to,
				      VAR_INIT_STATUS_INITIALIZED);
	    rtx_insn *bind_insn = emit_debug_insn_before (bind, pair->insn);
	    df_insn_rescan (bind_insn);
	    pair->to = dval;
	    break;
	  }
      return pair->to;
    }
  return copy_rtx (pair->to);
}

/* Replace all the occurrences of DEST with SRC in DEBUG_INSNs between INSN
   and LAST, not including INSN, but including LAST.  Also stop at the end
   of THIS_BASIC_BLOCK.  */

void
propagate_for_debug (rtx_insn *insn, rtx_insn *last, rtx dest, rtx src,
		     basic_block this_basic_block)
{
  rtx_insn *next, *end = NEXT_INSN (BB_END (this_basic_block));
  rtx loc;
  rtx (*saved_rtl_hook_no_emit) (machine_mode, rtx);

  struct rtx_subst_pair p;
  p.to = src;
  p.adjusted = false;
  p.insn = NEXT_INSN (insn);

  next = NEXT_INSN (insn);
  last = NEXT_INSN (last);
  saved_rtl_hook_no_emit = rtl_hooks.gen_lowpart_no_emit;
  rtl_hooks.gen_lowpart_no_emit = gen_lowpart_for_debug;
  while (next != last && next != end)
    {
      insn = next;
      next = NEXT_INSN (insn);
      if (DEBUG_BIND_INSN_P (insn))
	{
	  loc = simplify_replace_fn_rtx (INSN_VAR_LOCATION_LOC (insn),
					 dest, propagate_for_debug_subst, &p);
	  if (loc == INSN_VAR_LOCATION_LOC (insn))
	    continue;
	  if (volatile_insn_p (loc))
	    loc = gen_rtx_UNKNOWN_VAR_LOC ();
	  INSN_VAR_LOCATION_LOC (insn) = loc;
	  df_insn_rescan (insn);
	}
    }
  rtl_hooks.gen_lowpart_no_emit = saved_rtl_hook_no_emit;
}

/* Initialize DEBUG to an empty list, and clear USED, if given.  */

void
dead_debug_global_init (struct dead_debug_global *debug, bitmap used)
{
  debug->used = used;
  debug->htab = NULL;
  if (used)
    bitmap_clear (used);
}

/* Initialize DEBUG to an empty list, and clear USED, if given.  Link
   back to GLOBAL, if given, and bring in used bits from it.  */

void
dead_debug_local_init (struct dead_debug_local *debug, bitmap used,
		       struct dead_debug_global *global)
{
  if (!used && global && global->used)
    used = BITMAP_ALLOC (NULL);

  debug->head = NULL;
  debug->global = global;
  debug->used = used;
  debug->to_rescan = NULL;

  if (used)
    {
      if (global && global->used)
	bitmap_copy (used, global->used);
      else
	bitmap_clear (used);
    }
}

/* Locate the entry for REG in GLOBAL->htab.  */

static dead_debug_global_entry *
dead_debug_global_find (struct dead_debug_global *global, rtx reg)
{
  dead_debug_global_entry temp_entry;
  temp_entry.reg = reg;

  dead_debug_global_entry *entry = global->htab->find (&temp_entry);
  gcc_checking_assert (entry && entry->reg == temp_entry.reg);

  return entry;
}

/* Insert an entry mapping REG to DTEMP in GLOBAL->htab.  */

static dead_debug_global_entry *
dead_debug_global_insert (struct dead_debug_global *global, rtx reg, rtx dtemp)
{
  dead_debug_global_entry temp_entry;
  temp_entry.reg = reg;
  temp_entry.dtemp = dtemp;

  if (!global->htab)
    global->htab = new hash_table<dead_debug_hash_descr> (31);

  dead_debug_global_entry **slot = global->htab->find_slot (&temp_entry,
							    INSERT);
  gcc_checking_assert (!*slot);
  *slot = XNEW (dead_debug_global_entry);
  **slot = temp_entry;
  return *slot;
}

/* If UREGNO, referenced by USE, is a pseudo marked as used in GLOBAL,
   replace it with a USE of the debug temp recorded for it, and
   return TRUE.  Otherwise, just return FALSE.

   If PTO_RESCAN is given, instead of rescanning modified INSNs right
   away, add their UIDs to the bitmap, allocating one of *PTO_RESCAN
   is NULL.  */

static bool
dead_debug_global_replace_temp (struct dead_debug_global *global,
				df_ref use, unsigned int uregno,
				bitmap *pto_rescan)
{
  if (!global || uregno < FIRST_PSEUDO_REGISTER
      || !global->used
      || !REG_P (*DF_REF_REAL_LOC (use))
      || REGNO (*DF_REF_REAL_LOC (use)) != uregno
      || !bitmap_bit_p (global->used, uregno))
    return false;

  dead_debug_global_entry *entry
    = dead_debug_global_find (global, *DF_REF_REAL_LOC (use));
  gcc_checking_assert (GET_CODE (entry->reg) == REG
		       && REGNO (entry->reg) == uregno);

  if (!entry->dtemp)
    return true;

  *DF_REF_REAL_LOC (use) = entry->dtemp;
  if (!pto_rescan)
    df_insn_rescan (DF_REF_INSN (use));
  else
    {
      if (!*pto_rescan)
	*pto_rescan = BITMAP_ALLOC (NULL);
      bitmap_set_bit (*pto_rescan, INSN_UID (DF_REF_INSN (use)));
    }

  return true;
}

/* Reset all debug uses in HEAD, and clear DEBUG->to_rescan bits of
   each reset insn.  DEBUG is not otherwise modified.  If HEAD is
   DEBUG->head, DEBUG->head will be set to NULL at the end.
   Otherwise, entries from DEBUG->head that pertain to reset insns
   will be removed, and only then rescanned.  */

static void
dead_debug_reset_uses (struct dead_debug_local *debug,
		       struct dead_debug_use *head)
{
  bool got_head = (debug->head == head);
  bitmap rescan;
  struct dead_debug_use **tailp = &debug->head;
  struct dead_debug_use *cur;
  bitmap_iterator bi;
  unsigned int uid;

  if (got_head)
    rescan = NULL;
  else
    rescan = BITMAP_ALLOC (NULL);

  while (head)
    {
      struct dead_debug_use *next = head->next;
      rtx_insn *insn;

      insn = DF_REF_INSN (head->use);
      if (!next || DF_REF_INSN (next->use) != insn)
	{
	  INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
	  if (got_head)
	    df_insn_rescan_debug_internal (insn);
	  else
	    bitmap_set_bit (rescan, INSN_UID (insn));
	  if (debug->to_rescan)
	    bitmap_clear_bit (debug->to_rescan, INSN_UID (insn));
	}
      XDELETE (head);
      head = next;
    }

  if (got_head)
    {
      debug->head = NULL;
      return;
    }

  while ((cur = *tailp))
    if (bitmap_bit_p (rescan, INSN_UID (DF_REF_INSN (cur->use))))
      {
	*tailp = cur->next;
	XDELETE (cur);
      }
    else
      tailp = &cur->next;

  EXECUTE_IF_SET_IN_BITMAP (rescan, 0, uid, bi)
    {
      struct df_insn_info *insn_info = DF_INSN_UID_SAFE_GET (uid);
      if (insn_info)
	df_insn_rescan_debug_internal (insn_info->insn);
    }

  BITMAP_FREE (rescan);
}

/* Promote pending local uses of pseudos in DEBUG to global
   substitutions.  Uses of non-pseudos are left alone for
   resetting.  */

static void
dead_debug_promote_uses (struct dead_debug_local *debug)
{
  for (struct dead_debug_use *head = debug->head, **headp = &debug->head;
       head; head = *headp)
    {
      rtx reg = *DF_REF_REAL_LOC (head->use);
      df_ref ref;
      dead_debug_global_entry *entry;

      if (GET_CODE (reg) != REG
	  || REGNO (reg) < FIRST_PSEUDO_REGISTER)
	{
	  headp = &head->next;
	  continue;
	}

      if (!debug->global->used)
	debug->global->used = BITMAP_ALLOC (NULL);

      bool added = bitmap_set_bit (debug->global->used, REGNO (reg));
      gcc_checking_assert (added);

      entry = dead_debug_global_insert (debug->global, reg,
					make_debug_expr_from_rtl (reg));

      gcc_checking_assert (entry->dtemp);

      /* Tentatively remove the USE from the list.  */
      *headp = head->next;

      if (!debug->to_rescan)
	debug->to_rescan = BITMAP_ALLOC (NULL);

      for (ref = DF_REG_USE_CHAIN (REGNO (reg)); ref;
	   ref = DF_REF_NEXT_REG (ref))
	if (DEBUG_INSN_P (DF_REF_INSN (ref)))
	  {
	    if (!dead_debug_global_replace_temp (debug->global, ref,
						 REGNO (reg),
						 &debug->to_rescan))
	      {
		rtx_insn *insn = DF_REF_INSN (ref);
		INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
		bitmap_set_bit (debug->to_rescan, INSN_UID (insn));
	      }
	  }

      for (ref = DF_REG_DEF_CHAIN (REGNO (reg)); ref;
	   ref = DF_REF_NEXT_REG (ref))
	if (!dead_debug_insert_temp (debug, REGNO (reg), DF_REF_INSN (ref),
				     DEBUG_TEMP_BEFORE_WITH_VALUE))
	  {
	    rtx bind;
	    bind = gen_rtx_VAR_LOCATION (GET_MODE (reg),
					 DEBUG_EXPR_TREE_DECL (entry->dtemp),
					 gen_rtx_UNKNOWN_VAR_LOC (),
					 VAR_INIT_STATUS_INITIALIZED);
	    rtx_insn *insn = emit_debug_insn_before (bind, DF_REF_INSN (ref));
	    bitmap_set_bit (debug->to_rescan, INSN_UID (insn));
	  }

      entry->dtemp = NULL;
      XDELETE (head);
    }
}

/* Reset all debug insns with pending uses.  Release the bitmap in it,
   unless it is USED.  USED must be the same bitmap passed to
   dead_debug_local_init.  */

void
dead_debug_local_finish (struct dead_debug_local *debug, bitmap used)
{
  if (debug->global)
    dead_debug_promote_uses (debug);

  if (debug->used != used)
    BITMAP_FREE (debug->used);

  dead_debug_reset_uses (debug, debug->head);

  if (debug->to_rescan)
    {
      bitmap_iterator bi;
      unsigned int uid;

      EXECUTE_IF_SET_IN_BITMAP (debug->to_rescan, 0, uid, bi)
	{
	  struct df_insn_info *insn_info = DF_INSN_UID_SAFE_GET (uid);
	  if (insn_info)
	    df_insn_rescan (insn_info->insn);
	}
      BITMAP_FREE (debug->to_rescan);
    }
}

/* Release GLOBAL->used unless it is the same as USED.  Release the
   mapping hash table if it was initialized.  */

void
dead_debug_global_finish (struct dead_debug_global *global, bitmap used)
{
  if (global->used != used)
    BITMAP_FREE (global->used);

  delete global->htab;
  global->htab = NULL;
}

/* Add USE to DEBUG, or substitute it right away if it's a pseudo in
   the global substitution list.  USE must be a dead reference to
   UREGNO in a debug insn.  Create a bitmap for DEBUG as needed.  */

void
dead_debug_add (struct dead_debug_local *debug, df_ref use, unsigned int uregno)
{
  if (dead_debug_global_replace_temp (debug->global, use, uregno,
				      &debug->to_rescan))
    return;

  struct dead_debug_use *newddu = XNEW (struct dead_debug_use);

  newddu->use = use;
  newddu->next = debug->head;
  debug->head = newddu;

  if (!debug->used)
    debug->used = BITMAP_ALLOC (NULL);

  /* ??? If we dealt with split multi-registers below, we should set
     all registers for the used mode in case of hardware
     registers.  */
  bitmap_set_bit (debug->used, uregno);
}

/* Like lowpart_subreg, but if a subreg is not valid for machine, force
   it anyway - for use in debug insns.  */

static rtx
debug_lowpart_subreg (machine_mode outer_mode, rtx expr,
		      machine_mode inner_mode)
{
  if (inner_mode == VOIDmode)
    inner_mode = GET_MODE (expr);
  poly_int64 offset = subreg_lowpart_offset (outer_mode, inner_mode);
  rtx ret = simplify_gen_subreg (outer_mode, expr, inner_mode, offset);
  if (ret)
    return ret;
  if (GET_MODE (expr) != VOIDmode)
    return gen_rtx_raw_SUBREG (outer_mode, expr, offset);
  return NULL_RTX;
}

/* If UREGNO is referenced by any entry in DEBUG, emit a debug insn
   before or after INSN (depending on WHERE), that binds a (possibly
   global) debug temp to the widest-mode use of UREGNO, if WHERE is
   *_WITH_REG, or the value stored in UREGNO by INSN otherwise, and
   replace all uses of UREGNO in DEBUG with uses of the debug temp.
   INSN must be where UREGNO dies, if WHERE is *_BEFORE_*, or where it
   is set otherwise.  Return the number of debug insns emitted.  */

int
dead_debug_insert_temp (struct dead_debug_local *debug, unsigned int uregno,
			rtx_insn *insn, enum debug_temp_where where)
{
  struct dead_debug_use **tailp = &debug->head;
  struct dead_debug_use *cur;
  struct dead_debug_use *uses = NULL;
  struct dead_debug_use **usesp = &uses;
  rtx reg = NULL_RTX;
  rtx breg;
  rtx dval = NULL_RTX;
  rtx bind;
  bool global;

  if (!debug->used)
    return 0;

  global = (debug->global && debug->global->used
	    && bitmap_bit_p (debug->global->used, uregno));

  if (!global && !bitmap_clear_bit (debug->used, uregno))
    return 0;

  /* Move all uses of uregno from debug->head to uses, setting mode to
     the widest referenced mode.  */
  while ((cur = *tailp))
    {
      if (DF_REF_REGNO (cur->use) == uregno)
	{
	  /* If this loc has been changed e.g. to debug_expr already
	     as part of a multi-register use, just drop it.  */
	  if (!REG_P (*DF_REF_REAL_LOC (cur->use)))
	    {
	      *tailp = cur->next;
	      XDELETE (cur);
	      continue;
	    }
	  *usesp = cur;
	  usesp = &cur->next;
	  *tailp = cur->next;
	  cur->next = NULL;
	  /* "may" rather than "must" because we want (for example)
	     N V4SFs to win over plain V4SF even though N might be 1.  */
	  rtx candidate = *DF_REF_REAL_LOC (cur->use);
	  if (!reg
	      || maybe_lt (GET_MODE_BITSIZE (GET_MODE (reg)),
			   GET_MODE_BITSIZE (GET_MODE (candidate))))
	    reg = candidate;
	}
      else
	tailp = &(*tailp)->next;
    }

  /* We may have dangling bits in debug->used for registers that were part
     of a multi-register use, one component of which has been reset.  */
  if (reg == NULL)
    {
      gcc_checking_assert (!uses);
      if (!global)
	return 0;
    }

  if (global)
    {
      if (!reg)
	reg = regno_reg_rtx[uregno];
      dead_debug_global_entry *entry
	= dead_debug_global_find (debug->global, reg);
      gcc_checking_assert (entry->reg == reg);
      dval = entry->dtemp;
      if (!dval)
	return 0;
    }

  gcc_checking_assert (uses || global);

  breg = reg;
  /* Recover the expression INSN stores in REG.  */
  if (where == DEBUG_TEMP_BEFORE_WITH_VALUE)
    {
      rtx set = single_set (insn);
      rtx dest, src;

      if (set)
	{
	  dest = SET_DEST (set);
	  src = SET_SRC (set);
	  /* Reset uses if the REG-setting insn is a CALL.  Asm in
	     DEBUG_INSN is never useful, we can't emit debug info for
	     that.  And for volatile_insn_p, it is actually harmful -
	     DEBUG_INSNs shouldn't have any side-effects.  */
	  if (GET_CODE (src) == CALL || GET_CODE (src) == ASM_OPERANDS
	      || volatile_insn_p (src))
	    set = NULL_RTX;
	}

      /* ??? Should we try to extract it from a PARALLEL?  */
      if (!set)
	breg = NULL;
      /* Cool, it's the same REG, we can use SRC.  */
      else if (dest == reg)
	breg = cleanup_auto_inc_dec (src, VOIDmode);
      else if (REG_P (dest))
	{
	  /* Hmm...  Something's fishy, we should be setting REG here.  */
	  if (REGNO (dest) != REGNO (reg))
	    breg = NULL;
	  /* If we're not overwriting all the hardware registers that
	     setting REG in its mode would, we won't know what to bind
	     the debug temp to.  ??? We could bind the debug_expr to a
	     CONCAT or PARALLEL with the split multi-registers, and
	     replace them as we found the corresponding sets.  */
	  else if (REG_NREGS (reg) != REG_NREGS (dest))
	    breg = NULL;
	  /* Ok, it's the same (hardware) REG, but with a different
	     mode, so SUBREG it.  */
	  else
	    breg = debug_lowpart_subreg (GET_MODE (reg),
					 cleanup_auto_inc_dec (src, VOIDmode),
					 GET_MODE (dest));
	}
      else if (GET_CODE (dest) == SUBREG)
	{
	  /* We should be setting REG here.  Lose.  */
	  if (REGNO (SUBREG_REG (dest)) != REGNO (reg))
	    breg = NULL;
	  /* Lose if we're setting something other than the lowpart of
	     REG.  */
	  else if (!subreg_lowpart_p (dest))
	    breg = NULL;
	  /* If we're not overwriting all the hardware registers that
	     setting REG in its mode would, we won't know what to bind
	     the debug temp to.  */
	  else if (REGNO (reg) < FIRST_PSEUDO_REGISTER
		   && (REG_NREGS (reg)
		       != hard_regno_nregs (REGNO (reg), GET_MODE (dest))))
	    breg = NULL;
	  /* Yay, we can use SRC, just adjust its mode.  */
	  else
	    breg = debug_lowpart_subreg (GET_MODE (reg),
					 cleanup_auto_inc_dec (src, VOIDmode),
					 GET_MODE (dest));
	}
      /* Oh well, we're out of luck.  */
      else
	breg = NULL;

      /* We couldn't figure out the value stored in REG, so reset all
	 of its pending debug uses.  */
      if (!breg)
	{
	  dead_debug_reset_uses (debug, uses);
	  return 0;
	}
    }

  /* If there's a single (debug) use of an otherwise unused REG, and
     the debug use is not part of a larger expression, then it
     probably doesn't make sense to introduce a new debug temp.  */
  if (where == DEBUG_TEMP_AFTER_WITH_REG && !uses->next)
    {
      rtx_insn *next = DF_REF_INSN (uses->use);

      if (DEBUG_INSN_P (next) && reg == INSN_VAR_LOCATION_LOC (next))
	{
	  XDELETE (uses);
	  return 0;
	}
    }

  if (!global)
    /* Create DEBUG_EXPR (and DEBUG_EXPR_DECL).  */
    dval = make_debug_expr_from_rtl (reg);

  /* Emit a debug bind insn before the insn in which reg dies.  */
  bind = gen_rtx_VAR_LOCATION (GET_MODE (reg),
			       DEBUG_EXPR_TREE_DECL (dval), breg,
			       VAR_INIT_STATUS_INITIALIZED);

  if (where == DEBUG_TEMP_AFTER_WITH_REG
      || where == DEBUG_TEMP_AFTER_WITH_REG_FORCE)
    bind = emit_debug_insn_after (bind, insn);
  else
    bind = emit_debug_insn_before (bind, insn);
  if (debug->to_rescan == NULL)
    debug->to_rescan = BITMAP_ALLOC (NULL);
  bitmap_set_bit (debug->to_rescan, INSN_UID (bind));

  /* Adjust all uses.  */
  while ((cur = uses))
    {
      if (GET_MODE (*DF_REF_REAL_LOC (cur->use)) == GET_MODE (reg))
	*DF_REF_REAL_LOC (cur->use) = dval;
      else
	*DF_REF_REAL_LOC (cur->use)
	  = debug_lowpart_subreg (GET_MODE (*DF_REF_REAL_LOC (cur->use)), dval,
				  GET_MODE (dval));
      /* ??? Should we simplify subreg of subreg?  */
      bitmap_set_bit (debug->to_rescan, INSN_UID (DF_REF_INSN (cur->use)));
      uses = cur->next;
      XDELETE (cur);
    }

  return 1;
}
