re PR debug/54551 (DF resets some DEBUG_INSNs unnecessarily)

PR debug/54551
PR debug/54693
* valtrack.c (dead_debug_global_find): Accept NULL dtemp.
(dead_debug_global_insert): Return new entry.
(dead_debug_global_replace_temp): Return early if REG is no
longer in place, or if dtemp was already substituted.
(dead_debug_promote_uses): Insert for all defs and replace all
debug uses at once.
(dead_debug_local_finish): Release used after promotion.
(dead_debug_insert_temp): Stop if dtemp is NULL.

From-SVN: r192959
This commit is contained in:
Alexandre Oliva 2012-10-29 19:27:31 +00:00 committed by Alexandre Oliva
parent 8efb4b35f3
commit 0e45ec206c
2 changed files with 65 additions and 16 deletions

View File

@ -1,3 +1,16 @@
2012-10-29 Alexandre Oliva <aoliva@redhat.com>
PR debug/54551
PR debug/54693
* valtrack.c (dead_debug_global_find): Accept NULL dtemp.
(dead_debug_global_insert): Return new entry.
(dead_debug_global_replace_temp): Return early if REG is no
longer in place, or if dtemp was already substituted.
(dead_debug_promote_uses): Insert for all defs and replace all
debug uses at once.
(dead_debug_local_finish): Release used after promotion.
(dead_debug_insert_temp): Stop if dtemp is NULL.
2012-10-29 Alexandre Oliva <aoliva@redhat.com>
PR debug/54693

View File

@ -225,14 +225,13 @@ dead_debug_global_find (struct dead_debug_global *global, rtx reg)
dead_debug_global_entry *entry = global->htab.find (&temp_entry);
gcc_checking_assert (entry && entry->reg == temp_entry.reg);
gcc_checking_assert (entry->dtemp);
return entry;
}
/* Insert an entry mapping REG to DTEMP in GLOBAL->htab. */
static void
static dead_debug_global_entry *
dead_debug_global_insert (struct dead_debug_global *global, rtx reg, rtx dtemp)
{
dead_debug_global_entry temp_entry;
@ -246,6 +245,7 @@ dead_debug_global_insert (struct dead_debug_global *global, rtx reg, rtx dtemp)
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,
@ -263,16 +263,19 @@ dead_debug_global_replace_temp (struct dead_debug_global *global,
{
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;
gcc_checking_assert (REGNO (*DF_REF_REAL_LOC (use)) == uregno);
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));
@ -364,6 +367,8 @@ dead_debug_promote_uses (struct dead_debug_local *debug)
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)
@ -376,17 +381,46 @@ dead_debug_promote_uses (struct dead_debug_local *debug)
debug->global->used = BITMAP_ALLOC (NULL);
if (bitmap_set_bit (debug->global->used, REGNO (reg)))
dead_debug_global_insert (debug->global, reg,
make_debug_expr_from_rtl (reg));
entry = dead_debug_global_insert (debug->global, reg,
make_debug_expr_from_rtl (reg));
if (!dead_debug_global_replace_temp (debug->global, head->use,
REGNO (reg), &debug->to_rescan))
{
headp = &head->next;
continue;
}
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 = 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 = emit_debug_insn_before (bind, DF_REF_INSN (ref));
bitmap_set_bit (debug->to_rescan, INSN_UID (insn));
}
entry->dtemp = NULL;
XDELETE (head);
}
}
@ -398,12 +432,12 @@ dead_debug_promote_uses (struct dead_debug_local *debug)
void
dead_debug_local_finish (struct dead_debug_local *debug, bitmap used)
{
if (debug->used != used)
BITMAP_FREE (debug->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)
@ -535,6 +569,8 @@ dead_debug_insert_temp (struct dead_debug_local *debug, unsigned int uregno,
= 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);