OSDN Git Service

* gcc-interface/trans.c (can_equal_min_or_max_val_p): Be prepared for
[pf3gnuchains/gcc-fork.git] / gcc / dwarf2cfi.c
index 69e6f21..2e74955 100644 (file)
@@ -1930,9 +1930,6 @@ dwarf2out_frame_debug (rtx insn)
 {
   rtx note, n;
   bool handled_one = false;
-  bool need_flush = false;
-
-  any_cfis_emitted = false;
 
   for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
     switch (REG_NOTE_KIND (note))
@@ -2020,8 +2017,7 @@ dwarf2out_frame_debug (rtx insn)
        break;
 
       case REG_CFA_FLUSH_QUEUE:
-       /* The actual flush happens below.  */
-       need_flush = true;
+       /* The actual flush happens elsewhere.  */
        handled_one = true;
        break;
 
@@ -2029,13 +2025,7 @@ dwarf2out_frame_debug (rtx insn)
        break;
       }
 
-  if (handled_one)
-    {
-      /* Minimize the number of advances by emitting the entire queue
-        once anything is emitted.  */
-      need_flush |= any_cfis_emitted;
-    }
-  else
+  if (!handled_one)
     {
       insn = PATTERN (insn);
     do_frame_expr:
@@ -2044,12 +2034,9 @@ dwarf2out_frame_debug (rtx insn)
       /* 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;
+      if (clobbers_queued_reg_save (insn))
+       dwarf2out_flush_queued_reg_saves ();
     }
-
-  if (need_flush)
-    dwarf2out_flush_queued_reg_saves ();
 }
 
 /* Emit CFI info to change the state from OLD_ROW to NEW_ROW.  */
@@ -2452,10 +2439,12 @@ scan_trace (dw_trace_info *trace)
              if (INSN_FROM_TARGET_P (elt))
                {
                  HOST_WIDE_INT restore_args_size;
+                 cfi_vec save_row_reg_save;
 
                  add_cfi_insn = NULL;
                  restore_args_size = cur_trace->end_true_args_size;
                  cur_cfa = &cur_row->cfa;
+                 save_row_reg_save = VEC_copy (dw_cfi_ref, gc, cur_row->reg_save);
 
                  scan_insn_after (elt);
 
@@ -2466,6 +2455,7 @@ scan_trace (dw_trace_info *trace)
 
                  cur_trace->end_true_args_size = restore_args_size;
                  cur_row->cfa = this_cfa;
+                 cur_row->reg_save = save_row_reg_save;
                  cur_cfa = &this_cfa;
                  continue;
                }
@@ -2489,6 +2479,7 @@ scan_trace (dw_trace_info *trace)
 
          /* Make sure any register saves are visible at the jump target.  */
          dwarf2out_flush_queued_reg_saves ();
+         any_cfis_emitted = false;
 
           /* However, if there is some adjustment on the call itself, e.g.
             a call_pop, that action should be considered to happen after
@@ -2508,6 +2499,7 @@ scan_trace (dw_trace_info *trace)
                   || clobbers_queued_reg_save (insn)
                   || find_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL))
            dwarf2out_flush_queued_reg_saves ();
+         any_cfis_emitted = false;
 
          add_cfi_insn = insn;
          scan_insn_after (insn);
@@ -2518,6 +2510,12 @@ scan_trace (dw_trace_info *trace)
         emitted two cfa adjustments.  Do it now.  */
       def_cfa_1 (&this_cfa);
 
+      /* Minimize the number of advances by emitting the entire queue
+        once anything is emitted.  */
+      if (any_cfis_emitted
+         || find_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL))
+       dwarf2out_flush_queued_reg_saves ();
+
       /* Note that a test for control_flow_insn_p does exactly the
         same tests as are done to actually create the edges.  So
         always call the routine and let it not create edges for