dwarf2out: Add REG_CFA_FLUSH_QUEUE.

* reg-notes.def (REG_CFA_FLUSH_QUEUE): New.
        * dwarf2out.c (dwarf2out_frame_debug): Handle it.
        * final.c (final_scan_insn): Look for it, and invoke
        dwarf2out_frame_debug before the insn if found.

From-SVN: r175729
This commit is contained in:
Richard Henderson 2011-06-30 14:04:23 -07:00 committed by Richard Henderson
parent c8412f9770
commit ef284364b4
4 changed files with 44 additions and 15 deletions

View File

@ -1,3 +1,10 @@
2011-06-30 Richard Henderson <rth@redhat.com>
* reg-notes.def (REG_CFA_FLUSH_QUEUE): New.
* dwarf2out.c (dwarf2out_frame_debug): Handle it.
* final.c (final_scan_insn): Look for it, and invoke
dwarf2out_frame_debug before the insn if found.
2011-06-30 Richard Henderson <rth@redhat.com>
* dwarf2out.c (dwarf2out_frame_debug_cfa_offset): Allow PC_RTX

View File

@ -2832,6 +2832,7 @@ dwarf2out_frame_debug (rtx insn, bool after_p)
const char *label;
rtx note, n;
bool handled_one = false;
bool need_flush = false;
if (!NONJUMP_INSN_P (insn) || clobbers_queued_reg_save (insn))
dwarf2out_flush_queued_reg_saves ();
@ -2854,7 +2855,7 @@ dwarf2out_frame_debug (rtx insn, bool after_p)
{
case REG_FRAME_RELATED_EXPR:
insn = XEXP (note, 0);
goto found;
goto do_frame_expr;
case REG_CFA_DEF_CFA:
dwarf2out_frame_debug_def_cfa (XEXP (note, 0), label);
@ -2934,24 +2935,36 @@ dwarf2out_frame_debug (rtx insn, bool after_p)
handled_one = true;
break;
case REG_CFA_FLUSH_QUEUE:
/* The actual flush happens below. */
need_flush = true;
handled_one = true;
break;
default:
break;
}
if (handled_one)
{
if (any_cfis_emitted)
dwarf2out_flush_queued_reg_saves ();
return;
/* Minimize the number of advances by emitting the entire queue
once anything is emitted. */
need_flush |= any_cfis_emitted;
}
else
{
insn = PATTERN (insn);
do_frame_expr:
dwarf2out_frame_debug_expr (insn, label);
/* Check again. A parallel can save and update the same register.
We could probably check just once, here, but this is safer than
removing the check at the start of the function. */
if (any_cfis_emitted || clobbers_queued_reg_save (insn))
need_flush = true;
}
insn = PATTERN (insn);
found:
dwarf2out_frame_debug_expr (insn, label);
/* Check again. A parallel can save and update the same register.
We could probably check just once, here, but this is safer than
removing the check above. */
if (any_cfis_emitted || clobbers_queued_reg_save (insn))
if (need_flush)
dwarf2out_flush_queued_reg_saves ();
}

View File

@ -2683,7 +2683,9 @@ final_scan_insn (rtx insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
current_output_insn = debug_insn = insn;
if (CALL_P (insn) && dwarf2out_do_frame ())
if (dwarf2out_do_frame ()
&& (CALL_P (insn)
|| find_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL)))
dwarf2out_frame_debug (insn, false);
/* Find the proper template for this insn. */

View File

@ -155,16 +155,23 @@ REG_NOTE (CFA_EXPRESSION)
first pattern is the register to be restored. */
REG_NOTE (CFA_RESTORE)
/* Attached to insn that is RTX_FRAME_RELATED_P, marks insn that sets
/* Attached to insns that are RTX_FRAME_RELATED_P, marks insn that sets
vDRAP from DRAP. If vDRAP is a register, vdrap_reg is initalized
to the argument, if it is a MEM, it is ignored. */
REG_NOTE (CFA_SET_VDRAP)
/* Attached to insn that are RTX_FRAME_RELATED_P, indicating a window
/* Attached to insns that are RTX_FRAME_RELATED_P, indicating a window
save operation, i.e. will result in a DW_CFA_GNU_window_save.
The argument is ignored. */
REG_NOTE (CFA_WINDOW_SAVE)
/* Attached to insns that are RTX_FRAME_RELATED_P, marks the insn as
requiring that all queued information should be flushed *before* insn,
regardless of what is visible in the rtl. The argument is ignored.
This is normally used for a call instruction which is not exposed to
the rest of the compiler as a CALL_INSN. */
REG_NOTE (CFA_FLUSH_QUEUE)
/* Indicates that REG holds the exception context for the function.
This context is shared by inline functions, so the code to acquire
the real exception context is delayed until after inlining. */