[AArch64] Optimize epilogue when there is no frame pointer.
From-SVN: r213000
This commit is contained in:
parent
c5e1f66e59
commit
4b92caa1d6
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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 } } */
|
||||
|
@ -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 } } */
|
||||
|
@ -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 } } */
|
||||
|
@ -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 } } */
|
||||
|
@ -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 } } */
|
||||
|
@ -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 } } */
|
||||
|
@ -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 } } */
|
||||
|
Loading…
Reference in New Issue
Block a user