public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH][AArch64] Introduce emit_frame_chain
@ 2017-08-04 12:26 Wilco Dijkstra
  2017-08-15 16:27 ` Wilco Dijkstra
  2017-10-26 16:23 ` James Greenhalgh
  0 siblings, 2 replies; 3+ messages in thread
From: Wilco Dijkstra @ 2017-08-04 12:26 UTC (permalink / raw)
  To: GCC Patches, James Greenhalgh; +Cc: nd

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.

ChangeLog:
2017-08-03  Wilco Dijkstra  <wdijkstr@arm.com>

    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.

--
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 82d270e575ca40e9786de6a4e27408a32bc09be7..ee23944b191dd17339f42ce8ea7ff9733357c3d8 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -346,9 +346,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
@@ -604,6 +604,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;
 
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index e5c6c1ca65269a209e893729ce3230f70bd4e808..0c355506e2a1605d24d1e89934a063e5f333eebf 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -2847,10 +2847,6 @@ aarch64_frame_pointer_required (void)
       && (!crtl->is_leaf || 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;
 }
 
@@ -2866,6 +2862,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)
 
@@ -2900,7 +2900,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;
@@ -3639,6 +3639,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.  */
@@ -3669,7 +3670,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,
@@ -3677,12 +3678,12 @@ 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);
   aarch64_sub_sp (IP1_REGNUM, final_adjust, !frame_pointer_needed);

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH][AArch64] Introduce emit_frame_chain
  2017-08-04 12:26 [PATCH][AArch64] Introduce emit_frame_chain Wilco Dijkstra
@ 2017-08-15 16:27 ` Wilco Dijkstra
  2017-10-26 16:23 ` James Greenhalgh
  1 sibling, 0 replies; 3+ messages in thread
From: Wilco Dijkstra @ 2017-08-15 16:27 UTC (permalink / raw)
  To: GCC Patches, James Greenhalgh; +Cc: nd


ping



From: Wilco Dijkstra
Sent: 04 August 2017 13:26
To: GCC Patches; James Greenhalgh
Cc: nd
Subject: [PATCH][AArch64] 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.

ChangeLog:
2017-08-03  Wilco Dijkstra  <wdijkstr@arm.com>

    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.

--
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 82d270e575ca40e9786de6a4e27408a32bc09be7..ee23944b191dd17339f42ce8ea7ff9733357c3d8 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -346,9 +346,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
@@ -604,6 +604,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;
 
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index e5c6c1ca65269a209e893729ce3230f70bd4e808..0c355506e2a1605d24d1e89934a063e5f333eebf 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -2847,10 +2847,6 @@ aarch64_frame_pointer_required (void)
       && (!crtl->is_leaf || 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;
 }
 
@@ -2866,6 +2862,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)
 
@@ -2900,7 +2900,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;
@@ -3639,6 +3639,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.  */
@@ -3669,7 +3670,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,
@@ -3677,12 +3678,12 @@ 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);
   aarch64_sub_sp (IP1_REGNUM, final_adjust, !frame_pointer_needed);
    

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH][AArch64] Introduce emit_frame_chain
  2017-08-04 12:26 [PATCH][AArch64] Introduce emit_frame_chain Wilco Dijkstra
  2017-08-15 16:27 ` Wilco Dijkstra
@ 2017-10-26 16:23 ` James Greenhalgh
  1 sibling, 0 replies; 3+ messages in thread
From: James Greenhalgh @ 2017-10-26 16:23 UTC (permalink / raw)
  To: Wilco Dijkstra; +Cc: GCC Patches, nd

On Fri, Aug 04, 2017 at 01:26:15PM +0100, Wilco Dijkstra wrote:
> 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.

OK.

Reviewed by: James Greenhalgh <james.greenhalgh@arm.com>

Thanks,
James

> 
> ChangeLog:
> 2017-08-03  Wilco Dijkstra  <wdijkstr@arm.com>
> 
>     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.
> 

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2017-10-26 15:59 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-04 12:26 [PATCH][AArch64] Introduce emit_frame_chain Wilco Dijkstra
2017-08-15 16:27 ` Wilco Dijkstra
2017-10-26 16:23 ` James Greenhalgh

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).