[AArch64] Optimize prologue when there is no frame pointer.
From-SVN: r212999
This commit is contained in:
parent
ae13fce333
commit
c5e1f66e59
@ -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>
|
2014-07-24 Jiong Wang <jiong.wang@arm.com>
|
||||||
|
|
||||||
* config/aarch64/aarch64.c (aarch64_restore_callee_saves)
|
* config/aarch64/aarch64.c (aarch64_restore_callee_saves)
|
||||||
|
@ -1930,6 +1930,22 @@ aarch64_next_callee_save (unsigned regno, unsigned limit)
|
|||||||
return regno;
|
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
|
static rtx
|
||||||
aarch64_gen_storewb_pair (enum machine_mode mode, rtx base, rtx reg, rtx reg2,
|
aarch64_gen_storewb_pair (enum machine_mode mode, rtx base, rtx reg, rtx reg2,
|
||||||
HOST_WIDE_INT adjustment)
|
HOST_WIDE_INT adjustment)
|
||||||
@ -2279,11 +2295,10 @@ aarch64_expand_prologue (void)
|
|||||||
{
|
{
|
||||||
bool skip_wb = false;
|
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)
|
if (frame_pointer_needed)
|
||||||
{
|
{
|
||||||
|
skip_wb = true;
|
||||||
|
|
||||||
if (fp_offset)
|
if (fp_offset)
|
||||||
{
|
{
|
||||||
insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
|
insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
|
||||||
@ -2291,12 +2306,11 @@ aarch64_expand_prologue (void)
|
|||||||
RTX_FRAME_RELATED_P (insn) = 1;
|
RTX_FRAME_RELATED_P (insn) = 1;
|
||||||
aarch64_set_frame_expr (gen_rtx_SET
|
aarch64_set_frame_expr (gen_rtx_SET
|
||||||
(Pmode, stack_pointer_rtx,
|
(Pmode, stack_pointer_rtx,
|
||||||
gen_rtx_MINUS (Pmode,
|
gen_rtx_MINUS (Pmode, stack_pointer_rtx,
|
||||||
stack_pointer_rtx,
|
|
||||||
GEN_INT (offset))));
|
GEN_INT (offset))));
|
||||||
|
|
||||||
aarch64_save_callee_saves (DImode, fp_offset, R29_REGNUM,
|
aarch64_save_callee_saves (DImode, fp_offset, R29_REGNUM,
|
||||||
R30_REGNUM, skip_wb);
|
R30_REGNUM, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
aarch64_pushwb_pair_reg (DImode, R29_REGNUM, R30_REGNUM, offset);
|
aarch64_pushwb_pair_reg (DImode, R29_REGNUM, R30_REGNUM, offset);
|
||||||
@ -2314,20 +2328,36 @@ aarch64_expand_prologue (void)
|
|||||||
RTX_FRAME_RELATED_P (insn) = 1;
|
RTX_FRAME_RELATED_P (insn) = 1;
|
||||||
insn = emit_insn (gen_stack_tie (stack_pointer_rtx,
|
insn = emit_insn (gen_stack_tie (stack_pointer_rtx,
|
||||||
hard_frame_pointer_rtx));
|
hard_frame_pointer_rtx));
|
||||||
|
|
||||||
aarch64_save_callee_saves (DImode, fp_offset, R0_REGNUM, R28_REGNUM,
|
|
||||||
skip_wb);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
insn = emit_insn (gen_add2_insn (stack_pointer_rtx,
|
unsigned reg1 = cfun->machine->frame.wb_candidate1;
|
||||||
GEN_INT (-offset)));
|
unsigned reg2 = cfun->machine->frame.wb_candidate2;
|
||||||
RTX_FRAME_RELATED_P (insn) = 1;
|
|
||||||
|
|
||||||
aarch64_save_callee_saves (DImode, fp_offset, R0_REGNUM, R30_REGNUM,
|
if (fp_offset
|
||||||
skip_wb);
|
|| 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,
|
aarch64_save_callee_saves (DFmode, fp_offset, V0_REGNUM, V31_REGNUM,
|
||||||
skip_wb);
|
skip_wb);
|
||||||
}
|
}
|
||||||
|
@ -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>
|
2014-07-24 Martin Jambor <mjambor@suse.cz>
|
||||||
|
|
||||||
PR ipa/61160
|
PR ipa/61160
|
||||||
|
@ -21,6 +21,6 @@ non_leaf_2 (void)
|
|||||||
leaf ();
|
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 } } */
|
/* { dg-final { cleanup-saved-temps } } */
|
||||||
|
@ -6,9 +6,12 @@
|
|||||||
* optimized code should use "str !" for stack adjustment. */
|
* optimized code should use "str !" for stack adjustment. */
|
||||||
|
|
||||||
/* { dg-do run } */
|
/* { dg-do run } */
|
||||||
/* { dg-options "-O2 -fomit-frame-pointer" } */
|
/* { dg-options "-O2 -fomit-frame-pointer --save-temps" } */
|
||||||
|
|
||||||
#include "test_frame_common.h"
|
#include "test_frame_common.h"
|
||||||
|
|
||||||
t_frame_pattern (test1, 200, )
|
t_frame_pattern (test1, 200, )
|
||||||
t_frame_run (test1)
|
t_frame_run (test1)
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler-times "str\tx30, \\\[sp, -\[0-9\]+\\\]!" 2 } } */
|
||||||
|
/* { dg-final { cleanup-saved-temps } } */
|
||||||
|
@ -8,9 +8,12 @@
|
|||||||
the first subtractions could be optimized into "stp !". */
|
the first subtractions could be optimized into "stp !". */
|
||||||
|
|
||||||
/* { dg-do run } */
|
/* { dg-do run } */
|
||||||
/* { dg-options "-O2 -fomit-frame-pointer" } */
|
/* { dg-options "-O2 -fomit-frame-pointer --save-temps" } */
|
||||||
|
|
||||||
#include "test_frame_common.h"
|
#include "test_frame_common.h"
|
||||||
|
|
||||||
t_frame_pattern_outgoing (test10, 480, "x19", 24, a[8], a[9], a[10])
|
t_frame_pattern_outgoing (test10, 480, "x19", 24, a[8], a[9], a[10])
|
||||||
t_frame_run (test10)
|
t_frame_run (test10)
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler-times "stp\tx19, x30, \\\[sp, -\[0-9\]+\\\]!" 1 } } */
|
||||||
|
/* { dg-final { cleanup-saved-temps } } */
|
||||||
|
@ -6,9 +6,13 @@
|
|||||||
* optimized code should use "stp !" for stack adjustment. */
|
* optimized code should use "stp !" for stack adjustment. */
|
||||||
|
|
||||||
/* { dg-do run } */
|
/* { dg-do run } */
|
||||||
/* { dg-options "-O2 -fomit-frame-pointer" } */
|
/* { dg-options "-O2 -fomit-frame-pointer --save-temps" } */
|
||||||
|
|
||||||
#include "test_frame_common.h"
|
#include "test_frame_common.h"
|
||||||
|
|
||||||
t_frame_pattern (test2, 200, "x19")
|
t_frame_pattern (test2, 200, "x19")
|
||||||
t_frame_run (test2)
|
t_frame_run (test2)
|
||||||
|
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler-times "stp\tx19, x30, \\\[sp, -\[0-9\]+\\\]!" 1 } } */
|
||||||
|
/* { dg-final { cleanup-saved-temps } } */
|
||||||
|
@ -6,9 +6,12 @@
|
|||||||
* we can use "stp !" to optimize stack adjustment. */
|
* we can use "stp !" to optimize stack adjustment. */
|
||||||
|
|
||||||
/* { dg-do run } */
|
/* { dg-do run } */
|
||||||
/* { dg-options "-O2 -fomit-frame-pointer" } */
|
/* { dg-options "-O2 -fomit-frame-pointer --save-temps" } */
|
||||||
|
|
||||||
#include "test_frame_common.h"
|
#include "test_frame_common.h"
|
||||||
|
|
||||||
t_frame_pattern (test4, 400, "x19")
|
t_frame_pattern (test4, 400, "x19")
|
||||||
t_frame_run (test4)
|
t_frame_run (test4)
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler-times "stp\tx19, x30, \\\[sp, -\[0-9\]+\\\]!" 1 } } */
|
||||||
|
/* { dg-final { cleanup-saved-temps } } */
|
||||||
|
@ -7,9 +7,12 @@
|
|||||||
the second subtraction should use "str !". */
|
the second subtraction should use "str !". */
|
||||||
|
|
||||||
/* { dg-do run } */
|
/* { dg-do run } */
|
||||||
/* { dg-options "-O2 -fomit-frame-pointer" } */
|
/* { dg-options "-O2 -fomit-frame-pointer --save-temps" } */
|
||||||
|
|
||||||
#include "test_frame_common.h"
|
#include "test_frame_common.h"
|
||||||
|
|
||||||
t_frame_pattern (test6, 700, )
|
t_frame_pattern (test6, 700, )
|
||||||
t_frame_run (test6)
|
t_frame_run (test6)
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler-times "str\tx30, \\\[sp, -\[0-9\]+\\\]!" 2 } } */
|
||||||
|
/* { dg-final { cleanup-saved-temps } } */
|
||||||
|
@ -7,9 +7,12 @@
|
|||||||
the second subtraction should use "stp !". */
|
the second subtraction should use "stp !". */
|
||||||
|
|
||||||
/* { dg-do run } */
|
/* { dg-do run } */
|
||||||
/* { dg-options "-O2 -fomit-frame-pointer" } */
|
/* { dg-options "-O2 -fomit-frame-pointer --save-temps" } */
|
||||||
|
|
||||||
#include "test_frame_common.h"
|
#include "test_frame_common.h"
|
||||||
|
|
||||||
t_frame_pattern (test7, 700, "x19")
|
t_frame_pattern (test7, 700, "x19")
|
||||||
t_frame_run (test7)
|
t_frame_run (test7)
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler-times "stp\tx19, x30, \\\[sp, -\[0-9\]+\\\]!" 1 } } */
|
||||||
|
/* { dg-final { cleanup-saved-temps } } */
|
||||||
|
@ -5,9 +5,12 @@
|
|||||||
* number of callee-saved reg == 1. */
|
* number of callee-saved reg == 1. */
|
||||||
|
|
||||||
/* { dg-do run } */
|
/* { dg-do run } */
|
||||||
/* { dg-options "-O2 -fomit-frame-pointer" } */
|
/* { dg-options "-O2 -fomit-frame-pointer --save-temps" } */
|
||||||
|
|
||||||
#include "test_frame_common.h"
|
#include "test_frame_common.h"
|
||||||
|
|
||||||
t_frame_pattern_outgoing (test8, 700, , 8, a[8])
|
t_frame_pattern_outgoing (test8, 700, , 8, a[8])
|
||||||
t_frame_run (test8)
|
t_frame_run (test8)
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler-times "str\tx30, \\\[sp, -\[0-9\]+\\\]!" 3 } } */
|
||||||
|
/* { dg-final { cleanup-saved-temps } } */
|
||||||
|
Loading…
Reference in New Issue
Block a user