From 204d2c03acff4bf3b73cb5d2c9578b50c2aac703 Mon Sep 17 00:00:00 2001 From: Wilco Dijkstra Date: Thu, 26 Oct 2017 16:51:37 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 9 +++++++++ gcc/config/aarch64/aarch64.c | 19 ++++++++++--------- gcc/config/aarch64/aarch64.h | 9 ++++++--- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f32a30b7730..81e5bba244e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2017-10-26 Wilco Dijkstra + + * 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 * config/aarch64/aarch64.c (aarch64_layout_frame): diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index ed97e2d5de1..1cc10432b76 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -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); } diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index 75fda01a6f4..bc1ccc34281 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -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; -- 2.30.2