aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJiong Wang <jiong.wang@arm.com>2014-07-24 14:43:15 +0000
committerMarcus Shawcroft <mshawcroft@gcc.gnu.org>2014-07-24 14:43:15 +0000
commit4b92caa1d6e5623e3562a76976d0bba7a413b2ce (patch)
treeba08a8e49e7ef1bb33c5d39add2e264b8636f409 /gcc
parentc5e1f66e59f66083d9bc4229721aaae8d320c8dc (diff)
downloadgcc-4b92caa1d6e5623e3562a76976d0bba7a413b2ce.zip
gcc-4b92caa1d6e5623e3562a76976d0bba7a413b2ce.tar.gz
gcc-4b92caa1d6e5623e3562a76976d0bba7a413b2ce.tar.bz2
[AArch64] Optimize epilogue when there is no frame pointer.
From-SVN: r213000
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/aarch64/aarch64.c55
-rw-r--r--gcc/testsuite/ChangeLog11
-rw-r--r--gcc/testsuite/gcc.target/aarch64/test_frame_1.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/test_frame_10.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/test_frame_2.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/test_frame_4.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/test_frame_6.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/test_frame_7.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/test_frame_8.c2
10 files changed, 75 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cf3a2d9..1e827b5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@
2014-07-24 Jiong Wang <jiong.wang@arm.com>
+ * config/aarch64/aarch64.c (aarch64_popwb_single_reg): New function.
+ (aarch64_expand_epilogue): Optimize epilogue when !frame_pointer_needed.
+
+2014-07-24 Jiong Wang <jiong.wang@arm.com>
+
* config/aarch64/aarch64.c (aarch64_pushwb_single_reg): New function.
(aarch64_expand_prologue): Optimize prologue when !frame_pointer_needed.
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 76e6027..ed80269 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -1946,6 +1946,23 @@ aarch64_pushwb_single_reg (enum machine_mode mode, unsigned regno,
RTX_FRAME_RELATED_P (insn) = 1;
}
+static void
+aarch64_popwb_single_reg (enum machine_mode mode, unsigned regno,
+ HOST_WIDE_INT adjustment)
+{
+ rtx base_rtx = stack_pointer_rtx;
+ rtx insn, reg, mem;
+
+ reg = gen_rtx_REG (mode, regno);
+ mem = gen_rtx_POST_MODIFY (Pmode, base_rtx,
+ plus_constant (Pmode, base_rtx, adjustment));
+ mem = gen_rtx_MEM (mode, mem);
+
+ insn = emit_move_insn (reg, mem);
+ add_reg_note (insn, REG_CFA_RESTORE, reg);
+ RTX_FRAME_RELATED_P (insn) = 1;
+}
+
static rtx
aarch64_gen_storewb_pair (enum machine_mode mode, rtx base, rtx reg, rtx reg2,
HOST_WIDE_INT adjustment)
@@ -2384,7 +2401,6 @@ aarch64_expand_epilogue (bool for_sibcall)
HOST_WIDE_INT fp_offset;
rtx insn;
rtx cfa_reg;
- bool skip_wb = false;
aarch64_layout_frame ();
@@ -2432,22 +2448,41 @@ aarch64_expand_epilogue (bool for_sibcall)
cfa_reg = stack_pointer_rtx;
}
- aarch64_restore_callee_saves (DFmode, frame_pointer_needed ? 0 : fp_offset,
- V0_REGNUM, V31_REGNUM, skip_wb);
-
if (offset > 0)
{
+ unsigned reg1 = cfun->machine->frame.wb_candidate1;
+ unsigned reg2 = cfun->machine->frame.wb_candidate2;
+ bool skip_wb = true;
+
if (frame_pointer_needed)
+ fp_offset = 0;
+ else if (fp_offset
+ || reg1 == FIRST_PSEUDO_REGISTER
+ || (reg2 == FIRST_PSEUDO_REGISTER
+ && offset >= 256))
+ skip_wb = false;
+
+ aarch64_restore_callee_saves (DImode, fp_offset, R0_REGNUM, R30_REGNUM,
+ skip_wb);
+ aarch64_restore_callee_saves (DFmode, fp_offset, V0_REGNUM, V31_REGNUM,
+ skip_wb);
+
+ if (skip_wb)
{
- aarch64_restore_callee_saves (DImode, 0, R0_REGNUM, R28_REGNUM,
- skip_wb);
- aarch64_popwb_pair_reg (DImode, R29_REGNUM, R30_REGNUM, offset,
- cfa_reg);
+ enum machine_mode mode1 = (reg1 <= R30_REGNUM) ? DImode : DFmode;
+
+ if (reg2 == FIRST_PSEUDO_REGISTER)
+ aarch64_popwb_single_reg (mode1, reg1, offset);
+ else
+ {
+ if (reg1 != HARD_FRAME_POINTER_REGNUM)
+ cfa_reg = NULL;
+
+ aarch64_popwb_pair_reg (mode1, reg1, reg2, offset, cfa_reg);
+ }
}
else
{
- aarch64_restore_callee_saves (DImode, fp_offset, R0_REGNUM,
- R30_REGNUM, skip_wb);
insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
GEN_INT (offset)));
RTX_FRAME_RELATED_P (insn) = 1;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 901343c..1aeb7ab 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -2,6 +2,17 @@
* gcc.target/aarch64/test_frame_1.c: Match optimized instruction
sequences.
+ * gcc.target/aarch64/test_frame_2.c: Likewise.
+ * gcc.target/aarch64/test_frame_4.c: Likewise.
+ * gcc.target/aarch64/test_frame_6.c: Likewise.
+ * gcc.target/aarch64/test_frame_7.c: Likewise.
+ * gcc.target/aarch64/test_frame_8.c: Likewise.
+ * gcc.target/aarch64/test_frame_10.c: Likewise.
+
+2014-07-24 Jiong Wang <jiong.wang@arm.com>
+
+ * gcc.target/aarch64/test_frame_1.c: Match optimized instruction
+ sequences.
* gcc.target/aarch64/test_frame_10.c: Likewise.
* gcc.target/aarch64/test_frame_2.c: Likewise.
* gcc.target/aarch64/test_frame_4.c: Likewise.
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_1.c b/gcc/testsuite/gcc.target/aarch64/test_frame_1.c
index e9d04aa..5b3c0ab 100644
--- a/gcc/testsuite/gcc.target/aarch64/test_frame_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_1.c
@@ -14,4 +14,6 @@ t_frame_pattern (test1, 200, )
t_frame_run (test1)
/* { dg-final { scan-assembler-times "str\tx30, \\\[sp, -\[0-9\]+\\\]!" 2 } } */
+/* { dg-final { scan-assembler-times "ldr\tx30, \\\[sp\\\], \[0-9\]+" 3 } } */
+
/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_10.c b/gcc/testsuite/gcc.target/aarch64/test_frame_10.c
index b646a71..525b49e 100644
--- a/gcc/testsuite/gcc.target/aarch64/test_frame_10.c
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_10.c
@@ -16,4 +16,6 @@ t_frame_pattern_outgoing (test10, 480, "x19", 24, a[8], a[9], a[10])
t_frame_run (test10)
/* { dg-final { scan-assembler-times "stp\tx19, x30, \\\[sp, -\[0-9\]+\\\]!" 1 } } */
+/* { dg-final { scan-assembler-times "ldp\tx19, x30, \\\[sp\\\], \[0-9\]+" 1 } } */
+
/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_2.c b/gcc/testsuite/gcc.target/aarch64/test_frame_2.c
index b972664..6ec4088 100644
--- a/gcc/testsuite/gcc.target/aarch64/test_frame_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_2.c
@@ -15,4 +15,6 @@ t_frame_run (test2)
/* { dg-final { scan-assembler-times "stp\tx19, x30, \\\[sp, -\[0-9\]+\\\]!" 1 } } */
+/* { dg-final { scan-assembler-times "ldp\tx19, x30, \\\[sp\\\], \[0-9\]+" 2 } } */
+
/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_4.c b/gcc/testsuite/gcc.target/aarch64/test_frame_4.c
index 5a9a919..ebfb290 100644
--- a/gcc/testsuite/gcc.target/aarch64/test_frame_4.c
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_4.c
@@ -14,4 +14,6 @@ t_frame_pattern (test4, 400, "x19")
t_frame_run (test4)
/* { dg-final { scan-assembler-times "stp\tx19, x30, \\\[sp, -\[0-9\]+\\\]!" 1 } } */
+/* { dg-final { scan-assembler-times "ldp\tx19, x30, \\\[sp\\\], \[0-9\]+" 2 } } */
+
/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_6.c b/gcc/testsuite/gcc.target/aarch64/test_frame_6.c
index 6056f57..b5ea7ee 100644
--- a/gcc/testsuite/gcc.target/aarch64/test_frame_6.c
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_6.c
@@ -15,4 +15,6 @@ t_frame_pattern (test6, 700, )
t_frame_run (test6)
/* { dg-final { scan-assembler-times "str\tx30, \\\[sp, -\[0-9\]+\\\]!" 2 } } */
+/* { dg-final { scan-assembler-times "ldr\tx30, \\\[sp\\\], \[0-9\]+" 3 } } */
+
/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_7.c b/gcc/testsuite/gcc.target/aarch64/test_frame_7.c
index 991860c..daa1f42 100644
--- a/gcc/testsuite/gcc.target/aarch64/test_frame_7.c
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_7.c
@@ -15,4 +15,6 @@ t_frame_pattern (test7, 700, "x19")
t_frame_run (test7)
/* { dg-final { scan-assembler-times "stp\tx19, x30, \\\[sp, -\[0-9\]+\\\]!" 1 } } */
+/* { dg-final { scan-assembler-times "ldp\tx19, x30, \\\[sp\\\], \[0-9\]+" 2 } } */
+
/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/test_frame_8.c b/gcc/testsuite/gcc.target/aarch64/test_frame_8.c
index 4a4d93b..4ce630c 100644
--- a/gcc/testsuite/gcc.target/aarch64/test_frame_8.c
+++ b/gcc/testsuite/gcc.target/aarch64/test_frame_8.c
@@ -13,4 +13,6 @@ t_frame_pattern_outgoing (test8, 700, , 8, a[8])
t_frame_run (test8)
/* { dg-final { scan-assembler-times "str\tx30, \\\[sp, -\[0-9\]+\\\]!" 3 } } */
+/* { dg-final { scan-assembler-times "ldr\tx30, \\\[sp\\\], \[0-9\]+" 3 } } */
+
/* { dg-final { cleanup-saved-temps } } */