This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix PR rtl-optimization/88390
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 08 Dec 2018 12:08:03 +0100
- Subject: Fix PR rtl-optimization/88390
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
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