diff options
author | Jiong Wang <jiong.wang@arm.com> | 2014-07-24 14:43:15 +0000 |
---|---|---|
committer | Marcus Shawcroft <mshawcroft@gcc.gnu.org> | 2014-07-24 14:43:15 +0000 |
commit | 4b92caa1d6e5623e3562a76976d0bba7a413b2ce (patch) | |
tree | ba08a8e49e7ef1bb33c5d39add2e264b8636f409 /gcc | |
parent | c5e1f66e59f66083d9bc4229721aaae8d320c8dc (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.c | 55 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/test_frame_1.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/test_frame_10.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/test_frame_2.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/test_frame_4.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/test_frame_6.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/test_frame_7.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/test_frame_8.c | 2 |
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 } } */ |