dwarf2cfi: Populate CUR_ROW->REG_SAVE.
authorRichard Henderson <rth@redhat.com>
Sat, 23 Jul 2011 20:06:42 +0000 (13:06 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Sat, 23 Jul 2011 20:06:42 +0000 (13:06 -0700)
To be actually used by a subsequent patch.

        * dwarf2cfi.c (update_row_reg_save): New.
        (dwarf2out_frame_debug_cfa_expression): Use it.
        (dwarf2out_frame_debug_cfa_restore): Likewise.
        (reg_save): Likewise.  Do not emit DW_CFA_same_value.

From-SVN: r176699

gcc/ChangeLog
gcc/dwarf2cfi.c

index 03ab1d68b268aba1d0c742682abde8b210951bfb..6277b1eee818f668e79c802b25ab7a2849f593b2 100644 (file)
@@ -1,3 +1,10 @@
+2011-07-23  Richard Henderson  <rth@redhat.com>
+
+       * dwarf2cfi.c (update_row_reg_save): New.
+       (dwarf2out_frame_debug_cfa_expression): Use it.
+       (dwarf2out_frame_debug_cfa_restore): Likewise.
+       (reg_save): Likewise.  Do not emit DW_CFA_same_value.
+
 2011-07-23  Richard Henderson  <rth@redhat.com>
 
        * dwarf2cfi.c (add_cfi_insn): Rename from cfi_insn.  Update all users.
index eb59f2864b9c3e3559d94eb1620deaeb409ab825..36fa7f86cf5f57f1f920164fe4775847379626b6 100644 (file)
@@ -285,6 +285,17 @@ add_cfi (dw_cfi_ref cfi)
     VEC_safe_push (dw_cfi_ref, gc, *add_cfi_vec, cfi);
 }
 
+/* Perform ROW->REG_SAVE[COLUMN] = CFI.  CFI may be null, indicating
+   that the register column is no longer saved.  */
+
+static void
+update_row_reg_save (dw_cfi_row_ref row, unsigned column, dw_cfi_ref cfi)
+{
+  if (VEC_length (dw_cfi_ref, row->reg_save) <= column)
+    VEC_safe_grow_cleared (dw_cfi_ref, gc, row->reg_save, column + 1);
+  VEC_replace (dw_cfi_ref, row->reg_save, column, cfi);
+}
+
 /* This function fills in aa dw_cfa_location structure from a dwarf location
    descriptor sequence.  */
 
@@ -574,7 +585,13 @@ reg_save (unsigned int reg, unsigned int sreg, HOST_WIDE_INT offset)
       cfi->dw_cfi_oprnd2.dw_cfi_offset = offset;
     }
   else if (sreg == reg)
-    cfi->dw_cfi_opc = DW_CFA_same_value;
+    {
+      /* While we could emit something like DW_CFA_same_value or
+        DW_CFA_restore, we never expect to see something like that
+        in a prologue.  This is more likely to be a bug.  A backend
+        can always bypass this by using REG_CFA_RESTORE directly.  */
+      gcc_unreachable ();
+    }
   else
     {
       cfi->dw_cfi_opc = DW_CFA_register;
@@ -582,6 +599,7 @@ reg_save (unsigned int reg, unsigned int sreg, HOST_WIDE_INT offset)
     }
 
   add_cfi (cfi);
+  update_row_reg_save (cur_row, reg, cfi);
 }
 
 /* Given a SET, calculate the amount of stack adjustment it
@@ -1337,6 +1355,7 @@ dwarf2out_frame_debug_cfa_expression (rtx set)
 {
   rtx src, dest, span;
   dw_cfi_ref cfi = new_cfi ();
+  unsigned regno;
 
   dest = SET_DEST (set);
   src = SET_SRC (set);
@@ -1347,8 +1366,10 @@ dwarf2out_frame_debug_cfa_expression (rtx set)
   span = targetm.dwarf_register_span (src);
   gcc_assert (!span);
 
+  regno = dwf_regno (src);
+
   cfi->dw_cfi_opc = DW_CFA_expression;
-  cfi->dw_cfi_oprnd1.dw_cfi_reg_num = dwf_regno (src);
+  cfi->dw_cfi_oprnd1.dw_cfi_reg_num = regno;
   cfi->dw_cfi_oprnd2.dw_cfi_loc
     = mem_loc_descriptor (XEXP (dest, 0), get_address_mode (dest),
                          GET_MODE (dest), VAR_INIT_STATUS_INITIALIZED);
@@ -1356,6 +1377,7 @@ dwarf2out_frame_debug_cfa_expression (rtx set)
   /* ??? We'd like to use queue_reg_save, were the interface different,
      and, as above, we could manage flushing for epilogues.  */
   add_cfi (cfi);
+  update_row_reg_save (cur_row, regno, cfi);
 }
 
 /* A subroutine of dwarf2out_frame_debug, process a REG_CFA_RESTORE note.  */
@@ -1370,6 +1392,7 @@ dwarf2out_frame_debug_cfa_restore (rtx reg)
   cfi->dw_cfi_oprnd1.dw_cfi_reg_num = regno;
 
   add_cfi (cfi);
+  update_row_reg_save (cur_row, regno, NULL);
 }
 
 /* A subroutine of dwarf2out_frame_debug, process a REG_CFA_WINDOW_SAVE.