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