/* Infrastructure for tracking user variable locations and values
   throughout compilation.
   Copyright (C) 2010-2021 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 SCRATCH:
      /* SCRATCH must be shared because they represent distinct values.  */
      return x;
    case CLOBBER:
      /* Share clobbers of hard registers, 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;
  return gen_rtx_raw_SUBREG (outer_mode, expr, offset);
}

/* 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;
}
