dwarf2out: Move insn scanning out of final.c.
authorBernd Schmidt <bernds@codesourcery.com>
Thu, 7 Jul 2011 23:42:41 +0000 (23:42 +0000)
committerRichard Henderson <rth@gcc.gnu.org>
Thu, 7 Jul 2011 23:42:41 +0000 (16:42 -0700)
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

gcc/ChangeLog
gcc/dwarf2cfi.c
gcc/dwarf2out.c
gcc/dwarf2out.h
gcc/final.c
gcc/insn-notes.def
gcc/rtl.h

index 45836c2271e5b45f5caff292c54122c810583194..104c4ac83fd0b5c08e71fa5930b3308dd091a406 100644 (file)
@@ -1,3 +1,25 @@
+2011-07-07  Bernd Schmidt  <bernds@codesourcery.com>
+           Richard Henderson  <rth@redhat.com>
+
+       * 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.
+
 2011-07-07  Richard Henderson  <rth@redhat.com>
 
        * dwarf2cfi.c: New file.
index 8de13e52c0ca95dde3cf62ea5f29c7823276276d..3e8958fd39241ac985e39166a4b7abfd45bf2952 100644 (file)
@@ -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;
+\f
+
+static void dwarf2out_cfi_begin_epilogue (rtx insn);
+static void dwarf2out_frame_debug_restore_state (void);
+
 \f
 /* 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 ();
index 0f6918d0e9f542e39c88c2f80e1818ef009242c0..78e1b1a63c312241dcec61b8945b5589088a6c47 100644 (file)
@@ -843,7 +843,7 @@ output_cfi (dw_cfi_ref cfi, dw_fde_ref fde, int for_eh)
 
 /* Similar, but do it via assembler directives instead.  */
 
-void
+static void
 output_cfi_directive (dw_cfi_ref cfi)
 {
   unsigned long r, r2;
@@ -942,6 +942,12 @@ output_cfi_directive (dw_cfi_ref cfi)
     }
 }
 
+void
+dwarf2out_emit_cfi (dw_cfi_ref cfi)
+{
+  output_cfi_directive (cfi);
+}
+
 /* Output CFIs from VEC, up to index UPTO, to bring current FDE to the
    same state as after executing CFIs in CFI chain.  DO_CFI_ASM is
    true if .cfi_* directives shall be emitted, false otherwise.  If it
index 40cd848c5afcc5f82f63860ea87168f324ad78f3..9342d50d37c9bb5da1a008739902df50232596ec 100644 (file)
@@ -216,7 +216,6 @@ dw_loc_descr_node;
 
 /* Interface from dwarf2out.c to dwarf2cfi.c.  */
 extern dw_fde_ref current_fde (void);
-extern void output_cfi_directive (dw_cfi_ref);
 extern struct dw_loc_descr_struct *build_cfa_loc
   (dw_cfa_location *, HOST_WIDE_INT);
 extern struct dw_loc_descr_struct *build_cfa_aligned_loc
@@ -244,8 +243,7 @@ extern enum dw_cfi_oprnd_type dw_cfi_oprnd2_desc
 extern void dwarf2out_decl (tree);
 extern void dwarf2out_frame_debug (rtx, bool);
 extern void dwarf2out_frame_debug_init (void);
-extern void dwarf2out_cfi_begin_epilogue (rtx);
-extern void dwarf2out_frame_debug_restore_state (void);
+extern void dwarf2out_emit_cfi (dw_cfi_ref cfi);
 
 extern void debug_dwarf (void);
 struct die_struct;
index c0c1fc850ecfa69bc1857b74c65234ab688ea341..835bbd502bf0ecf644950e65d95d5467cd66a75f 100644 (file)
@@ -1727,7 +1727,7 @@ dump_basic_block_info (FILE *file, rtx insn, basic_block *start_to_bb,
 void
 final (rtx first, FILE *file, int optimize_p)
 {
-  rtx insn;
+  rtx insn, next;
   int max_uid = 0;
   int seen = 0;
 
@@ -1801,6 +1801,16 @@ final (rtx first, FILE *file, int optimize_p)
       free (start_to_bb);
       free (end_to_bb);
     }
+
+  /* Remove CFI notes, to avoid compare-debug failures.  */
+  for (insn = first; insn; insn = next)
+    {
+      next = NEXT_INSN (insn);
+      if (NOTE_P (insn)
+         && (NOTE_KIND (insn) == NOTE_INSN_CFI
+             || NOTE_KIND (insn) == NOTE_INSN_CFI_LABEL))
+       delete_insn (insn);
+    }
 }
 \f
 const char *
@@ -1973,16 +1983,20 @@ final_scan_insn (rtx insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
          break;
 
        case NOTE_INSN_EPILOGUE_BEG:
-#if defined (HAVE_epilogue)
-         if (dwarf2out_do_frame ())
-           dwarf2out_cfi_begin_epilogue (insn);
-#endif
          (*debug_hooks->begin_epilogue) (last_linenum, last_filename);
          targetm.asm_out.function_begin_epilogue (file);
          break;
 
        case NOTE_INSN_CFA_RESTORE_STATE:
-         dwarf2out_frame_debug_restore_state ();
+         break;
+
+       case NOTE_INSN_CFI:
+         dwarf2out_emit_cfi (NOTE_CFI (insn));
+         break;
+
+       case NOTE_INSN_CFI_LABEL:
+         ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LCFI",
+                                 NOTE_LABEL_NUMBER (insn));
          break;
 
        case NOTE_INSN_FUNCTION_BEG:
@@ -2092,8 +2106,6 @@ final_scan_insn (rtx insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
       break;
 
     case BARRIER:
-      if (dwarf2out_do_frame ())
-       dwarf2out_frame_debug (insn, false);
       break;
 
     case CODE_LABEL:
@@ -2314,11 +2326,6 @@ final_scan_insn (rtx insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
            location_t loc;
            expanded_location expanded;
 
-           /* Make sure we flush any queued register saves in case this
-              clobbers affected registers.  */
-           if (dwarf2out_do_frame ())
-             dwarf2out_frame_debug (insn, false);
-
            /* There's no telling what that did to the condition codes.  */
            CC_STATUS_INIT;
 
@@ -2364,12 +2371,6 @@ final_scan_insn (rtx insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
 
            final_sequence = body;
 
-           /* Record the delay slots' frame information before the branch.
-              This is needed for delayed calls: see execute_cfa_program().  */
-           if (dwarf2out_do_frame ())
-             for (i = 1; i < XVECLEN (body, 0); i++)
-               dwarf2out_frame_debug (XVECEXP (body, 0, i), false);
-
            /* The first insn in this SEQUENCE might be a JUMP_INSN that will
               force the restoration of a comparison that was previously
               thought unnecessary.  If that happens, cancel this sequence
@@ -2683,11 +2684,6 @@ final_scan_insn (rtx insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
 
        current_output_insn = debug_insn = insn;
 
-       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.  */
        templ = get_insn_template (insn_code_number, insn);
 
@@ -2767,16 +2763,6 @@ final_scan_insn (rtx insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
          targetm.asm_out.final_postscan_insn (file, insn, recog_data.operand,
                                               recog_data.n_operands);
 
-       /* If necessary, report the effect that the instruction has on
-          the unwind info.   We've already done this for delay slots
-          and call instructions.  */
-       if (final_sequence == 0
-#if !defined (HAVE_prologue)
-           && !ACCUMULATE_OUTGOING_ARGS
-#endif
-           && dwarf2out_do_frame ())
-         dwarf2out_frame_debug (insn, true);
-
        if (!targetm.asm_out.unwind_emit_before_insn
            && targetm.asm_out.unwind_emit)
          targetm.asm_out.unwind_emit (asm_out_file, insn);
index 6cdbabde09d6e1a0d1dd20dfb89348e07ae4a0b8..859cdacab590c00512f06dc54268afdf0a18149f 100644 (file)
@@ -77,4 +77,12 @@ INSN_NOTE (SWITCH_TEXT_SECTIONS)
    when an epilogue appears in the middle of a function.  */
 INSN_NOTE (CFA_RESTORE_STATE)
 
+/* When emitting dwarf2 frame information, contains a directive that
+   should be emitted.  */
+INSN_NOTE (CFI)
+
+/* When emitting dwarf2 frame information, contains the number of a debug
+   label that should be emitted.  */
+INSN_NOTE (CFI_LABEL)
+
 #undef INSN_NOTE
index 5e009c0b871ce421838217347e22004f02de7a14..e3ceecddc2fae746ea45d19f83327d954ff89060 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -180,6 +180,7 @@ union rtunion_def
   mem_attrs *rt_mem;
   reg_attrs *rt_reg;
   struct constant_descriptor_rtx *rt_constant;
+  struct dw_cfi_struct *rt_cfi;
 };
 typedef union rtunion_def rtunion;
 
@@ -708,6 +709,7 @@ extern void rtl_check_failed_flag (const char *, const_rtx, const char *,
 #define XTREE(RTX, N)   (RTL_CHECK1 (RTX, N, 't').rt_tree)
 #define XBBDEF(RTX, N) (RTL_CHECK1 (RTX, N, 'B').rt_bb)
 #define XTMPL(RTX, N)  (RTL_CHECK1 (RTX, N, 'T').rt_str)
+#define XCFI(RTX, N)   (RTL_CHECK1 (RTX, N, 'C').rt_cfi)
 
 #define XVECEXP(RTX, N, M)     RTVEC_ELT (XVEC (RTX, N), M)
 #define XVECLEN(RTX, N)                GET_NUM_ELEM (XVEC (RTX, N))
@@ -740,6 +742,7 @@ extern void rtl_check_failed_flag (const char *, const_rtx, const char *,
 #define XCMODE(RTX, N, C)     (RTL_CHECKC1 (RTX, N, C).rt_type)
 #define XCTREE(RTX, N, C)     (RTL_CHECKC1 (RTX, N, C).rt_tree)
 #define XCBBDEF(RTX, N, C)    (RTL_CHECKC1 (RTX, N, C).rt_bb)
+#define XCCFI(RTX, N, C)      (RTL_CHECKC1 (RTX, N, C).rt_cfi)
 #define XCCSELIB(RTX, N, C)   (RTL_CHECKC1 (RTX, N, C).rt_cselib)
 
 #define XCVECEXP(RTX, N, M, C) RTVEC_ELT (XCVEC (RTX, N, C), M)
@@ -883,6 +886,8 @@ extern const char * const reg_note_name[];
 #define NOTE_EH_HANDLER(INSN)  XCINT (INSN, 4, NOTE)
 #define NOTE_BASIC_BLOCK(INSN) XCBBDEF (INSN, 4, NOTE)
 #define NOTE_VAR_LOCATION(INSN)        XCEXP (INSN, 4, NOTE)
+#define NOTE_CFI(INSN)         XCCFI (INSN, 4, NOTE)
+#define NOTE_LABEL_NUMBER(INSN)        XCINT (INSN, 4, NOTE)
 
 /* In a NOTE that is a line number, this is the line number.
    Other kinds of NOTEs are identified by negative numbers here.  */