xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/valtrack.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /* Infrastructure for tracking user variable locations and values
2    throughout compilation.
3    Copyright (C) 2010-2015 Free Software Foundation, Inc.
4    Contributed by Alexandre Oliva <aoliva@redhat.com>.
5 
6 This file is part of GCC.
7 
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12 
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21 
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "rtl.h"
27 #include "predict.h"
28 #include "basic-block.h"
29 #include "valtrack.h"
30 #include "hashtab.h"
31 #include "hash-set.h"
32 #include "vec.h"
33 #include "machmode.h"
34 #include "hard-reg-set.h"
35 #include "input.h"
36 #include "function.h"
37 #include "regs.h"
38 #include "emit-rtl.h"
39 
40 /* gen_lowpart_no_emit hook implementation for DEBUG_INSNs.  In DEBUG_INSNs,
41    all lowpart SUBREGs are valid, despite what the machine requires for
42    instructions.  */
43 
44 static rtx
45 gen_lowpart_for_debug (machine_mode mode, rtx x)
46 {
47   rtx result = gen_lowpart_if_possible (mode, x);
48   if (result)
49     return result;
50 
51   if (GET_MODE (x) != VOIDmode)
52     return gen_rtx_raw_SUBREG (mode, x,
53 			       subreg_lowpart_offset (mode, GET_MODE (x)));
54 
55   return NULL_RTX;
56 }
57 
58 /* Replace auto-increment addressing modes with explicit operations to access
59    the same addresses without modifying the corresponding registers.  */
60 
61 static rtx
62 cleanup_auto_inc_dec (rtx src, machine_mode mem_mode ATTRIBUTE_UNUSED)
63 {
64   rtx x = src;
65 #ifdef AUTO_INC_DEC
66   const RTX_CODE code = GET_CODE (x);
67   int i;
68   const char *fmt;
69 
70   switch (code)
71     {
72     case REG:
73     CASE_CONST_ANY:
74     case SYMBOL_REF:
75     case CODE_LABEL:
76     case PC:
77     case CC0:
78     case SCRATCH:
79       /* SCRATCH must be shared because they represent distinct values.  */
80       return x;
81     case CLOBBER:
82       /* Share clobbers of hard registers (like cc0), but do not share pseudo reg
83          clobbers or clobbers of hard registers that originated as pseudos.
84          This is needed to allow safe register renaming.  */
85       if (REG_P (XEXP (x, 0)) && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
86 	  && ORIGINAL_REGNO (XEXP (x, 0)) == REGNO (XEXP (x, 0)))
87 	return x;
88       break;
89 
90     case CONST:
91       if (shared_const_p (x))
92 	return x;
93       break;
94 
95     case MEM:
96       mem_mode = GET_MODE (x);
97       break;
98 
99     case PRE_INC:
100     case PRE_DEC:
101       gcc_assert (mem_mode != VOIDmode && mem_mode != BLKmode);
102       return gen_rtx_PLUS (GET_MODE (x),
103 			   cleanup_auto_inc_dec (XEXP (x, 0), mem_mode),
104 			   gen_int_mode (code == PRE_INC
105 					 ? GET_MODE_SIZE (mem_mode)
106 					 : -GET_MODE_SIZE (mem_mode),
107 					 GET_MODE (x)));
108 
109     case POST_INC:
110     case POST_DEC:
111     case PRE_MODIFY:
112     case POST_MODIFY:
113       return cleanup_auto_inc_dec (code == PRE_MODIFY
114 				   ? XEXP (x, 1) : XEXP (x, 0),
115 				   mem_mode);
116 
117     default:
118       break;
119     }
120 
121   /* Copy the various flags, fields, and other information.  We assume
122      that all fields need copying, and then clear the fields that should
123      not be copied.  That is the sensible default behavior, and forces
124      us to explicitly document why we are *not* copying a flag.  */
125   x = shallow_copy_rtx (x);
126 
127   /* We do not copy the USED flag, which is used as a mark bit during
128      walks over the RTL.  */
129   RTX_FLAG (x, used) = 0;
130 
131   /* We do not copy FRAME_RELATED for INSNs.  */
132   if (INSN_P (x))
133     RTX_FLAG (x, frame_related) = 0;
134 
135   fmt = GET_RTX_FORMAT (code);
136   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
137     if (fmt[i] == 'e')
138       XEXP (x, i) = cleanup_auto_inc_dec (XEXP (x, i), mem_mode);
139     else if (fmt[i] == 'E' || fmt[i] == 'V')
140       {
141 	int j;
142 	XVEC (x, i) = rtvec_alloc (XVECLEN (x, i));
143 	for (j = 0; j < XVECLEN (x, i); j++)
144 	  XVECEXP (x, i, j)
145 	    = cleanup_auto_inc_dec (XVECEXP (src, i, j), mem_mode);
146       }
147 
148 #else /* !AUTO_INC_DEC */
149   x = copy_rtx (x);
150 #endif /* !AUTO_INC_DEC */
151 
152   return x;
153 }
154 
155 /* Auxiliary data structure for propagate_for_debug_stmt.  */
156 
157 struct rtx_subst_pair
158 {
159   rtx to;
160   bool adjusted;
161 };
162 
163 /* DATA points to an rtx_subst_pair.  Return the value that should be
164    substituted.  */
165 
166 static rtx
167 propagate_for_debug_subst (rtx from, const_rtx old_rtx, void *data)
168 {
169   struct rtx_subst_pair *pair = (struct rtx_subst_pair *)data;
170 
171   if (!rtx_equal_p (from, old_rtx))
172     return NULL_RTX;
173   if (!pair->adjusted)
174     {
175       pair->adjusted = true;
176       pair->to = cleanup_auto_inc_dec (pair->to, VOIDmode);
177       pair->to = make_compound_operation (pair->to, SET);
178       return pair->to;
179     }
180   return copy_rtx (pair->to);
181 }
182 
183 /* Replace all the occurrences of DEST with SRC in DEBUG_INSNs between INSN
184    and LAST, not including INSN, but including LAST.  Also stop at the end
185    of THIS_BASIC_BLOCK.  */
186 
187 void
188 propagate_for_debug (rtx_insn *insn, rtx_insn *last, rtx dest, rtx src,
189 		     basic_block this_basic_block)
190 {
191   rtx_insn *next, *end = NEXT_INSN (BB_END (this_basic_block));
192   rtx loc;
193   rtx (*saved_rtl_hook_no_emit) (machine_mode, rtx);
194 
195   struct rtx_subst_pair p;
196   p.to = src;
197   p.adjusted = false;
198 
199   next = NEXT_INSN (insn);
200   last = NEXT_INSN (last);
201   saved_rtl_hook_no_emit = rtl_hooks.gen_lowpart_no_emit;
202   rtl_hooks.gen_lowpart_no_emit = gen_lowpart_for_debug;
203   while (next != last && next != end)
204     {
205       insn = next;
206       next = NEXT_INSN (insn);
207       if (DEBUG_INSN_P (insn))
208 	{
209 	  loc = simplify_replace_fn_rtx (INSN_VAR_LOCATION_LOC (insn),
210 					 dest, propagate_for_debug_subst, &p);
211 	  if (loc == INSN_VAR_LOCATION_LOC (insn))
212 	    continue;
213 	  INSN_VAR_LOCATION_LOC (insn) = loc;
214 	  df_insn_rescan (insn);
215 	}
216     }
217   rtl_hooks.gen_lowpart_no_emit = saved_rtl_hook_no_emit;
218 }
219 
220 /* Initialize DEBUG to an empty list, and clear USED, if given.  */
221 
222 void
223 dead_debug_global_init (struct dead_debug_global *debug, bitmap used)
224 {
225   debug->used = used;
226   debug->htab = NULL;
227   if (used)
228     bitmap_clear (used);
229 }
230 
231 /* Initialize DEBUG to an empty list, and clear USED, if given.  Link
232    back to GLOBAL, if given, and bring in used bits from it.  */
233 
234 void
235 dead_debug_local_init (struct dead_debug_local *debug, bitmap used,
236 		       struct dead_debug_global *global)
237 {
238   if (!used && global && global->used)
239     used = BITMAP_ALLOC (NULL);
240 
241   debug->head = NULL;
242   debug->global = global;
243   debug->used = used;
244   debug->to_rescan = NULL;
245 
246   if (used)
247     {
248       if (global && global->used)
249 	bitmap_copy (used, global->used);
250       else
251 	bitmap_clear (used);
252     }
253 }
254 
255 /* Locate the entry for REG in GLOBAL->htab.  */
256 
257 static dead_debug_global_entry *
258 dead_debug_global_find (struct dead_debug_global *global, rtx reg)
259 {
260   dead_debug_global_entry temp_entry;
261   temp_entry.reg = reg;
262 
263   dead_debug_global_entry *entry = global->htab->find (&temp_entry);
264   gcc_checking_assert (entry && entry->reg == temp_entry.reg);
265 
266   return entry;
267 }
268 
269 /* Insert an entry mapping REG to DTEMP in GLOBAL->htab.  */
270 
271 static dead_debug_global_entry *
272 dead_debug_global_insert (struct dead_debug_global *global, rtx reg, rtx dtemp)
273 {
274   dead_debug_global_entry temp_entry;
275   temp_entry.reg = reg;
276   temp_entry.dtemp = dtemp;
277 
278   if (!global->htab)
279     global->htab = new hash_table<dead_debug_hash_descr> (31);
280 
281   dead_debug_global_entry **slot = global->htab->find_slot (&temp_entry,
282 							    INSERT);
283   gcc_checking_assert (!*slot);
284   *slot = XNEW (dead_debug_global_entry);
285   **slot = temp_entry;
286   return *slot;
287 }
288 
289 /* If UREGNO, referenced by USE, is a pseudo marked as used in GLOBAL,
290    replace it with with a USE of the debug temp recorded for it, and
291    return TRUE.  Otherwise, just return FALSE.
292 
293    If PTO_RESCAN is given, instead of rescanning modified INSNs right
294    away, add their UIDs to the bitmap, allocating one of *PTO_RESCAN
295    is NULL.  */
296 
297 static bool
298 dead_debug_global_replace_temp (struct dead_debug_global *global,
299 				df_ref use, unsigned int uregno,
300 				bitmap *pto_rescan)
301 {
302   if (!global || uregno < FIRST_PSEUDO_REGISTER
303       || !global->used
304       || !REG_P (*DF_REF_REAL_LOC (use))
305       || REGNO (*DF_REF_REAL_LOC (use)) != uregno
306       || !bitmap_bit_p (global->used, uregno))
307     return false;
308 
309   dead_debug_global_entry *entry
310     = dead_debug_global_find (global, *DF_REF_REAL_LOC (use));
311   gcc_checking_assert (GET_CODE (entry->reg) == REG
312 		       && REGNO (entry->reg) == uregno);
313 
314   if (!entry->dtemp)
315     return true;
316 
317   *DF_REF_REAL_LOC (use) = entry->dtemp;
318   if (!pto_rescan)
319     df_insn_rescan (DF_REF_INSN (use));
320   else
321     {
322       if (!*pto_rescan)
323 	*pto_rescan = BITMAP_ALLOC (NULL);
324       bitmap_set_bit (*pto_rescan, INSN_UID (DF_REF_INSN (use)));
325     }
326 
327   return true;
328 }
329 
330 /* Reset all debug uses in HEAD, and clear DEBUG->to_rescan bits of
331    each reset insn.  DEBUG is not otherwise modified.  If HEAD is
332    DEBUG->head, DEBUG->head will be set to NULL at the end.
333    Otherwise, entries from DEBUG->head that pertain to reset insns
334    will be removed, and only then rescanned.  */
335 
336 static void
337 dead_debug_reset_uses (struct dead_debug_local *debug,
338 		       struct dead_debug_use *head)
339 {
340   bool got_head = (debug->head == head);
341   bitmap rescan;
342   struct dead_debug_use **tailp = &debug->head;
343   struct dead_debug_use *cur;
344   bitmap_iterator bi;
345   unsigned int uid;
346 
347   if (got_head)
348     rescan = NULL;
349   else
350     rescan = BITMAP_ALLOC (NULL);
351 
352   while (head)
353     {
354       struct dead_debug_use *next = head->next;
355       rtx_insn *insn;
356 
357       insn = DF_REF_INSN (head->use);
358       if (!next || DF_REF_INSN (next->use) != insn)
359 	{
360 	  INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
361 	  if (got_head)
362 	    df_insn_rescan_debug_internal (insn);
363 	  else
364 	    bitmap_set_bit (rescan, INSN_UID (insn));
365 	  if (debug->to_rescan)
366 	    bitmap_clear_bit (debug->to_rescan, INSN_UID (insn));
367 	}
368       XDELETE (head);
369       head = next;
370     }
371 
372   if (got_head)
373     {
374       debug->head = NULL;
375       return;
376     }
377 
378   while ((cur = *tailp))
379     if (bitmap_bit_p (rescan, INSN_UID (DF_REF_INSN (cur->use))))
380       {
381 	*tailp = cur->next;
382 	XDELETE (cur);
383       }
384     else
385       tailp = &cur->next;
386 
387   EXECUTE_IF_SET_IN_BITMAP (rescan, 0, uid, bi)
388     {
389       struct df_insn_info *insn_info = DF_INSN_UID_SAFE_GET (uid);
390       if (insn_info)
391 	df_insn_rescan_debug_internal (insn_info->insn);
392     }
393 
394   BITMAP_FREE (rescan);
395 }
396 
397 /* Promote pending local uses of pseudos in DEBUG to global
398    substitutions.  Uses of non-pseudos are left alone for
399    resetting.  */
400 
401 static void
402 dead_debug_promote_uses (struct dead_debug_local *debug)
403 {
404   for (struct dead_debug_use *head = debug->head, **headp = &debug->head;
405        head; head = *headp)
406     {
407       rtx reg = *DF_REF_REAL_LOC (head->use);
408       df_ref ref;
409       dead_debug_global_entry *entry;
410 
411       if (GET_CODE (reg) != REG
412 	  || REGNO (reg) < FIRST_PSEUDO_REGISTER)
413 	{
414 	  headp = &head->next;
415 	  continue;
416 	}
417 
418       if (!debug->global->used)
419 	debug->global->used = BITMAP_ALLOC (NULL);
420 
421       bool added = bitmap_set_bit (debug->global->used, REGNO (reg));
422       gcc_checking_assert (added);
423 
424       entry = dead_debug_global_insert (debug->global, reg,
425 					make_debug_expr_from_rtl (reg));
426 
427       gcc_checking_assert (entry->dtemp);
428 
429       /* Tentatively remove the USE from the list.  */
430       *headp = head->next;
431 
432       if (!debug->to_rescan)
433 	debug->to_rescan = BITMAP_ALLOC (NULL);
434 
435       for (ref = DF_REG_USE_CHAIN (REGNO (reg)); ref;
436 	   ref = DF_REF_NEXT_REG (ref))
437 	if (DEBUG_INSN_P (DF_REF_INSN (ref)))
438 	  {
439 	    if (!dead_debug_global_replace_temp (debug->global, ref,
440 						 REGNO (reg),
441 						 &debug->to_rescan))
442 	      {
443 		rtx_insn *insn = DF_REF_INSN (ref);
444 		INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
445 		bitmap_set_bit (debug->to_rescan, INSN_UID (insn));
446 	      }
447 	  }
448 
449       for (ref = DF_REG_DEF_CHAIN (REGNO (reg)); ref;
450 	   ref = DF_REF_NEXT_REG (ref))
451 	if (!dead_debug_insert_temp (debug, REGNO (reg), DF_REF_INSN (ref),
452 				     DEBUG_TEMP_BEFORE_WITH_VALUE))
453 	  {
454 	    rtx bind;
455 	    bind = gen_rtx_VAR_LOCATION (GET_MODE (reg),
456 					 DEBUG_EXPR_TREE_DECL (entry->dtemp),
457 					 gen_rtx_UNKNOWN_VAR_LOC (),
458 					 VAR_INIT_STATUS_INITIALIZED);
459 	    rtx_insn *insn = emit_debug_insn_before (bind, DF_REF_INSN (ref));
460 	    bitmap_set_bit (debug->to_rescan, INSN_UID (insn));
461 	  }
462 
463       entry->dtemp = NULL;
464       XDELETE (head);
465     }
466 }
467 
468 /* Reset all debug insns with pending uses.  Release the bitmap in it,
469    unless it is USED.  USED must be the same bitmap passed to
470    dead_debug_local_init.  */
471 
472 void
473 dead_debug_local_finish (struct dead_debug_local *debug, bitmap used)
474 {
475   if (debug->global)
476     dead_debug_promote_uses (debug);
477 
478   if (debug->used != used)
479     BITMAP_FREE (debug->used);
480 
481   dead_debug_reset_uses (debug, debug->head);
482 
483   if (debug->to_rescan)
484     {
485       bitmap_iterator bi;
486       unsigned int uid;
487 
488       EXECUTE_IF_SET_IN_BITMAP (debug->to_rescan, 0, uid, bi)
489 	{
490 	  struct df_insn_info *insn_info = DF_INSN_UID_SAFE_GET (uid);
491 	  if (insn_info)
492 	    df_insn_rescan (insn_info->insn);
493 	}
494       BITMAP_FREE (debug->to_rescan);
495     }
496 }
497 
498 /* Release GLOBAL->used unless it is the same as USED.  Release the
499    mapping hash table if it was initialized.  */
500 
501 void
502 dead_debug_global_finish (struct dead_debug_global *global, bitmap used)
503 {
504   if (global->used != used)
505     BITMAP_FREE (global->used);
506 
507   delete global->htab;
508   global->htab = NULL;
509 }
510 
511 /* Add USE to DEBUG, or substitute it right away if it's a pseudo in
512    the global substitution list.  USE must be a dead reference to
513    UREGNO in a debug insn.  Create a bitmap for DEBUG as needed.  */
514 
515 void
516 dead_debug_add (struct dead_debug_local *debug, df_ref use, unsigned int uregno)
517 {
518   if (dead_debug_global_replace_temp (debug->global, use, uregno,
519 				      &debug->to_rescan))
520     return;
521 
522   struct dead_debug_use *newddu = XNEW (struct dead_debug_use);
523 
524   newddu->use = use;
525   newddu->next = debug->head;
526   debug->head = newddu;
527 
528   if (!debug->used)
529     debug->used = BITMAP_ALLOC (NULL);
530 
531   /* ??? If we dealt with split multi-registers below, we should set
532      all registers for the used mode in case of hardware
533      registers.  */
534   bitmap_set_bit (debug->used, uregno);
535 }
536 
537 /* Like lowpart_subreg, but if a subreg is not valid for machine, force
538    it anyway - for use in debug insns.  */
539 
540 static rtx
541 debug_lowpart_subreg (machine_mode outer_mode, rtx expr,
542 		      machine_mode inner_mode)
543 {
544   if (inner_mode == VOIDmode)
545     inner_mode = GET_MODE (expr);
546   int offset = subreg_lowpart_offset (outer_mode, inner_mode);
547   rtx ret = simplify_gen_subreg (outer_mode, expr, inner_mode, offset);
548   if (ret)
549     return ret;
550   return gen_rtx_raw_SUBREG (outer_mode, expr, offset);
551 }
552 
553 /* If UREGNO is referenced by any entry in DEBUG, emit a debug insn
554    before or after INSN (depending on WHERE), that binds a (possibly
555    global) debug temp to the widest-mode use of UREGNO, if WHERE is
556    *_WITH_REG, or the value stored in UREGNO by INSN otherwise, and
557    replace all uses of UREGNO in DEBUG with uses of the debug temp.
558    INSN must be where UREGNO dies, if WHERE is *_BEFORE_*, or where it
559    is set otherwise.  Return the number of debug insns emitted.  */
560 
561 int
562 dead_debug_insert_temp (struct dead_debug_local *debug, unsigned int uregno,
563 			rtx_insn *insn, enum debug_temp_where where)
564 {
565   struct dead_debug_use **tailp = &debug->head;
566   struct dead_debug_use *cur;
567   struct dead_debug_use *uses = NULL;
568   struct dead_debug_use **usesp = &uses;
569   rtx reg = NULL_RTX;
570   rtx breg;
571   rtx dval = NULL_RTX;
572   rtx bind;
573   bool global;
574 
575   if (!debug->used)
576     return 0;
577 
578   global = (debug->global && debug->global->used
579 	    && bitmap_bit_p (debug->global->used, uregno));
580 
581   if (!global && !bitmap_clear_bit (debug->used, uregno))
582     return 0;
583 
584   /* Move all uses of uregno from debug->head to uses, setting mode to
585      the widest referenced mode.  */
586   while ((cur = *tailp))
587     {
588       if (DF_REF_REGNO (cur->use) == uregno)
589 	{
590 	  /* If this loc has been changed e.g. to debug_expr already
591 	     as part of a multi-register use, just drop it.  */
592 	  if (!REG_P (*DF_REF_REAL_LOC (cur->use)))
593 	    {
594 	      *tailp = cur->next;
595 	      XDELETE (cur);
596 	      continue;
597 	    }
598 	  *usesp = cur;
599 	  usesp = &cur->next;
600 	  *tailp = cur->next;
601 	  cur->next = NULL;
602 	  if (!reg
603 	      || (GET_MODE_BITSIZE (GET_MODE (reg))
604 		  < GET_MODE_BITSIZE (GET_MODE (*DF_REF_REAL_LOC (cur->use)))))
605 	    reg = *DF_REF_REAL_LOC (cur->use);
606 	}
607       else
608 	tailp = &(*tailp)->next;
609     }
610 
611   /* We may have dangling bits in debug->used for registers that were part
612      of a multi-register use, one component of which has been reset.  */
613   if (reg == NULL)
614     {
615       gcc_checking_assert (!uses);
616       if (!global)
617 	return 0;
618     }
619 
620   if (global)
621     {
622       if (!reg)
623 	reg = regno_reg_rtx[uregno];
624       dead_debug_global_entry *entry
625 	= dead_debug_global_find (debug->global, reg);
626       gcc_checking_assert (entry->reg == reg);
627       dval = entry->dtemp;
628       if (!dval)
629 	return 0;
630     }
631 
632   gcc_checking_assert (uses || global);
633 
634   breg = reg;
635   /* Recover the expression INSN stores in REG.  */
636   if (where == DEBUG_TEMP_BEFORE_WITH_VALUE)
637     {
638       rtx set = single_set (insn);
639       rtx dest, src;
640 
641       if (set)
642 	{
643 	  dest = SET_DEST (set);
644 	  src = SET_SRC (set);
645 	  /* Lose if the REG-setting insn is a CALL.  */
646 	  if (GET_CODE (src) == CALL)
647 	    {
648 	      while (uses)
649 		{
650 		  cur = uses->next;
651 		  XDELETE (uses);
652 		  uses = cur;
653 		}
654 	      return 0;
655 	    }
656 	}
657 
658       /* ??? Should we try to extract it from a PARALLEL?  */
659       if (!set)
660 	breg = NULL;
661       /* Cool, it's the same REG, we can use SRC.  */
662       else if (dest == reg)
663 	breg = cleanup_auto_inc_dec (src, VOIDmode);
664       else if (REG_P (dest))
665 	{
666 	  /* Hmm...  Something's fishy, we should be setting REG here.  */
667 	  if (REGNO (dest) != REGNO (reg))
668 	    breg = NULL;
669 	  /* If we're not overwriting all the hardware registers that
670 	     setting REG in its mode would, we won't know what to bind
671 	     the debug temp to.  ??? We could bind the debug_expr to a
672 	     CONCAT or PARALLEL with the split multi-registers, and
673 	     replace them as we found the corresponding sets.  */
674 	  else if (REGNO (reg) < FIRST_PSEUDO_REGISTER
675 		   && (hard_regno_nregs[REGNO (reg)][GET_MODE (reg)]
676 		       != hard_regno_nregs[REGNO (reg)][GET_MODE (dest)]))
677 	    breg = NULL;
678 	  /* Ok, it's the same (hardware) REG, but with a different
679 	     mode, so SUBREG it.  */
680 	  else
681 	    breg = debug_lowpart_subreg (GET_MODE (reg),
682 					 cleanup_auto_inc_dec (src, VOIDmode),
683 					 GET_MODE (dest));
684 	}
685       else if (GET_CODE (dest) == SUBREG)
686 	{
687 	  /* We should be setting REG here.  Lose.  */
688 	  if (REGNO (SUBREG_REG (dest)) != REGNO (reg))
689 	    breg = NULL;
690 	  /* Lose if we're setting something other than the lowpart of
691 	     REG.  */
692 	  else if (!subreg_lowpart_p (dest))
693 	    breg = NULL;
694 	  /* If we're not overwriting all the hardware registers that
695 	     setting REG in its mode would, we won't know what to bind
696 	     the debug temp to.  */
697 	  else if (REGNO (reg) < FIRST_PSEUDO_REGISTER
698 		   && (hard_regno_nregs[REGNO (reg)][GET_MODE (reg)]
699 		       != hard_regno_nregs[REGNO (reg)][GET_MODE (dest)]))
700 	    breg = NULL;
701 	  /* Yay, we can use SRC, just adjust its mode.  */
702 	  else
703 	    breg = debug_lowpart_subreg (GET_MODE (reg),
704 					 cleanup_auto_inc_dec (src, VOIDmode),
705 					 GET_MODE (dest));
706 	}
707       /* Oh well, we're out of luck.  */
708       else
709 	breg = NULL;
710 
711       /* We couldn't figure out the value stored in REG, so reset all
712 	 of its pending debug uses.  */
713       if (!breg)
714 	{
715 	  dead_debug_reset_uses (debug, uses);
716 	  return 0;
717 	}
718     }
719 
720   /* If there's a single (debug) use of an otherwise unused REG, and
721      the debug use is not part of a larger expression, then it
722      probably doesn't make sense to introduce a new debug temp.  */
723   if (where == DEBUG_TEMP_AFTER_WITH_REG && !uses->next)
724     {
725       rtx_insn *next = DF_REF_INSN (uses->use);
726 
727       if (DEBUG_INSN_P (next) && reg == INSN_VAR_LOCATION_LOC (next))
728 	{
729 	  XDELETE (uses);
730 	  return 0;
731 	}
732     }
733 
734   if (!global)
735     /* Create DEBUG_EXPR (and DEBUG_EXPR_DECL).  */
736     dval = make_debug_expr_from_rtl (reg);
737 
738   /* Emit a debug bind insn before the insn in which reg dies.  */
739   bind = gen_rtx_VAR_LOCATION (GET_MODE (reg),
740 			       DEBUG_EXPR_TREE_DECL (dval), breg,
741 			       VAR_INIT_STATUS_INITIALIZED);
742 
743   if (where == DEBUG_TEMP_AFTER_WITH_REG
744       || where == DEBUG_TEMP_AFTER_WITH_REG_FORCE)
745     bind = emit_debug_insn_after (bind, insn);
746   else
747     bind = emit_debug_insn_before (bind, insn);
748   if (debug->to_rescan == NULL)
749     debug->to_rescan = BITMAP_ALLOC (NULL);
750   bitmap_set_bit (debug->to_rescan, INSN_UID (bind));
751 
752   /* Adjust all uses.  */
753   while ((cur = uses))
754     {
755       if (GET_MODE (*DF_REF_REAL_LOC (cur->use)) == GET_MODE (reg))
756 	*DF_REF_REAL_LOC (cur->use) = dval;
757       else
758 	*DF_REF_REAL_LOC (cur->use)
759 	  = debug_lowpart_subreg (GET_MODE (*DF_REF_REAL_LOC (cur->use)), dval,
760 				  GET_MODE (dval));
761       /* ??? Should we simplify subreg of subreg?  */
762       bitmap_set_bit (debug->to_rescan, INSN_UID (DF_REF_INSN (cur->use)));
763       uses = cur->next;
764       XDELETE (cur);
765     }
766 
767   return 1;
768 }
769