Fix PR rtl-optimization/88390

Message ID 2670184.ocz1KtPm3k@polaris
State New
Headers show
Series
  • Fix PR rtl-optimization/88390
Related show

Commit Message

Eric Botcazou Dec. 8, 2018, 11:08 a.m.
This is the failure of g++.dg/tree-prof/pr57451.C on the SPARC, caused by the 
-freorder-blocks-and-partition RTL optimization.  The optimization splits the 
getData function into hold and cold parts, with the cold part throwing an 
exception.  Now the CFI for the cold part is emitted as a second, independent 
FDE, although there is still a single function for the RTL machinery, so there 
is specific code in dwarf2cfi to patch things up.

The problem is that it doesn't take into account the DW_CFA_GNU_window_save 
operation used on the SPARC so the second FDE lacks it entirely.  That's fixed 
by adding a flag to dw_cfi_row to record whether the operation has been seen.

Tested on SPARC/Solaris 11, applied on the mainline.


2018-12-08  Eric Botcazou  <ebotcazou@adacore.com>

	PR rtl-optimization/88390
	* dwarf2cfi.c (struct dw_cfi_row): Add window_save field.
	(cfi_row_equal_p): Compare it.
	(dwarf2out_frame_debug_cfa_window_save): Add FAKE parameter.
	If FAKE is false, set window_save of the current row.
	(dwarf2out_frame_debug) <REG_CFA_TOGGLE_RA_MANGLE>: Call above
	function with FAKE parameter set to true.
	<REG_CFA_WINDOW_SAVE>: Likewise but with FAKE parameter set to false.
	(change_cfi_row): Emit a DW_CFA_GNU_window_save if necessary.

-- 
Eric Botcazou

Patch

Index: dwarf2cfi.c
===================================================================
--- dwarf2cfi.c	(revision 266884)
+++ dwarf2cfi.c	(working copy)
@@ -68,6 +68,9 @@  struct GTY(()) dw_cfi_row
 
   /* The expressions for any register column that is saved.  */
   cfi_vec reg_save;
+
+  /* True if the register window is saved.  */
+  bool window_save;
 };
 
 /* The caller's ORIG_REG is saved in SAVED_IN_REG.  */
@@ -766,6 +769,9 @@  cfi_row_equal_p (dw_cfi_row *a, dw_cfi_r
         return false;
     }
 
+  if (a->window_save != b->window_save)
+    return false;
+
   return true;
 }
 
@@ -1364,16 +1370,20 @@  dwarf2out_frame_debug_cfa_restore (rtx r
 }
 
 /* A subroutine of dwarf2out_frame_debug, process a REG_CFA_WINDOW_SAVE.
-   ??? Perhaps we should note in the CIE where windows are saved (instead of
-   assuming 0(cfa)) and what registers are in the window.  */
+   FAKE is true if this is not really a window save but something else.
+
+   ??? Perhaps we should note in the CIE where windows are saved (instead
+   of assuming 0(cfa)) and what registers are in the window.  */
 
 static void
-dwarf2out_frame_debug_cfa_window_save (void)
+dwarf2out_frame_debug_cfa_window_save (bool fake)
 {
   dw_cfi_ref cfi = new_cfi ();
 
   cfi->dw_cfi_opc = DW_CFA_GNU_window_save;
   add_cfi (cfi);
+  if (!fake)
+    cur_row->window_save = true;
 }
 
 /* Record call frame debugging information for an expression EXPR,
@@ -2133,9 +2143,13 @@  dwarf2out_frame_debug (rtx_insn *insn)
 	break;
 
       case REG_CFA_TOGGLE_RA_MANGLE:
+	/* This uses the same DWARF opcode as the next operation.  */
+	dwarf2out_frame_debug_cfa_window_save (true);
+	handled_one = true;
+	break;
+
       case REG_CFA_WINDOW_SAVE:
-	/* We overload both of these operations onto the same DWARF opcode.  */
-	dwarf2out_frame_debug_cfa_window_save ();
+	dwarf2out_frame_debug_cfa_window_save (false);
 	handled_one = true;
 	break;
 
@@ -2199,6 +2213,14 @@  change_cfi_row (dw_cfi_row *old_row, dw_
       else if (!cfi_equal_p (r_old, r_new))
         add_cfi (r_new);
     }
+
+  if (!old_row->window_save && new_row->window_save)
+    {
+      dw_cfi_ref cfi = new_cfi ();
+
+      cfi->dw_cfi_opc = DW_CFA_GNU_window_save;
+      add_cfi (cfi);
+    }
 }
 
 /* Examine CFI and return true if a cfi label and set_loc is needed