for gcc/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* df.h (enum debug_temp_where): New.
(dead_debug_init, dead_debug_finish) Declare.
(dead_debug_add, dead_debug_insert_temp): Declare.
(struct dead_debug_use, struct dead_debug): Moved from...
* df-problems.c: ... here.
(df_set_unused_notes_for_mw): Bind debug uses of unused regno
to a debug temp.
(df_create_unused_note): Likewise.
(df_set_dead_notes_for_mw): Move comment where it belongs.
(dead_debug_init): Export.
(dead_debug_reset_uses): New, factored out of...
(dead_debug_finish): ...this. Export.
(dead_debug_reset): Remove.
(dead_debug_add): Export.
(dead_debug_insert_before): Rename to...
(dead_debug_insert_temp): ... this. Add where argument. Export.
Locate stored value for BEFORE_WITH_VALUE. Avoid repeat inserts.
Return insertion count.
(df_note_bb_compute): Adjust.
* dce.c (reset_unmarked_insns_debug_uses): New.
(delete_unmarked_insns): Skip debug insns.
(prescan_insns_for_dce): Likewise.
(rest_of_handle_ud_dce): Propagate debug uses.
(word_dce_process_block): Adjust dead debug uses.
(dce_process_block): Likewise.
* reg-stack.c (subst_stack_regs_in_debug_insn): Signal when no
active reg can be found.
(subst_all_stack_regs_in_debug_insn): New. Reset debug insn then.
(convert_regs_1): Use it.
===================================================================
@@ -2842,25 +2842,6 @@ df_whole_mw_reg_unused_p (struct df_mw_h
}
-/* Node of a linked list of uses of dead REGs in debug insns. */
-struct dead_debug_use
-{
- df_ref use;
- struct dead_debug_use *next;
-};
-
-/* Linked list of the above, with a bitmap of the REGs in the
- list. */
-struct dead_debug
-{
- struct dead_debug_use *head;
- bitmap used;
- bitmap to_rescan;
-};
-
-static void dead_debug_reset (struct dead_debug *, unsigned int);
-
-
/* Set the REG_UNUSED notes for the multiword hardreg defs in INSN
based on the bits in LIVE. Do not generate notes for registers in
artificial uses. DO_NOT_GEN is updated so that REG_DEAD notes are
@@ -2886,7 +2867,7 @@ df_set_unused_notes_for_mw (rtx insn, st
{
unsigned int regno = mws->start_regno;
df_set_note (REG_UNUSED, insn, mws->mw_reg);
- dead_debug_reset (debug, regno);
+ dead_debug_insert_temp (debug, regno, insn, DEBUG_TEMP_AFTER_WITH_REG);
#ifdef REG_DEAD_DEBUGGING
df_print_note ("adding 1: ", insn, REG_NOTES (insn));
@@ -2901,7 +2882,7 @@ df_set_unused_notes_for_mw (rtx insn, st
&& !bitmap_bit_p (artificial_uses, r))
{
df_set_note (REG_UNUSED, insn, regno_reg_rtx[r]);
- dead_debug_reset (debug, r);
+ dead_debug_insert_temp (debug, r, insn, DEBUG_TEMP_AFTER_WITH_REG);
#ifdef REG_DEAD_DEBUGGING
df_print_note ("adding 2: ", insn, REG_NOTES (insn));
#endif
@@ -2969,12 +2950,12 @@ df_set_dead_notes_for_mw (rtx insn, stru
if (df_whole_mw_reg_dead_p (mws, live, artificial_uses, do_not_gen))
{
- /* Add a dead note for the entire multi word register. */
if (is_debug)
{
*added_notes_p = true;
return;
}
+ /* Add a dead note for the entire multi word register. */
df_set_note (REG_DEAD, insn, mws->mw_reg);
#ifdef REG_DEAD_DEBUGGING
df_print_note ("adding 1: ", insn, REG_NOTES (insn));
@@ -3028,7 +3009,7 @@ df_create_unused_note (rtx insn, df_ref
rtx reg = (DF_REF_LOC (def))
? *DF_REF_REAL_LOC (def): DF_REF_REG (def);
df_set_note (REG_UNUSED, insn, reg);
- dead_debug_reset (debug, dregno);
+ dead_debug_insert_temp (debug, dregno, insn, DEBUG_TEMP_AFTER_WITH_REG);
#ifdef REG_DEAD_DEBUGGING
df_print_note ("adding 3: ", insn, REG_NOTES (insn));
#endif
@@ -3039,7 +3020,7 @@ df_create_unused_note (rtx insn, df_ref
/* Initialize DEBUG to an empty list, and clear USED, if given. */
-static inline void
+void
dead_debug_init (struct dead_debug *debug, bitmap used)
{
debug->head = NULL;
@@ -3049,32 +3030,83 @@ dead_debug_init (struct dead_debug *debu
bitmap_clear (used);
}
-/* 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_init. */
-static inline void
-dead_debug_finish (struct dead_debug *debug, bitmap used)
+/* 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 *debug, struct dead_debug_use *head)
{
- struct dead_debug_use *head;
- rtx insn = NULL;
+ 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 (debug->used != used)
- BITMAP_FREE (debug->used);
+ if (got_head)
+ rescan = NULL;
+ else
+ rescan = BITMAP_ALLOC (NULL);
- while ((head = debug->head))
+ while (head)
{
+ struct dead_debug_use *next = head->next;
+ rtx insn;
+
insn = DF_REF_INSN (head->use);
- if (!head->next || DF_REF_INSN (head->next->use) != insn)
+ if (!next || DF_REF_INSN (next->use) != insn)
{
INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
- df_insn_rescan_debug_internal (insn);
+ 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));
}
- debug->head = head->next;
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);
+}
+
+/* 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_init. */
+void
+dead_debug_finish (struct dead_debug *debug, bitmap used)
+{
+ if (debug->used != used)
+ BITMAP_FREE (debug->used);
+
+ dead_debug_reset_uses (debug, debug->head);
+
if (debug->to_rescan)
{
bitmap_iterator bi;
@@ -3090,37 +3122,9 @@ dead_debug_finish (struct dead_debug *de
}
}
-/* Reset DEBUG_INSNs with pending uses of DREGNO. */
-static void
-dead_debug_reset (struct dead_debug *debug, unsigned int dregno)
-{
- struct dead_debug_use **tailp = &debug->head;
- struct dead_debug_use *cur;
- rtx insn;
-
- if (!debug->used || !bitmap_clear_bit (debug->used, dregno))
- return;
-
- while ((cur = *tailp))
- {
- if (DF_REF_REGNO (cur->use) == dregno)
- {
- *tailp = cur->next;
- insn = DF_REF_INSN (cur->use);
- INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
- if (debug->to_rescan == NULL)
- debug->to_rescan = BITMAP_ALLOC (NULL);
- bitmap_set_bit (debug->to_rescan, INSN_UID (insn));
- XDELETE (cur);
- }
- else
- tailp = &(*tailp)->next;
- }
-}
-
/* Add USE to DEBUG. It must be a dead reference to UREGNO in a debug
insn. Create a bitmap for DEBUG as needed. */
-static inline void
+void
dead_debug_add (struct dead_debug *debug, df_ref use, unsigned int uregno)
{
struct dead_debug_use *newddu = XNEW (struct dead_debug_use);
@@ -3136,12 +3140,15 @@ dead_debug_add (struct dead_debug *debug
}
/* If UREGNO is referenced by any entry in DEBUG, emit a debug insn
- before INSN that binds the REG to a debug temp, and replace all
- uses of UREGNO in DEBUG with uses of the debug temp. INSN must be
- the insn where UREGNO dies. */
-static inline void
-dead_debug_insert_before (struct dead_debug *debug, unsigned int uregno,
- rtx insn)
+ before or after INSN (depending on WHERE), that binds a debug temp
+ to the widest-mode use of UREGNO, if WHERE is _WITH_REG, or
+ _WITH_VALUE otherwise, and replace all uses of UREGNO in DEBUG with
+ uses of the debug temp. INSN must be where UREGNO dies, if WHERE
+ is DEAD_DEBUG_BEFORE_WITH_REG, or where it is set otherwise.
+ Return the number of debug insns emitted. */
+int
+dead_debug_insert_temp (struct dead_debug *debug, unsigned int uregno,
+ rtx insn, enum debug_temp_where where)
{
struct dead_debug_use **tailp = &debug->head;
struct dead_debug_use *cur;
@@ -3152,7 +3159,7 @@ dead_debug_insert_before (struct dead_de
rtx bind;
if (!debug->used || !bitmap_clear_bit (debug->used, uregno))
- return;
+ return 0;
/* Move all uses of uregno from debug->head to uses, setting mode to
the widest referenced mode. */
@@ -3173,17 +3180,100 @@ dead_debug_insert_before (struct dead_de
tailp = &(*tailp)->next;
}
- gcc_assert (reg);
+ if (!reg)
+ {
+ gcc_checking_assert (!uses);
+ return 0;
+ }
+
+ gcc_checking_assert (uses);
+
+ bind = 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);
+ if (GET_CODE (src) == CALL)
+ {
+ while (uses)
+ {
+ cur = uses->next;
+ XDELETE (uses);
+ uses = cur;
+ }
+ return 0;
+ }
+ }
+ else
+ set = NULL;
+
+ if (!set)
+ bind = NULL;
+ else if (dest == reg)
+ bind = copy_rtx (src);
+ else if (REG_P (dest))
+ {
+ if (REGNO (dest) != REGNO (reg))
+ bind = NULL;
+ else
+ bind = lowpart_subreg (GET_MODE (reg), copy_rtx (src),
+ GET_MODE (dest));
+ }
+ else if (GET_CODE (dest) == SUBREG)
+ {
+ if (REGNO (SUBREG_REG (dest)) != REGNO (reg))
+ bind = NULL;
+ else if (!subreg_lowpart_p (dest))
+ bind = NULL;
+ else if (REGNO (reg) < FIRST_PSEUDO_REGISTER
+ && (hard_regno_nregs[REGNO (reg)][GET_MODE (reg)]
+ == hard_regno_nregs[REGNO (reg)][GET_MODE (dest)]))
+ bind = NULL;
+ else
+ bind = lowpart_subreg (GET_MODE (reg), copy_rtx (src),
+ GET_MODE (dest));
+ }
+ else
+ bind = NULL;
+
+ if (!bind)
+ {
+ 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 next = DF_REF_INSN (uses->use);
+
+ if (DEBUG_INSN_P (next) && reg == INSN_VAR_LOCATION_LOC (next))
+ {
+ XDELETE (uses);
+ return 0;
+ }
+ }
/* 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), reg,
+ DEBUG_EXPR_TREE_DECL (dval), bind,
VAR_INIT_STATUS_INITIALIZED);
- bind = emit_debug_insn_before (bind, insn);
+ if (where == DEBUG_TEMP_AFTER_WITH_REG)
+ bind = emit_debug_insn_after (bind, insn);
+ else
+ bind = emit_debug_insn_before (bind, insn);
df_insn_rescan (bind);
/* Adjust all uses. */
@@ -3201,6 +3291,8 @@ dead_debug_insert_before (struct dead_de
uses = cur->next;
XDELETE (cur);
}
+
+ return 1;
}
/* Recompute the REG_DEAD and REG_UNUSED notes and compute register
@@ -3395,7 +3487,8 @@ df_note_bb_compute (unsigned int bb_inde
break;
}
else
- dead_debug_insert_before (&debug, uregno, insn);
+ dead_debug_insert_temp (&debug, uregno, insn,
+ DEBUG_TEMP_BEFORE_WITH_REG);
if ( (!(DF_REF_FLAGS (use)
& (DF_REF_MW_HARDREG | DF_REF_READ_WRITE)))
===================================================================
@@ -493,6 +493,43 @@ remove_reg_equal_equiv_notes_for_defs (r
remove_reg_equal_equiv_notes_for_regno (DF_REF_REGNO (*def_rec));
}
+/* Scan all BBs for debug insns and reset those that reference values
+ defined in unmarked insns. */
+
+static void
+reset_unmarked_insns_debug_uses (void)
+{
+ basic_block bb;
+ rtx insn, next;
+
+ FOR_EACH_BB_REVERSE (bb)
+ FOR_BB_INSNS_REVERSE_SAFE (bb, insn, next)
+ if (DEBUG_INSN_P (insn))
+ {
+ df_ref *use_rec;
+
+ for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++)
+ {
+ df_ref use = *use_rec;
+ struct df_link *defs;
+ for (defs = DF_REF_CHAIN (use); defs; defs = defs->next)
+ {
+ rtx insn;
+ if (DF_REF_IS_ARTIFICIAL (defs->ref))
+ continue;
+ insn = DF_REF_INSN (defs->ref);
+ if (!marked_insn_p (insn))
+ break;
+ }
+ if (!defs)
+ continue;
+ /* ??? FIXME could we propagate the values assigned to
+ each of the DEFs? */
+ INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
+ df_insn_rescan_debug_internal (insn);
+ }
+ }
+}
/* Delete every instruction that hasn't been marked. */
@@ -505,7 +542,7 @@ delete_unmarked_insns (void)
FOR_EACH_BB_REVERSE (bb)
FOR_BB_INSNS_REVERSE_SAFE (bb, insn, next)
- if (INSN_P (insn))
+ if (NONDEBUG_INSN_P (insn))
{
/* Always delete no-op moves. */
if (noop_move_p (insn))
@@ -579,7 +616,7 @@ prescan_insns_for_dce (bool fast)
FOR_EACH_BB (bb)
{
FOR_BB_INSNS_REVERSE_SAFE (bb, insn, prev)
- if (INSN_P (insn))
+ if (NONDEBUG_INSN_P (insn))
{
/* Don't mark argument stores now. They will be marked
if needed when the associated CALL is marked. */
@@ -713,6 +750,9 @@ rest_of_handle_ud_dce (void)
}
VEC_free (rtx, heap, worklist);
+ if (MAY_HAVE_DEBUG_INSNS)
+ reset_unmarked_insns_debug_uses ();
+
/* Before any insns are deleted, we must remove the chains since
they are not bidirectional. */
df_remove_problem (df_chain);
@@ -767,6 +807,7 @@ word_dce_process_block (basic_block bb,
bitmap local_live = BITMAP_ALLOC (&dce_tmp_bitmap_obstack);
rtx insn;
bool block_changed;
+ struct dead_debug debug;
if (redo_out)
{
@@ -788,11 +829,24 @@ word_dce_process_block (basic_block bb,
}
bitmap_copy (local_live, DF_WORD_LR_OUT (bb));
+ dead_debug_init (&debug, NULL);
FOR_BB_INSNS_REVERSE (bb, insn)
- if (NONDEBUG_INSN_P (insn))
+ if (DEBUG_INSN_P (insn))
+ {
+ df_ref *use_rec;
+ for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++)
+ if (DF_REF_REGNO (*use_rec) >= FIRST_PSEUDO_REGISTER
+ && (GET_MODE_SIZE (GET_MODE (DF_REF_REAL_REG (*use_rec)))
+ == 2 * UNITS_PER_WORD)
+ && !bitmap_bit_p (local_live, 2 * DF_REF_REGNO (*use_rec))
+ && !bitmap_bit_p (local_live, 2 * DF_REF_REGNO (*use_rec) + 1))
+ dead_debug_add (&debug, *use_rec, DF_REF_REGNO (*use_rec));
+ }
+ else if (INSN_P (insn))
{
bool any_changed;
+
/* No matter if the instruction is needed or not, we remove
any regno in the defs from the live set. */
any_changed = df_word_lr_simulate_defs (insn, local_live);
@@ -804,6 +858,15 @@ word_dce_process_block (basic_block bb,
if (marked_insn_p (insn))
df_word_lr_simulate_uses (insn, local_live);
+ if (debug.used && !bitmap_empty_p (debug.used))
+ {
+ df_ref *def_rec;
+
+ for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++)
+ dead_debug_insert_temp (&debug, DF_REF_REGNO (*def_rec), insn,
+ DEBUG_TEMP_BEFORE_WITH_VALUE);
+ }
+
if (dump_file)
{
fprintf (dump_file, "finished processing insn %d live out = ",
@@ -816,6 +879,7 @@ word_dce_process_block (basic_block bb,
if (block_changed)
bitmap_copy (DF_WORD_LR_IN (bb), local_live);
+ dead_debug_finish (&debug, NULL);
BITMAP_FREE (local_live);
return block_changed;
}
@@ -833,6 +897,7 @@ dce_process_block (basic_block bb, bool
rtx insn;
bool block_changed;
df_ref *def_rec;
+ struct dead_debug debug;
if (redo_out)
{
@@ -856,22 +921,36 @@ dce_process_block (basic_block bb, bool
bitmap_copy (local_live, DF_LR_OUT (bb));
df_simulate_initialize_backwards (bb, local_live);
+ dead_debug_init (&debug, NULL);
FOR_BB_INSNS_REVERSE (bb, insn)
- if (INSN_P (insn))
+ if (DEBUG_INSN_P (insn))
+ {
+ df_ref *use_rec;
+ for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++)
+ if (!bitmap_bit_p (local_live, DF_REF_REGNO (*use_rec))
+ && !bitmap_bit_p (au, DF_REF_REGNO (*use_rec)))
+ dead_debug_add (&debug, *use_rec, DF_REF_REGNO (*use_rec));
+ }
+ else if (INSN_P (insn))
{
bool needed = marked_insn_p (insn);
/* The insn is needed if there is someone who uses the output. */
if (!needed)
for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++)
- if (bitmap_bit_p (local_live, DF_REF_REGNO (*def_rec))
- || bitmap_bit_p (au, DF_REF_REGNO (*def_rec)))
- {
- needed = true;
- mark_insn (insn, true);
- break;
- }
+ {
+ dead_debug_insert_temp (&debug, DF_REF_REGNO (*def_rec), insn,
+ DEBUG_TEMP_BEFORE_WITH_VALUE);
+
+ if (bitmap_bit_p (local_live, DF_REF_REGNO (*def_rec))
+ || bitmap_bit_p (au, DF_REF_REGNO (*def_rec)))
+ {
+ needed = true;
+ mark_insn (insn, true);
+ break;
+ }
+ }
/* No matter if the instruction is needed or not, we remove
any regno in the defs from the live set. */
@@ -883,6 +962,7 @@ dce_process_block (basic_block bb, bool
df_simulate_uses (insn, local_live);
}
+ dead_debug_finish (&debug, NULL);
df_simulate_finalize_backwards (bb, local_live);
block_changed = !bitmap_equal_p (local_live, DF_LR_IN (bb));
===================================================================
@@ -1333,6 +1333,11 @@ subst_stack_regs_in_debug_insn (rtx *loc
return 0;
hard_regno = get_hard_regnum (regstack, *loc);
+
+ /* If we can't find an active register, reset this debug insn. */
+ if (hard_regno == -1)
+ return 1;
+
gcc_assert (hard_regno >= FIRST_STACK_REG);
replace_reg (loc, hard_regno);
@@ -1340,6 +1345,23 @@ subst_stack_regs_in_debug_insn (rtx *loc
return -1;
}
+/* Substitute hardware stack regs in debug insn INSN, using stack
+ layout REGSTACK. If we can't find a hardware stack reg for any of
+ the REGs in it, reset the debug insn. */
+
+static void
+subst_all_stack_regs_in_debug_insn (rtx insn, struct stack_def *regstack)
+{
+ int ret = for_each_rtx (&INSN_VAR_LOCATION_LOC (insn),
+ subst_stack_regs_in_debug_insn,
+ regstack);
+
+ if (ret == 1)
+ INSN_VAR_LOCATION_LOC (insn) = gen_rtx_UNKNOWN_VAR_LOC ();
+ else
+ gcc_checking_assert (ret == 0);
+}
+
/* Substitute new registers in PAT, which is part of INSN. REGSTACK
is the current register layout. Return whether a control flow insn
was deleted in the process. */
@@ -2947,8 +2969,7 @@ convert_regs_1 (basic_block block)
debug_insns_with_starting_stack++;
else
{
- for_each_rtx (&PATTERN (insn), subst_stack_regs_in_debug_insn,
- ®stack);
+ subst_all_stack_regs_in_debug_insn (insn, ®stack);
/* Nothing must ever die at a debug insn. If something
is referenced in it that becomes dead, it should have
@@ -2986,8 +3007,7 @@ convert_regs_1 (basic_block block)
continue;
debug_insns_with_starting_stack--;
- for_each_rtx (&PATTERN (insn), subst_stack_regs_in_debug_insn,
- &bi->stack_in);
+ subst_all_stack_regs_in_debug_insn (insn, &bi->stack_in);
}
}
===================================================================
@@ -1101,4 +1101,35 @@ extern void union_defs (df_ref, struct w
unsigned int *used, struct web_entry *,
bool (*fun) (struct web_entry *, struct web_entry *));
+/* Debug uses of dead regs. */
+
+/* Node of a linked list of uses of dead REGs in debug insns. */
+struct dead_debug_use
+{
+ df_ref use;
+ struct dead_debug_use *next;
+};
+
+/* Linked list of the above, with a bitmap of the REGs in the
+ list. */
+struct dead_debug
+{
+ struct dead_debug_use *head;
+ bitmap used;
+ bitmap to_rescan;
+};
+
+enum debug_temp_where
+ {
+ DEBUG_TEMP_BEFORE_WITH_REG = -1,
+ DEBUG_TEMP_BEFORE_WITH_VALUE = 0,
+ DEBUG_TEMP_AFTER_WITH_REG = 1
+ };
+
+void dead_debug_init (struct dead_debug *, bitmap);
+void dead_debug_finish (struct dead_debug *, bitmap);
+void dead_debug_add (struct dead_debug *, df_ref, unsigned int);
+int dead_debug_insert_temp (struct dead_debug *, unsigned int, rtx,
+ enum debug_temp_where);
+
#endif /* GCC_DF_H */