]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[AArch64] Optimize epilogue when there is no frame pointer.
authorJiong Wang <jiong.wang@arm.com>
Thu, 24 Jul 2014 14:43:15 +0000 (14:43 +0000)
committerMarcus Shawcroft <mshawcroft@gcc.gnu.org>
Thu, 24 Jul 2014 14:43:15 +0000 (14:43 +0000)
From-SVN: r213000

gcc/ChangeLog
gcc/config/aarch64/aarch64.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/test_frame_1.c
gcc/testsuite/gcc.target/aarch64/test_frame_10.c
gcc/testsuite/gcc.target/aarch64/test_frame_2.c
gcc/testsuite/gcc.target/aarch64/test_frame_4.c
gcc/testsuite/gcc.target/aarch64/test_frame_6.c
gcc/testsuite/gcc.target/aarch64/test_frame_7.c
gcc/testsuite/gcc.target/aarch64/test_frame_8.c

index cf3a2d93656a2be18d062f5c2ffa778801d78d8e..1e827b573e3815abfa3ba51ce77a7a2aea27bff1 100644 (file)
@@ -1,3 +1,8 @@
+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.
index 76e602749100ef204d8b93c2edb8bf198ce3759d..ed80269d55fafab40e08f658a03241391ba85f3e 100644 (file)
@@ -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;
index 901343c59f036f86e18fd1d17cf4acb102e81fee..1aeb7abd353e9ffb56cc10ac785123f152ab5885 100644 (file)
@@ -1,3 +1,14 @@
+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_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
index e9d04aacf632121622e94b0376c8ba5f580c2fc4..5b3c0ab32f700dfb27d2058143145e1b51b16352 100644 (file)
@@ -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 } } */
index b646a7156cb27888ae2d38074cd6fb68984d02d5..525b49e3868435e4e9b7aaeb8d2b764ef97005d9 100644 (file)
@@ -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 } } */
index b972664354595aae119a8d96e2d4c8cb1f169418..6ec4088da03c85e0e98ae58dbcbe3f3894d68f2e 100644 (file)
@@ -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 } } */
index 5a9a919b7f9fef7c37e12e40fa0116c8eccf07e3..ebfb290ef1229684b48d968b2d28d50211486c08 100644 (file)
@@ -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 } } */
index 6056f57c011d01f697ac35989518041da1607170..b5ea7ee08ce09e864be89a2ebf059af12c0f000c 100644 (file)
@@ -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 } } */
index 991860c759bf5d25ab55d07d7444d25ce024cd84..daa1f422e169d933a9c32cc9588628dc327750c0 100644 (file)
@@ -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 } } */
index 4a4d93bba2afa519cc42b76385b29bf41d064d88..4ce630ce0fec2d977ec6765c33b2fca7994414d4 100644 (file)
@@ -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 } } */