diff mbox series

[ARC] Restore blink first when optimizing for speed.

Message ID 20190325105649.9142-1-claziss@gmail.com
State New
Headers show
Series [ARC] Restore blink first when optimizing for speed. | expand

Commit Message

Claudiu Zissulescu Ianculescu March 25, 2019, 10:56 a.m. UTC
Hi,

When not optimizing for size, we can restore first blink, hence the return
instruction will be executed faster.

OK to apply?
Claudiu

gcc/
xxxx-xx-xx  Claudiu Zissulescu  <claziss@synopsys.com>

	* config/arc/arc.c (GMASK_LEN): Define.
	(arc_restore_callee_saves): Restore first blink when
	!optimize_size.
---
 gcc/config/arc/arc.c | 37 +++++++++++++++++++++++++++++++++++--
 1 file changed, 35 insertions(+), 2 deletions(-)

Comments

Andrew Burgess April 2, 2019, 11:50 p.m. UTC | #1
* Claudiu Zissulescu <claziss@gmail.com> [2019-03-25 11:56:49 +0100]:

> Hi,
> 
> When not optimizing for size, we can restore first blink, hence the return
> instruction will be executed faster.
> 
> OK to apply?
> Claudiu
> 
> gcc/
> xxxx-xx-xx  Claudiu Zissulescu  <claziss@synopsys.com>
> 
> 	* config/arc/arc.c (GMASK_LEN): Define.
> 	(arc_restore_callee_saves): Restore first blink when
> 	!optimize_size.


This looks fine.

Thanks,
Andrew

> ---
>  gcc/config/arc/arc.c | 37 +++++++++++++++++++++++++++++++++++--
>  1 file changed, 35 insertions(+), 2 deletions(-)
> 
> diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
> index de2c8d5df9c..9a6920a709f 100644
> --- a/gcc/config/arc/arc.c
> +++ b/gcc/config/arc/arc.c
> @@ -2545,6 +2545,9 @@ struct GTY (()) arc_frame_info
>    bool save_return_addr;
>  };
>  
> +/* GMASK bit length -1.  */
> +#define GMASK_LEN 31
> +
>  /* Defining data structures for per-function information.  */
>  
>  typedef struct GTY (()) machine_function
> @@ -3087,6 +3090,8 @@ arc_restore_callee_saves (unsigned int gmask,
>  {
>    rtx reg;
>    int frame_deallocated = 0;
> +  HOST_WIDE_INT offs = cfun->machine->frame_info.reg_size;
> +  bool early_blink_restore;
>  
>    /* Emit mov fp,sp.  */
>    if (arc_frame_pointer_needed () && offset)
> @@ -3112,9 +3117,21 @@ arc_restore_callee_saves (unsigned int gmask,
>        offset = 0;
>      }
>  
> +  /* When we do not optimize for size, restore first blink.  */
> +  early_blink_restore = restore_blink && !optimize_size && offs;
> +  if (early_blink_restore)
> +    {
> +      rtx addr = plus_constant (Pmode, stack_pointer_rtx, offs);
> +      reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
> +      rtx insn = frame_move_inc (reg, gen_frame_mem (Pmode, addr),
> +				 stack_pointer_rtx, NULL_RTX);
> +      add_reg_note (insn, REG_CFA_RESTORE, reg);
> +      restore_blink = false;
> +    }
> +
>    /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask.  */
>    if (gmask)
> -    for (int i = 0; i <= 31; i++)
> +    for (int i = 0; i <= GMASK_LEN; i++)
>        {
>  	machine_mode restore_mode = SImode;
>  
> @@ -3127,7 +3144,23 @@ arc_restore_callee_saves (unsigned int gmask,
>  	  continue;
>  
>  	reg = gen_rtx_REG (restore_mode, i);
> -	frame_deallocated += frame_restore_reg (reg, 0);
> +	offs = 0;
> +	switch (restore_mode)
> +	  {
> +	  case E_DImode:
> +	    if ((GMASK_LEN - __builtin_clz (gmask)) == (i + 1)
> +		&& early_blink_restore)
> +	      offs = 4;
> +	    break;
> +	  case E_SImode:
> +	    if ((GMASK_LEN - __builtin_clz (gmask)) == i
> +		&& early_blink_restore)
> +	      offs = 4;
> +	    break;
> +	  default:
> +	    offs = 0;
> +	  }
> +	frame_deallocated += frame_restore_reg (reg, offs);
>  	offset = 0;
>  
>  	if (restore_mode == DImode)
> -- 
> 2.20.1
>
Claudiu Zissulescu Ianculescu April 3, 2019, 10:08 a.m. UTC | #2
Great, thanks!
Claudiu

On Wed, Apr 3, 2019 at 2:50 AM Andrew Burgess
<andrew.burgess@embecosm.com> wrote:
>
> * Claudiu Zissulescu <claziss@gmail.com> [2019-03-25 11:56:49 +0100]:
>
> > Hi,
> >
> > When not optimizing for size, we can restore first blink, hence the return
> > instruction will be executed faster.
> >
> > OK to apply?
> > Claudiu
> >
> > gcc/
> > xxxx-xx-xx  Claudiu Zissulescu  <claziss@synopsys.com>
> >
> >       * config/arc/arc.c (GMASK_LEN): Define.
> >       (arc_restore_callee_saves): Restore first blink when
> >       !optimize_size.
>
>
> This looks fine.
>
> Thanks,
> Andrew
>
> > ---
> >  gcc/config/arc/arc.c | 37 +++++++++++++++++++++++++++++++++++--
> >  1 file changed, 35 insertions(+), 2 deletions(-)
> >
> > diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
> > index de2c8d5df9c..9a6920a709f 100644
> > --- a/gcc/config/arc/arc.c
> > +++ b/gcc/config/arc/arc.c
> > @@ -2545,6 +2545,9 @@ struct GTY (()) arc_frame_info
> >    bool save_return_addr;
> >  };
> >
> > +/* GMASK bit length -1.  */
> > +#define GMASK_LEN 31
> > +
> >  /* Defining data structures for per-function information.  */
> >
> >  typedef struct GTY (()) machine_function
> > @@ -3087,6 +3090,8 @@ arc_restore_callee_saves (unsigned int gmask,
> >  {
> >    rtx reg;
> >    int frame_deallocated = 0;
> > +  HOST_WIDE_INT offs = cfun->machine->frame_info.reg_size;
> > +  bool early_blink_restore;
> >
> >    /* Emit mov fp,sp.  */
> >    if (arc_frame_pointer_needed () && offset)
> > @@ -3112,9 +3117,21 @@ arc_restore_callee_saves (unsigned int gmask,
> >        offset = 0;
> >      }
> >
> > +  /* When we do not optimize for size, restore first blink.  */
> > +  early_blink_restore = restore_blink && !optimize_size && offs;
> > +  if (early_blink_restore)
> > +    {
> > +      rtx addr = plus_constant (Pmode, stack_pointer_rtx, offs);
> > +      reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
> > +      rtx insn = frame_move_inc (reg, gen_frame_mem (Pmode, addr),
> > +                              stack_pointer_rtx, NULL_RTX);
> > +      add_reg_note (insn, REG_CFA_RESTORE, reg);
> > +      restore_blink = false;
> > +    }
> > +
> >    /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask.  */
> >    if (gmask)
> > -    for (int i = 0; i <= 31; i++)
> > +    for (int i = 0; i <= GMASK_LEN; i++)
> >        {
> >       machine_mode restore_mode = SImode;
> >
> > @@ -3127,7 +3144,23 @@ arc_restore_callee_saves (unsigned int gmask,
> >         continue;
> >
> >       reg = gen_rtx_REG (restore_mode, i);
> > -     frame_deallocated += frame_restore_reg (reg, 0);
> > +     offs = 0;
> > +     switch (restore_mode)
> > +       {
> > +       case E_DImode:
> > +         if ((GMASK_LEN - __builtin_clz (gmask)) == (i + 1)
> > +             && early_blink_restore)
> > +           offs = 4;
> > +         break;
> > +       case E_SImode:
> > +         if ((GMASK_LEN - __builtin_clz (gmask)) == i
> > +             && early_blink_restore)
> > +           offs = 4;
> > +         break;
> > +       default:
> > +         offs = 0;
> > +       }
> > +     frame_deallocated += frame_restore_reg (reg, offs);
> >       offset = 0;
> >
> >       if (restore_mode == DImode)
> > --
> > 2.20.1
> >
diff mbox series

Patch

diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index de2c8d5df9c..9a6920a709f 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -2545,6 +2545,9 @@  struct GTY (()) arc_frame_info
   bool save_return_addr;
 };
 
+/* GMASK bit length -1.  */
+#define GMASK_LEN 31
+
 /* Defining data structures for per-function information.  */
 
 typedef struct GTY (()) machine_function
@@ -3087,6 +3090,8 @@  arc_restore_callee_saves (unsigned int gmask,
 {
   rtx reg;
   int frame_deallocated = 0;
+  HOST_WIDE_INT offs = cfun->machine->frame_info.reg_size;
+  bool early_blink_restore;
 
   /* Emit mov fp,sp.  */
   if (arc_frame_pointer_needed () && offset)
@@ -3112,9 +3117,21 @@  arc_restore_callee_saves (unsigned int gmask,
       offset = 0;
     }
 
+  /* When we do not optimize for size, restore first blink.  */
+  early_blink_restore = restore_blink && !optimize_size && offs;
+  if (early_blink_restore)
+    {
+      rtx addr = plus_constant (Pmode, stack_pointer_rtx, offs);
+      reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
+      rtx insn = frame_move_inc (reg, gen_frame_mem (Pmode, addr),
+				 stack_pointer_rtx, NULL_RTX);
+      add_reg_note (insn, REG_CFA_RESTORE, reg);
+      restore_blink = false;
+    }
+
   /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask.  */
   if (gmask)
-    for (int i = 0; i <= 31; i++)
+    for (int i = 0; i <= GMASK_LEN; i++)
       {
 	machine_mode restore_mode = SImode;
 
@@ -3127,7 +3144,23 @@  arc_restore_callee_saves (unsigned int gmask,
 	  continue;
 
 	reg = gen_rtx_REG (restore_mode, i);
-	frame_deallocated += frame_restore_reg (reg, 0);
+	offs = 0;
+	switch (restore_mode)
+	  {
+	  case E_DImode:
+	    if ((GMASK_LEN - __builtin_clz (gmask)) == (i + 1)
+		&& early_blink_restore)
+	      offs = 4;
+	    break;
+	  case E_SImode:
+	    if ((GMASK_LEN - __builtin_clz (gmask)) == i
+		&& early_blink_restore)
+	      offs = 4;
+	    break;
+	  default:
+	    offs = 0;
+	  }
+	frame_deallocated += frame_restore_reg (reg, offs);
 	offset = 0;
 
 	if (restore_mode == DImode)