diff options
author | Claudiu Zissulescu <claziss@synopsys.com> | 2019-04-03 12:08:04 +0200 |
---|---|---|
committer | Claudiu Zissulescu <claziss@gcc.gnu.org> | 2019-04-03 12:08:04 +0200 |
commit | 8f84521301fa84c4fe3ab1b5294532b6a6dd3dae (patch) | |
tree | 0a218c2fbb8b9adf24ad9163347ec268f585d2cf /gcc | |
parent | deb012a19d852a3decf241cb4f81f6f7a606df69 (diff) | |
download | gcc-8f84521301fa84c4fe3ab1b5294532b6a6dd3dae.zip gcc-8f84521301fa84c4fe3ab1b5294532b6a6dd3dae.tar.gz gcc-8f84521301fa84c4fe3ab1b5294532b6a6dd3dae.tar.bz2 |
[ARC] Restore blink first when optimizing for speed.
When not optimizing for size, we can restore first blink, hence the return
instruction will be executed faster.
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.
From-SVN: r270120
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/arc/arc.c | 37 |
2 files changed, 41 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0568d3b..48b224a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2019-04-03 Claudiu Zissulescu <claziss@synopsys.com> + + * config/arc/arc.c (GMASK_LEN): Define. + (arc_restore_callee_saves): Restore first blink when + !optimize_size. + 2019-04-03 Sudakshina Das <sudi.das@arm.com> * doc/extend.texi: Add deprecated comment on sign-return-address diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c index 978d845..578c426 100644 --- a/gcc/config/arc/arc.c +++ b/gcc/config/arc/arc.c @@ -2506,6 +2506,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 @@ -3048,6 +3051,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) @@ -3073,9 +3078,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; @@ -3088,7 +3105,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) |