aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudiu Zissulescu <claziss@synopsys.com>2019-04-03 12:08:04 +0200
committerClaudiu Zissulescu <claziss@gcc.gnu.org>2019-04-03 12:08:04 +0200
commit8f84521301fa84c4fe3ab1b5294532b6a6dd3dae (patch)
tree0a218c2fbb8b9adf24ad9163347ec268f585d2cf
parentdeb012a19d852a3decf241cb4f81f6f7a606df69 (diff)
downloadgcc-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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/arc/arc.c37
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)