This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: fix left-over debug insns in DCE
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: Alexandre Oliva <aoliva at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Mon, 9 Apr 2012 15:41:27 +0200
- Subject: Re: fix left-over debug insns in DCE
- References: <or7h9832gd.fsf@livre.localdomain> <orfwnncco8.fsf@livre.localdomain> <orsjgde8ll.fsf@livre.localdomain>
> Some more context here: this enables DCE to turn removed insns into
> debug temps when they're useful for debug info. It further improves
> debug info quality when installed along with the patch I just posted for
> PR 48866. Without it, a number of chains of debug temps that lead to a
> real insn that gets deleted end up useless.
> Regstrapped on x86_64-linux-gnu and i686-pc-linux-gnu. Ok to install?
OK for mainline, modulo the following nits:
+enum debug_temp_where
+ {
+ DEBUG_TEMP_BEFORE_WITH_REG = -1,
+ DEBUG_TEMP_BEFORE_WITH_VALUE = 0,
+ DEBUG_TEMP_AFTER_WITH_REG = 1
+ };
Could you add a comment for each value?
+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);
Missing "extern" for all declarations.
/* If UREGNO is referenced by any entry in DEBUG, emit a debug 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. */
I don't understand the "or _WITH_VALUE otherwise" part of the comment.
+ 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)
+ breg = NULL;
+ else if (dest == reg)
+ breg = copy_rtx (src);
+ else if (REG_P (dest))
+ {
+ if (REGNO (dest) != REGNO (reg))
+ breg = NULL;
+ else
+ breg = lowpart_subreg (GET_MODE (reg), copy_rtx (src),
+ GET_MODE (dest));
+ }
+ else if (GET_CODE (dest) == SUBREG)
+ {
+ if (REGNO (SUBREG_REG (dest)) != REGNO (reg))
+ breg = NULL;
+ else if (!subreg_lowpart_p (dest))
+ breg = NULL;
+ else if (REGNO (reg) < FIRST_PSEUDO_REGISTER
+ && (hard_regno_nregs[REGNO (reg)][GET_MODE (reg)]
+ == hard_regno_nregs[REGNO (reg)][GET_MODE (dest)]))
+ breg = NULL;
+ else
+ breg = lowpart_subreg (GET_MODE (reg), copy_rtx (src),
+ GET_MODE (dest));
+ }
+ else
+ breg = NULL;
+
+ if (!breg)
+ {
+ dead_debug_reset_uses (debug, uses);
+ return 0;
+ }
+ }
Please add a comment explaining what this is doing.
--
Eric Botcazou