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

gcc/ChangeLog
gcc/config/aarch64/aarch64.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/test_fp_attribute_1.c
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 fa627c5e562a0299c354236c94cc0fae0bf56bfe..cf3a2d93656a2be18d062f5c2ffa778801d78d8e 100644 (file)
@@ -1,3 +1,8 @@
+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.
+
 2014-07-24  Jiong Wang  <jiong.wang@arm.com>
 
        * config/aarch64/aarch64.c (aarch64_restore_callee_saves)
index 163dfcdca46b026f179d620abb4efbaf2d1404ff..76e602749100ef204d8b93c2edb8bf198ce3759d 100644 (file)
@@ -1930,6 +1930,22 @@ aarch64_next_callee_save (unsigned regno, unsigned limit)
   return regno;
 }
 
+static void
+aarch64_pushwb_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_PRE_MODIFY (Pmode, base_rtx,
+                           plus_constant (Pmode, base_rtx, -adjustment));
+  mem = gen_rtx_MEM (mode, mem);
+
+  insn = emit_move_insn (mem, 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)
@@ -2279,11 +2295,10 @@ aarch64_expand_prologue (void)
     {
       bool skip_wb = false;
 
-      /* Save the frame pointer and lr if the frame pointer is needed
-        first.  Make the frame pointer point to the location of the
-        old frame pointer on the stack.  */
       if (frame_pointer_needed)
        {
+         skip_wb = true;
+
          if (fp_offset)
            {
              insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
@@ -2291,12 +2306,11 @@ aarch64_expand_prologue (void)
              RTX_FRAME_RELATED_P (insn) = 1;
              aarch64_set_frame_expr (gen_rtx_SET
                                      (Pmode, stack_pointer_rtx,
-                                      gen_rtx_MINUS (Pmode,
-                                                     stack_pointer_rtx,
+                                      gen_rtx_MINUS (Pmode, stack_pointer_rtx,
                                                      GEN_INT (offset))));
 
              aarch64_save_callee_saves (DImode, fp_offset, R29_REGNUM,
-                                        R30_REGNUM, skip_wb);
+                                        R30_REGNUM, false);
            }
          else
            aarch64_pushwb_pair_reg (DImode, R29_REGNUM, R30_REGNUM, offset);
@@ -2314,20 +2328,36 @@ aarch64_expand_prologue (void)
          RTX_FRAME_RELATED_P (insn) = 1;
          insn = emit_insn (gen_stack_tie (stack_pointer_rtx,
                                           hard_frame_pointer_rtx));
-
-         aarch64_save_callee_saves (DImode, fp_offset, R0_REGNUM, R28_REGNUM,
-                                    skip_wb);
        }
       else
        {
-         insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
-                                          GEN_INT (-offset)));
-         RTX_FRAME_RELATED_P (insn) = 1;
+         unsigned reg1 = cfun->machine->frame.wb_candidate1;
+         unsigned reg2 = cfun->machine->frame.wb_candidate2;
 
-         aarch64_save_callee_saves (DImode, fp_offset, R0_REGNUM, R30_REGNUM,
-                                    skip_wb);
+         if (fp_offset
+             || reg1 == FIRST_PSEUDO_REGISTER
+             || (reg2 == FIRST_PSEUDO_REGISTER
+                 && offset >= 256))
+           {
+             insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
+                                              GEN_INT (-offset)));
+             RTX_FRAME_RELATED_P (insn) = 1;
+           }
+         else
+           {
+             enum machine_mode mode1 = (reg1 <= R30_REGNUM) ? DImode : DFmode;
+
+             skip_wb = true;
+
+             if (reg2 == FIRST_PSEUDO_REGISTER)
+               aarch64_pushwb_single_reg (mode1, reg1, offset);
+             else
+               aarch64_pushwb_pair_reg (mode1, reg1, reg2, offset);
+           }
        }
 
+      aarch64_save_callee_saves (DImode, fp_offset, R0_REGNUM, R30_REGNUM,
+                                skip_wb);
       aarch64_save_callee_saves (DFmode, fp_offset, V0_REGNUM, V31_REGNUM,
                                 skip_wb);
     }
index 42ac62f2c0aa5025d45848bbd6501a2b2d46f8a5..901343c59f036f86e18fd1d17cf4acb102e81fee 100644 (file)
@@ -1,3 +1,15 @@
+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.
+       * 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_fp_attribute_1.c: Likewise.
+
 2014-07-24  Martin Jambor  <mjambor@suse.cz>
 
        PR ipa/61160
index 7538250c9f304eba62b7fa71b41d76bcf7130127..960174a5e202a612d89ab94f96f00d1140596f4e 100644 (file)
@@ -21,6 +21,6 @@ non_leaf_2 (void)
   leaf ();
 }
 
-/* { dg-final { scan-assembler-times "str\tx30, \\\[sp\\\]" 2 } } */
+/* { dg-final { scan-assembler-times "str\tx30, \\\[sp, -\[0-9\]+\\\]!" 2 } } */
 
 /* { dg-final { cleanup-saved-temps } } */
index feea7a2f275d35ea613a20bdfe2f8bb01fc6e18a..e9d04aacf632121622e94b0376c8ba5f580c2fc4 100644 (file)
@@ -6,9 +6,12 @@
      * optimized code should use "str !" for stack adjustment.  */
 
 /* { dg-do run } */
-/* { dg-options "-O2 -fomit-frame-pointer" } */
+/* { dg-options "-O2 -fomit-frame-pointer --save-temps" } */
 
 #include "test_frame_common.h"
 
 t_frame_pattern (test1, 200, )
 t_frame_run (test1)
+
+/* { dg-final { scan-assembler-times "str\tx30, \\\[sp, -\[0-9\]+\\\]!" 2 } } */
+/* { dg-final { cleanup-saved-temps } } */
index 2892c5fbc2e34fe200bf945c8d3f4fd24015c9b9..b646a7156cb27888ae2d38074cd6fb68984d02d5 100644 (file)
@@ -8,9 +8,12 @@
        the first subtractions could be optimized into "stp !".  */
 
 /* { dg-do run } */
-/* { dg-options "-O2 -fomit-frame-pointer" } */
+/* { dg-options "-O2 -fomit-frame-pointer --save-temps" } */
 
 #include "test_frame_common.h"
 
 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 { cleanup-saved-temps } } */
index aa15dae8a5225cc7b326ddd2a564e4c9fb3fd49b..b972664354595aae119a8d96e2d4c8cb1f169418 100644 (file)
@@ -6,9 +6,13 @@
      * optimized code should use "stp !" for stack adjustment.  */
 
 /* { dg-do run } */
-/* { dg-options "-O2 -fomit-frame-pointer" } */
+/* { dg-options "-O2 -fomit-frame-pointer --save-temps" } */
 
 #include "test_frame_common.h"
 
 t_frame_pattern (test2, 200, "x19")
 t_frame_run (test2)
+
+
+/* { dg-final { scan-assembler-times "stp\tx19, x30, \\\[sp, -\[0-9\]+\\\]!" 1 } } */
+/* { dg-final { cleanup-saved-temps } } */
index c45e7402cbe92c4fb0462371f400cc4790f6acfa..5a9a919b7f9fef7c37e12e40fa0116c8eccf07e3 100644 (file)
@@ -6,9 +6,12 @@
      * we can use "stp !" to optimize stack adjustment.  */
 
 /* { dg-do run } */
-/* { dg-options "-O2 -fomit-frame-pointer" } */
+/* { dg-options "-O2 -fomit-frame-pointer --save-temps" } */
 
 #include "test_frame_common.h"
 
 t_frame_pattern (test4, 400, "x19")
 t_frame_run (test4)
+
+/* { dg-final { scan-assembler-times "stp\tx19, x30, \\\[sp, -\[0-9\]+\\\]!" 1 } } */
+/* { dg-final { cleanup-saved-temps } } */
index 54f646b3a7a7c239840c9d97b04381e0037a88fa..6056f57c011d01f697ac35989518041da1607170 100644 (file)
@@ -7,9 +7,12 @@
        the second subtraction should use "str !".  */
 
 /* { dg-do run } */
-/* { dg-options "-O2 -fomit-frame-pointer" } */
+/* { dg-options "-O2 -fomit-frame-pointer --save-temps" } */
 
 #include "test_frame_common.h"
 
 t_frame_pattern (test6, 700, )
 t_frame_run (test6)
+
+/* { dg-final { scan-assembler-times "str\tx30, \\\[sp, -\[0-9\]+\\\]!" 2 } } */
+/* { dg-final { cleanup-saved-temps } } */
index aa97bc0bf57d750cc1f89f6a6f11b8bdc2416252..991860c759bf5d25ab55d07d7444d25ce024cd84 100644 (file)
@@ -7,9 +7,12 @@
        the second subtraction should use "stp !".  */
 
 /* { dg-do run } */
-/* { dg-options "-O2 -fomit-frame-pointer" } */
+/* { dg-options "-O2 -fomit-frame-pointer --save-temps" } */
 
 #include "test_frame_common.h"
 
 t_frame_pattern (test7, 700, "x19")
 t_frame_run (test7)
+
+/* { dg-final { scan-assembler-times "stp\tx19, x30, \\\[sp, -\[0-9\]+\\\]!" 1 } } */
+/* { dg-final { cleanup-saved-temps } } */
index f75f08021cfeaf143894c52c2a83257b11783e26..4a4d93bba2afa519cc42b76385b29bf41d064d88 100644 (file)
@@ -5,9 +5,12 @@
      * number of callee-saved reg == 1.  */
 
 /* { dg-do run } */
-/* { dg-options "-O2 -fomit-frame-pointer" } */
+/* { dg-options "-O2 -fomit-frame-pointer --save-temps" } */
 
 #include "test_frame_common.h"
 
 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 { cleanup-saved-temps } } */