dwarf2out: Add REG_CFA_FLUSH_QUEUE.
authorRichard Henderson <rth@redhat.com>
Thu, 30 Jun 2011 21:04:23 +0000 (14:04 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Thu, 30 Jun 2011 21:04:23 +0000 (14:04 -0700)
        * 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

gcc/ChangeLog
gcc/dwarf2out.c
gcc/final.c
gcc/reg-notes.def

index 2358289f64f0c03fc237ac97a5b571ede3db1cb0..28109773726c69e6f1f4bb7be8083f346ea4984e 100644 (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
index 8e543919ffe5df756e76d1eb7f9c6f28a4f17333..9ab551d8ed23f776dc1774f9c93eedc85e475f63 100644 (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);
 
-  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 at the start of the function.  */
+      if (any_cfis_emitted || clobbers_queued_reg_save (insn))
+       need_flush = true;
+    }
 
-  /* 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 ();
 }
 
index cb4a83d08ee93fb0a3beb4a1b43ea200151c3f58..c0c1fc850ecfa69bc1857b74c65234ab688ea341 100644 (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.  */
index 9924355f7721534b0364391c45f7ddc9673de06d..eccac9e9d7046232e8926d099d147f6fa2a8836d 100644 (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.  */