aboutsummaryrefslogtreecommitdiff
path: root/gcc/dwarf2cfi.c
diff options
context:
space:
mode:
authorBernd Schmidt <bernds@codesourcery.com>2011-07-07 23:42:41 +0000
committerRichard Henderson <rth@gcc.gnu.org>2011-07-07 16:42:41 -0700
commitbc5612ed5640eb8e98e9f50061db7d2325113eef (patch)
treeb847cd3bf525fe133a6b119fd23ec62761a5bce8 /gcc/dwarf2cfi.c
parent647a156710dcd42a2bccce3fcc0322f2be835cae (diff)
downloadgcc-bc5612ed5640eb8e98e9f50061db7d2325113eef.zip
gcc-bc5612ed5640eb8e98e9f50061db7d2325113eef.tar.gz
gcc-bc5612ed5640eb8e98e9f50061db7d2325113eef.tar.bz2
dwarf2out: Move insn scanning out of final.c.
This patch is essentially Bernd's 005-scanfirst patch, updated for the introduction of the dwarf2cfi.c file. We introduce NOTE_INSN_CFI and NOTE_INSN_CFI_LABEL to hold the dwarf2 info during the bulk of final. The actual construction of these notes still happens during final, right at the very beginning of the pass, via the dwarf2out_frame_debug_init hook. * dwarf2cfi.c (cfi_insn): New. (dwarf2out_cfi_label): Don't emit cfi label here. (add_fde_cfi): Create a NOTE_INSN_CFI. (dwarf2out_frame_debug): Setup cfi_insn. (dwarf2out_frame_debug_init): Loop over insns creating CFI notes. (dwarf2out_cfi_begin_epilogue): Make static. (dwarf2out_frame_debug_restore_state): Make static. * dwarf2out.c (output_cfi_directive): Make static. (dwarf2out_emit_cfi): New. * dwarf2out.h: Update. * final.c (final): Remove CFI notes. (final_scan_insn): Don't call dwarf2out_cfi_begin_epilogue, dwarf2out_frame_debug_restore_state, dwarf2out_frame_debug. Handle NOTE_INSN_CFI and NOTE_INSN_CFI_LABEL. * insn-notes.def (NOTE_INSN_CFI): New. (NOTE_INSN_CFI_LABEL): New. * rtl.h (union rtunion_def): Add rt_cfi member. (XCFI, XCCFI, NOTE_CFI, NOTE_LABEL_NUMBER): New. Co-Authored-By: Richard Henderson <rth@redhat.com> From-SVN: r176016
Diffstat (limited to 'gcc/dwarf2cfi.c')
-rw-r--r--gcc/dwarf2cfi.c97
1 files changed, 80 insertions, 17 deletions
diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c
index 8de13e5..3e8958f 100644
--- a/gcc/dwarf2cfi.c
+++ b/gcc/dwarf2cfi.c
@@ -143,6 +143,19 @@ cfi_vec cie_cfi_vec;
static GTY(()) unsigned long dwarf2out_cfi_label_num;
+/* The insn after which a new CFI note should be emitted. */
+static rtx cfi_insn;
+
+/* True if remember_state should be emitted before following CFI directive. */
+static bool emit_cfa_remember;
+
+/* True if any CFI directives were emitted at the current insn. */
+static bool any_cfis_emitted;
+
+
+static void dwarf2out_cfi_begin_epilogue (rtx insn);
+static void dwarf2out_frame_debug_restore_state (void);
+
/* Hook used by __throw. */
@@ -292,18 +305,13 @@ dwarf2out_cfi_label (bool force)
{
int num = dwarf2out_cfi_label_num++;
ASM_GENERATE_INTERNAL_LABEL (label, "LCFI", num);
- ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LCFI", num);
+ cfi_insn = emit_note_after (NOTE_INSN_CFI_LABEL, cfi_insn);
+ NOTE_LABEL_NUMBER (cfi_insn) = num;
}
return label;
}
-/* True if remember_state should be emitted before following CFI directive. */
-static bool emit_cfa_remember;
-
-/* True if any CFI directives were emitted at the current insn. */
-static bool any_cfis_emitted;
-
/* Add CFI to the current fde at the PC value indicated by LABEL if specified,
or to the CIE if LABEL is NULL. */
@@ -383,7 +391,8 @@ add_fde_cfi (const char *label, dw_cfi_ref cfi)
}
}
- output_cfi_directive (cfi);
+ cfi_insn = emit_note_after (NOTE_INSN_CFI, cfi_insn);
+ NOTE_CFI (cfi_insn) = cfi;
vec = &fde->dw_fde_cfi;
any_cfis_emitted = true;
@@ -2301,6 +2310,9 @@ dwarf2out_frame_debug (rtx insn, bool after_p)
bool handled_one = false;
bool need_flush = false;
+ /* Remember where we are to insert notes. */
+ cfi_insn = (after_p ? insn : PREV_INSN (insn));
+
if (!NONJUMP_INSN_P (insn) || clobbers_queued_reg_save (insn))
dwarf2out_flush_queued_reg_saves ();
@@ -2440,8 +2452,16 @@ dwarf2out_frame_debug (rtx insn, bool after_p)
void
dwarf2out_frame_debug_init (void)
{
- /* Flush any queued register saves. */
- dwarf2out_flush_queued_reg_saves ();
+ rtx insn;
+
+ regs_saved_in_regs = NULL;
+ queued_reg_saves = NULL;
+
+ if (barrier_args_size)
+ {
+ XDELETEVEC (barrier_args_size);
+ barrier_args_size = NULL;
+ }
/* Set up state for generating call frame debug info. */
lookup_cfa (&cfa);
@@ -2453,12 +2473,55 @@ dwarf2out_frame_debug_init (void)
cfa_temp.reg = -1;
cfa_temp.offset = 0;
- regs_saved_in_regs = NULL;
-
- if (barrier_args_size)
+ for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
{
- XDELETEVEC (barrier_args_size);
- barrier_args_size = NULL;
+ rtx pat;
+
+ if (BARRIER_P (insn))
+ {
+ dwarf2out_frame_debug (insn, false);
+ continue;
+ }
+
+ if (NOTE_P (insn))
+ {
+ switch (NOTE_KIND (insn))
+ {
+ case NOTE_INSN_EPILOGUE_BEG:
+#if defined(HAVE_epilogue)
+ dwarf2out_cfi_begin_epilogue (insn);
+#endif
+ break;
+ case NOTE_INSN_CFA_RESTORE_STATE:
+ cfi_insn = insn;
+ dwarf2out_frame_debug_restore_state ();
+ break;
+ }
+ continue;
+ }
+
+ if (!NONDEBUG_INSN_P (insn))
+ continue;
+
+ pat = PATTERN (insn);
+ if (asm_noperands (pat) >= 0)
+ {
+ dwarf2out_frame_debug (insn, false);
+ continue;
+ }
+
+ if (GET_CODE (pat) == SEQUENCE)
+ {
+ int i, n = XVECLEN (pat, 0);
+ for (i = 1; i < n; ++i)
+ dwarf2out_frame_debug (XVECEXP (pat, 0, i), false);
+ }
+
+ if (CALL_P (insn)
+ || find_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL))
+ dwarf2out_frame_debug (insn, false);
+
+ dwarf2out_frame_debug (insn, true);
}
}
@@ -2467,7 +2530,7 @@ dwarf2out_frame_debug_init (void)
we do need to save/restore, then emit the save now, and insert a
NOTE_INSN_CFA_RESTORE_STATE at the appropriate place in the stream. */
-void
+static void
dwarf2out_cfi_begin_epilogue (rtx insn)
{
bool saw_frp = false;
@@ -2544,7 +2607,7 @@ dwarf2out_cfi_begin_epilogue (rtx insn)
/* A "subroutine" of dwarf2out_cfi_begin_epilogue. Emit the restore
required. */
-void
+static void
dwarf2out_frame_debug_restore_state (void)
{
dw_cfi_ref cfi = new_cfi ();