From 0e45ec206c6aa3715fa55a9ee8986670eff38b14 Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Mon, 29 Oct 2012 19:27:31 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 13 +++++++++++ gcc/valtrack.c | 68 ++++++++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 65 insertions(+), 16 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fd75ccd..8422ca0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,18 @@ 2012-10-29 Alexandre Oliva + 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 + 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 52f5ed6..f6c0db4 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); -- 2.7.4