Commit 204d2c03 by Wilco Dijkstra Committed by Wilco Dijkstra

Introduce emit_frame_chain

The current frame code combines the separate concepts of a frame chain
(saving old FP,LR in a record and pointing new FP to it) and a frame
pointer used to access locals.  Add emit_frame_chain to the aarch64_frame
descriptor and use it in the prolog and epilog code.  For now just
initialize it as before, so generated code is identical.

Also correctly set EXIT_IGNORE_STACK.  The current AArch64 epilog code 
restores SP from FP if alloca is used.  If a frame pointer is used but
there is no alloca, SP must remain valid for the epilog to work correctly.

    gcc/
	* config/aarch64/aarch64.h (EXIT_IGNORE_STACK): Set if alloca is used.
	(aarch64_frame): Add emit_frame_chain boolean.
	* config/aarch64/aarch64.c (aarch64_frame_pointer_required)
	Move eh_return case to aarch64_layout_frame.
	(aarch64_layout_frame): Initialize emit_frame_chain.
	(aarch64_expand_prologue): Use emit_frame_chain.

From-SVN: r254114
parent 957f5fea
2017-10-26 Wilco Dijkstra <wdijkstr@arm.com>
* config/aarch64/aarch64.h (EXIT_IGNORE_STACK): Set if alloca is used.
(aarch64_frame): Add emit_frame_chain boolean.
* config/aarch64/aarch64.c (aarch64_frame_pointer_required)
Move eh_return case to aarch64_layout_frame.
(aarch64_layout_frame): Initialize emit_frame_chain.
(aarch64_expand_prologue): Use emit_frame_chain.
2017-10-26 Wilco Dijkstra <wdijkstr@arm.com>
* config/aarch64/aarch64.c (aarch64_layout_frame):
Ensure LR is always stored at the bottom of the callee-saves.
Remove rarely used frame layout which saves callee-saves at top of
......@@ -2876,10 +2876,6 @@ aarch64_frame_pointer_required (void)
&& !df_regs_ever_live_p (LR_REGNUM)))
return true;
/* Force a frame pointer for EH returns so the return address is at FP+8. */
if (crtl->calls_eh_return)
return true;
return false;
}
......@@ -2896,6 +2892,10 @@ aarch64_layout_frame (void)
if (reload_completed && cfun->machine->frame.laid_out)
return;
/* Force a frame chain for EH returns so the return address is at FP+8. */
cfun->machine->frame.emit_frame_chain
= frame_pointer_needed || crtl->calls_eh_return;
#define SLOT_NOT_REQUIRED (-2)
#define SLOT_REQUIRED (-1)
......@@ -2930,7 +2930,7 @@ aarch64_layout_frame (void)
last_fp_reg = regno;
}
if (frame_pointer_needed)
if (cfun->machine->frame.emit_frame_chain)
{
/* FP and LR are placed in the linkage record. */
cfun->machine->frame.reg_offset[R29_REGNUM] = 0;
......@@ -3659,6 +3659,7 @@ aarch64_expand_prologue (void)
HOST_WIDE_INT callee_offset = cfun->machine->frame.callee_offset;
unsigned reg1 = cfun->machine->frame.wb_candidate1;
unsigned reg2 = cfun->machine->frame.wb_candidate2;
bool emit_frame_chain = cfun->machine->frame.emit_frame_chain;
rtx_insn *insn;
/* Sign return address for functions. */
......@@ -3691,7 +3692,7 @@ aarch64_expand_prologue (void)
if (callee_adjust != 0)
aarch64_push_regs (reg1, reg2, callee_adjust);
if (frame_pointer_needed)
if (emit_frame_chain)
{
if (callee_adjust == 0)
aarch64_save_callee_saves (DImode, callee_offset, R29_REGNUM,
......@@ -3699,14 +3700,14 @@ aarch64_expand_prologue (void)
insn = emit_insn (gen_add3_insn (hard_frame_pointer_rtx,
stack_pointer_rtx,
GEN_INT (callee_offset)));
RTX_FRAME_RELATED_P (insn) = 1;
RTX_FRAME_RELATED_P (insn) = frame_pointer_needed;
emit_insn (gen_stack_tie (stack_pointer_rtx, hard_frame_pointer_rtx));
}
aarch64_save_callee_saves (DImode, callee_offset, R0_REGNUM, R30_REGNUM,
callee_adjust != 0 || frame_pointer_needed);
callee_adjust != 0 || emit_frame_chain);
aarch64_save_callee_saves (DFmode, callee_offset, V0_REGNUM, V31_REGNUM,
callee_adjust != 0 || frame_pointer_needed);
callee_adjust != 0 || emit_frame_chain);
aarch64_sub_sp (IP1_REGNUM, final_adjust, !frame_pointer_needed);
}
......
......@@ -343,9 +343,9 @@ extern unsigned aarch64_architecture_version;
(epilogue_completed && (REGNO) == LR_REGNUM)
/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
the stack pointer does not matter. The value is tested only in
functions that have frame pointers. */
#define EXIT_IGNORE_STACK 1
the stack pointer does not matter. This is only true if the function
uses alloca. */
#define EXIT_IGNORE_STACK (cfun->calls_alloca)
#define STATIC_CHAIN_REGNUM R18_REGNUM
#define HARD_FRAME_POINTER_REGNUM R29_REGNUM
......@@ -595,6 +595,9 @@ struct GTY (()) aarch64_frame
/* The size of the stack adjustment after saving callee-saves. */
HOST_WIDE_INT final_adjust;
/* Store FP,LR and setup a frame pointer. */
bool emit_frame_chain;
unsigned wb_candidate1;
unsigned wb_candidate2;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment