reg-notes.def (REG_CFA_WINDOW_SAVE): New.

* reg-notes.def (REG_CFA_WINDOW_SAVE): New.
	* dwarf2out.c (dwarf2out_frame_debug): Handle it.
	(dwarf2out_frame_debug_cfa_window_save): Rename from
	dwarf2out_window_save; make static.
	* tree.h (dwarf2out_window_save): Don't declare.

	* config/sparc/sparc.c (sparc_dwarf_handle_frame_unspec): Remove.
	(TARGET_DWARF_HANDLE_FRAME_UNSPEC): Remove.
	(emit_save_register_window): Rename from gen_save_register_window;
	emit the insn and add REG_CFA_* notes.
	(sparc_expand_prologue): Update to match.
	* config/sparc/sparc.md (save_register_window_1): Simplify from
	save_register_window<P:mode>.

From-SVN: r175297
This commit is contained in:
Richard Henderson 2011-06-22 09:26:52 -07:00 committed by Richard Henderson
parent 8288cc7387
commit 78a8eb4edc
6 changed files with 70 additions and 64 deletions

View File

@ -1,3 +1,19 @@
2011-06-22 Richard Henderson <rth@redhat.com>
* reg-notes.def (REG_CFA_WINDOW_SAVE): New.
* dwarf2out.c (dwarf2out_frame_debug): Handle it.
(dwarf2out_frame_debug_cfa_window_save): Rename from
dwarf2out_window_save; make static.
* tree.h (dwarf2out_window_save): Don't declare.
* config/sparc/sparc.c (sparc_dwarf_handle_frame_unspec): Remove.
(TARGET_DWARF_HANDLE_FRAME_UNSPEC): Remove.
(emit_save_register_window): Rename from gen_save_register_window;
emit the insn and add REG_CFA_* notes.
(sparc_expand_prologue): Update to match.
* config/sparc/sparc.md (save_register_window_1): Simplify from
save_register_window<P:mode>.
2011-06-22 H.J. Lu <hongjiu.lu@intel.com>
PR target/49497

View File

@ -460,7 +460,6 @@ static unsigned int sparc_function_arg_boundary (enum machine_mode,
const_tree);
static int sparc_arg_partial_bytes (cumulative_args_t,
enum machine_mode, tree, bool);
static void sparc_dwarf_handle_frame_unspec (const char *, rtx, int);
static void sparc_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
static void sparc_file_end (void);
static bool sparc_frame_pointer_required (void);
@ -611,9 +610,6 @@ char sparc_hard_reg_printed[8];
#undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
#define TARGET_VECTORIZE_PREFERRED_SIMD_MODE sparc_preferred_simd_mode
#undef TARGET_DWARF_HANDLE_FRAME_UNSPEC
#define TARGET_DWARF_HANDLE_FRAME_UNSPEC sparc_dwarf_handle_frame_unspec
#ifdef SUBTARGET_INSERT_ATTRIBUTES
#undef TARGET_INSERT_ATTRIBUTES
#define TARGET_INSERT_ATTRIBUTES SUBTARGET_INSERT_ATTRIBUTES
@ -4597,12 +4593,28 @@ emit_save_or_restore_local_in_regs (rtx base, int offset, sorr_act_t action)
/* Generate a save_register_window insn. */
static rtx
gen_save_register_window (rtx increment)
emit_save_register_window (rtx increment)
{
if (TARGET_ARCH64)
return gen_save_register_windowdi (increment);
else
return gen_save_register_windowsi (increment);
rtx insn;
insn = emit_insn (gen_save_register_window_1 (increment));
RTX_FRAME_RELATED_P (insn) = 1;
/* The return address (%i7) is saved in %o7. */
add_reg_note (insn, REG_CFA_REGISTER,
gen_rtx_SET (VOIDmode,
gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM),
gen_rtx_REG (Pmode, INCOMING_RETURN_ADDR_REGNUM)));
/* The window save event. */
add_reg_note (insn, REG_CFA_WINDOW_SAVE, const0_rtx);
/* The CFA is %fp, the hard frame pointer. */
add_reg_note (insn, REG_CFA_DEF_CFA,
plus_constant (hard_frame_pointer_rtx,
INCOMING_FRAME_SP_OFFSET));
return insn;
}
/* Generate a create_flat_frame_1 insn. */
@ -4671,7 +4683,6 @@ sparc_expand_prologue (void)
{
HOST_WIDE_INT size;
rtx insn;
int i;
/* Compute a snapshot of current_function_uses_only_leaf_regs. Relying
on the final value of the flag means deferring the prologue/epilogue
@ -4733,10 +4744,10 @@ sparc_expand_prologue (void)
else
{
if (size <= 4096)
insn = emit_insn (gen_save_register_window (GEN_INT (-size)));
emit_save_register_window (GEN_INT (-size));
else if (size <= 8192)
{
insn = emit_insn (gen_save_register_window (GEN_INT (-4096)));
emit_save_register_window (GEN_INT (-4096));
/* %sp is not the CFA register anymore. */
emit_insn (gen_stack_pointer_inc (GEN_INT (4096 - size)));
}
@ -4744,12 +4755,8 @@ sparc_expand_prologue (void)
{
rtx reg = gen_rtx_REG (Pmode, 1);
emit_move_insn (reg, GEN_INT (-size));
insn = emit_insn (gen_save_register_window (reg));
emit_save_register_window (reg);
}
RTX_FRAME_RELATED_P (insn) = 1;
for (i=0; i < XVECLEN (PATTERN (insn), 0); i++)
RTX_FRAME_RELATED_P (XVECEXP (PATTERN (insn), 0, i)) = 1;
}
if (sparc_leaf_function_p)
@ -10000,20 +10007,6 @@ get_some_local_dynamic_name_1 (rtx *px, void *data ATTRIBUTE_UNUSED)
return 0;
}
/* Handle the TARGET_DWARF_HANDLE_FRAME_UNSPEC hook.
This is called from dwarf2out.c to emit call frame instructions
for frame-related insns containing UNSPECs and UNSPEC_VOLATILEs. */
static void
sparc_dwarf_handle_frame_unspec (const char *label,
rtx pattern ATTRIBUTE_UNUSED,
int index ATTRIBUTE_UNUSED)
{
gcc_assert (index == UNSPECV_SAVEW);
dwarf2out_window_save (label);
}
/* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
We need to emit DTP-relative relocations. */

View File

@ -6276,24 +6276,18 @@
DONE;
})
;; The "save register window" insn is modelled as follows so that the DWARF-2
;; backend automatically emits the required call frame debugging information
;; while it is parsing it. Therefore, the pattern should not be modified
;; without first studying the impact of the changes on the debug info.
;; [(set (%fp) (%sp))
;; (set (%sp) (unspec_volatile [(%sp) (-frame_size)] UNSPECV_SAVEW))
;; (set (%i7) (%o7))]
;; The "save register window" insn is modelled as follows. The dwarf2
;; information is manually added in emit_save_register_window in sparc.c.
(define_insn "save_register_window<P:mode>"
[(set (reg:P 30) (reg:P 14))
(set (reg:P 14) (unspec_volatile:P [(reg:P 14)
(match_operand:P 0 "arith_operand" "rI")] UNSPECV_SAVEW))
(set (reg:P 31) (reg:P 15))]
(define_insn "save_register_window_1"
[(unspec_volatile
[(match_operand 0 "arith_operand" "rI")]
UNSPECV_SAVEW)]
"!TARGET_FLAT"
"save\t%%sp, %0, %%sp"
[(set_attr "type" "savew")])
;; Likewise for the "create flat frame" insns. We need to use special insns
;; For the "create flat frame" insns, we need to use special insns
;; because %fp cannot be clobbered until after the frame is established (so
;; that it contains the live register window save area) and %i7 changed with
;; a simple move as it is a fixed register and the move would be eliminated.

View File

@ -1232,22 +1232,6 @@ reg_save (const char *label, unsigned int reg, unsigned int sreg, HOST_WIDE_INT
add_fde_cfi (label, cfi);
}
/* Add the CFI for saving a register window. LABEL is passed to reg_save.
This CFI tells the unwinder that it needs to restore the window registers
from the previous frame's window save area.
??? Perhaps we should note in the CIE where windows are saved (instead of
assuming 0(cfa)) and what registers are in the window. */
void
dwarf2out_window_save (const char *label)
{
dw_cfi_ref cfi = new_cfi ();
cfi->dw_cfi_opc = DW_CFA_GNU_window_save;
add_fde_cfi (label, cfi);
}
/* Entry point for saving a register to the stack. REG is the GCC register
number. LABEL and OFFSET are passed to reg_save. */
@ -2104,6 +2088,19 @@ dwarf2out_frame_debug_cfa_restore (rtx reg, const char *label)
add_fde_cfi (label, cfi);
}
/* 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. */
static void
dwarf2out_frame_debug_cfa_window_save (const char *label)
{
dw_cfi_ref cfi = new_cfi ();
cfi->dw_cfi_opc = DW_CFA_GNU_window_save;
add_fde_cfi (label, cfi);
}
/* Record call frame debugging information for an expression EXPR,
which either sets SP or FP (adjusting how we calculate the frame
address) or saves a register to the stack or another register.
@ -2900,6 +2897,11 @@ dwarf2out_frame_debug (rtx insn, bool after_p)
handled_one = true;
break;
case REG_CFA_WINDOW_SAVE:
dwarf2out_frame_debug_cfa_window_save (label);
handled_one = true;
break;
default:
break;
}

View File

@ -160,6 +160,11 @@ REG_NOTE (CFA_RESTORE)
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
save operation, i.e. will result in a DW_CFA_GNU_window_save.
The argument is ignored. */
REG_NOTE (CFA_WINDOW_SAVE)
/* 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. */

View File

@ -5607,10 +5607,6 @@ extern char *dwarf2out_cfi_label (bool);
extern void dwarf2out_def_cfa (const char *, unsigned, HOST_WIDE_INT);
/* Add the CFI for saving a register window. */
extern void dwarf2out_window_save (const char *);
/* Entry point for saving a register to the stack. */
extern void dwarf2out_reg_save (const char *, unsigned, HOST_WIDE_INT);