This patch optimizes the prolog and epilog code to reduce the number of
commit5fc13c396f02b1d031fafbf932028beed26aa720
authorwilco <wilco@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 1 Aug 2016 16:37:24 +0000 (1 16:37 +0000)
committerwilco <wilco@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 1 Aug 2016 16:37:24 +0000 (1 16:37 +0000)
treedf4eedfb99680e45d6aa78e03d9b41f2d7cea674
parent93ca8b3824c693e04eedcf0a061afe820b201c88
This patch optimizes the prolog and epilog code to reduce the number of
instructions and avoid multiple writes to SP.  The key idea is that epilogs
are almost exact reverses of prologs, and thus all the decisions only need
to be taken once.  The frame layout is decided in aarch64_layout_frame()
and decisions recorded in the new aarch64_frame fields initial_adjust,
callee_adjust, callee_offset and final_adjust.

A generic frame setup consists of 5 basic steps:

1. sub sp, sp, initial_adjust
2. stp reg1, reg2, [sp, -callee_adjust]!      (push if callee_adjust != 0)
3. add fp, sp, callee_offset                  (if frame_pointer_needed)
4. stp reg3, reg4, [sp, callee_offset + N*16] (store remaining callee-saves)
5. sub sp, sp, final_adjust

The epilog reverses this, and may omit step 3 if alloca wasn't used.

    gcc/
* config/aarch64/aarch64.h (aarch64_frame):
Remove padding0 and hardfp_offset.  Add locals_offset,
initial_adjust, callee_adjust, callee_offset and final_adjust.
* config/aarch64/aarch64.c (aarch64_layout_frame):
Remove unused padding0 and hardfp_offset initializations.
Choose frame layout and set frame variables accordingly.
Use INVALID_REGNUM instead of FIRST_PSEUDO_REGISTER.
(aarch64_push_regs): Use INVALID_REGNUM, not FIRST_PSEUDO_REGISTER.
(aarch64_pop_regs): Likewise.
(aarch64_expand_prologue): Remove all decision code, just emit
prolog according to frame variables.
(aarch64_expand_epilogue): Remove all decision code, just emit
epilog according to frame variables.
(aarch64_initial_elimination_offset): Use offset to local/arg area.

    testsuite/
* gcc.target/aarch64/test_frame_10.c: Fix test to check for a
single stack adjustment, no writeback.
* gcc.target/aarch64/test_frame_12.c: Likewise.
* gcc.target/aarch64/test_frame_13.c: Likewise.
* gcc.target/aarch64/test_frame_15.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_16.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@238960 138bc75d-0d04-0410-961f-82ee72b054a4
12 files changed:
gcc/ChangeLog
gcc/config/aarch64/aarch64.c
gcc/config/aarch64/aarch64.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/test_frame_10.c
gcc/testsuite/gcc.target/aarch64/test_frame_12.c
gcc/testsuite/gcc.target/aarch64/test_frame_13.c
gcc/testsuite/gcc.target/aarch64/test_frame_15.c
gcc/testsuite/gcc.target/aarch64/test_frame_16.c [new file with mode: 0644]
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