summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>2012-10-29 19:27:31 +0000
committeraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>2012-10-29 19:27:31 +0000
commit92a66fbd0df7690c007e3b1bdf415f182c7fce91 (patch)
treefc4dbac1aeedff33373bc39d63f6ab98048b4828
parenteb912266699a6a5636b1042d4e1e555cc41223f3 (diff)
downloadgcc-92a66fbd0df7690c007e3b1bdf415f182c7fce91.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@192959 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/valtrack.c68
2 files changed, 65 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fd75ccd3a3e..8422ca06275 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,18 @@
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
* loop-unroll.c (loop_exit_at_end_p): Skip debug insns.
diff --git a/gcc/valtrack.c b/gcc/valtrack.c
index 52f5ed65313..f6c0db473bb 100644
--- a/gcc/valtrack.c
+++ b/gcc/valtrack.c
@@ -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);