From: Jiong Wang Date: Wed, 12 Nov 2014 17:15:57 +0000 (+0000) Subject: [AArch64] Let LR register alloctable X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=1c923b60a0da74ae3b7f58857fac4d0c66d0e58b;p=gcc.git [AArch64] Let LR register alloctable gcc/ * config/aarch64/aarch64.h (CALL_USED_REGISTERS): Mark LR as caller-save. (EPILOGUE_USES): Guard the check by epilogue_completed. * config/aarch64/aarch64.c (aarch64_layout_frame): Explictly check for LR. (aarch64_can_eliminate): Check LR_REGNUM liveness. gcc/testsuite/ * gcc.target/aarch64/lr_free_1.c: New testcase for -fomit-frame-pointer. * gcc.target/aarch64/lr_free_2.c: New testcase for leaf -fno-omit-frame-pointer. From-SVN: r217431 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0f40e9993b0..492b5c74898 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2014-11-12 Jiong Wang + + * config/aarch64/aarch64.h (CALL_USED_REGISTERS): Mark LR as + caller-save. + (EPILOGUE_USES): Guard the check by epilogue_completed. + * config/aarch64/aarch64.c (aarch64_layout_frame): Explictly check for + LR. + (aarch64_can_eliminate): Check LR_REGNUM liveness. + 2014-11-12 Ramana Radhakrishnan * config/arm/arm.c (*_shiftsi): Fix typo. diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 0429d96710b..d4a8a2fe405 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -1901,7 +1901,8 @@ aarch64_layout_frame (void) /* ... and any callee saved register that dataflow says is live. */ for (regno = R0_REGNUM; regno <= R30_REGNUM; regno++) if (df_regs_ever_live_p (regno) - && !call_used_regs[regno]) + && (regno == R30_REGNUM + || !call_used_regs[regno])) cfun->machine->frame.reg_offset[regno] = SLOT_REQUIRED; for (regno = V0_REGNUM; regno <= V31_REGNUM; regno++) @@ -4418,6 +4419,16 @@ aarch64_can_eliminate (const int from, const int to) return false; } + else + { + /* If we decided that we didn't need a leaf frame pointer but then used + LR in the function, then we'll want a frame pointer after all, so + prevent this elimination to ensure a frame pointer is used. */ + if (to == STACK_POINTER_REGNUM + && flag_omit_leaf_frame_pointer + && df_regs_ever_live_p (LR_REGNUM)) + return false; + } return true; } diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index 99ff7cee745..c046b43c662 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -272,7 +272,7 @@ extern unsigned long aarch64_tune_flags; 1, 1, 1, 1, 1, 1, 1, 1, /* R0 - R7 */ \ 1, 1, 1, 1, 1, 1, 1, 1, /* R8 - R15 */ \ 1, 1, 1, 0, 0, 0, 0, 0, /* R16 - R23 */ \ - 0, 0, 0, 0, 0, 1, 0, 1, /* R24 - R30, SP */ \ + 0, 0, 0, 0, 0, 1, 1, 1, /* R24 - R30, SP */ \ 1, 1, 1, 1, 1, 1, 1, 1, /* V0 - V7 */ \ 0, 0, 0, 0, 0, 0, 0, 0, /* V8 - V15 */ \ 1, 1, 1, 1, 1, 1, 1, 1, /* V16 - V23 */ \ @@ -331,7 +331,7 @@ extern unsigned long aarch64_tune_flags; considered live at the start of the called function. */ #define EPILOGUE_USES(REGNO) \ - ((REGNO) == LR_REGNUM) + (epilogue_completed && (REGNO) == LR_REGNUM) /* EXIT_IGNORE_STACK should be nonzero if, when returning from a function, the stack pointer does not matter. The value is tested only in diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1c69805aed5..d017a9a96ca 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2014-11-12 Jiong Wang + + * gcc.target/aarch64/lr_free_1.c: New testcase for -fomit-frame-pointer. + * gcc.target/aarch64/lr_free_2.c: New testcase for leaf + -fno-omit-frame-pointer. + 2014-11-12 Marek Polacek * lib/gcc-dg.exp (${tool}_load): Call prune_file_path instead diff --git a/gcc/testsuite/gcc.target/aarch64/lr_free_1.c b/gcc/testsuite/gcc.target/aarch64/lr_free_1.c new file mode 100644 index 00000000000..4c530a2ad5e --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/lr_free_1.c @@ -0,0 +1,38 @@ +/* { dg-do run } */ +/* { dg-options "-fno-inline -O2 -fomit-frame-pointer -ffixed-x2 -ffixed-x3 -ffixed-x4 -ffixed-x5 -ffixed-x6 -ffixed-x7 -ffixed-x8 -ffixed-x9 -ffixed-x10 -ffixed-x11 -ffixed-x12 -ffixed-x13 -ffixed-x14 -ffixed-x15 -ffixed-x16 -ffixed-x17 -ffixed-x18 -ffixed-x19 -ffixed-x20 -ffixed-x21 -ffixed-x22 -ffixed-x23 -ffixed-x24 -ffixed-x25 -ffixed-x26 -ffixed-x27 -ffixed-28 -ffixed-29 --save-temps -mgeneral-regs-only -fno-ipa-cp" } */ + +extern void abort (); + +int +dec (int a, int b) +{ + return a + b; +} + +int +cal (int a, int b) +{ + int sum1 = a * b; + int sum2 = a / b; + int sum = dec (sum1, sum2); + return a + b + sum + sum1 + sum2; +} + +int +main (int argc, char **argv) +{ + int ret = cal (2, 1); + + if (ret != 11) + abort (); + + return 0; +} + +/* { dg-final { scan-assembler-times "str\tx30, \\\[sp, -\[0-9\]+\\\]!" 2 } } */ +/* { dg-final { scan-assembler "str\tw30, \\\[sp, \[0-9\]+\\\]" } } */ + +/* { dg-final { scan-assembler "ldr\tw30, \\\[sp, \[0-9\]+\\\]" } } */ +/* { dg-final { scan-assembler-times "ldr\tx30, \\\[sp\\\], \[0-9\]+" 2 } } */ + +/* { dg-final { cleanup-saved-temps } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/lr_free_2.c b/gcc/testsuite/gcc.target/aarch64/lr_free_2.c new file mode 100644 index 00000000000..6cf6e63c57b --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/lr_free_2.c @@ -0,0 +1,29 @@ +/* { dg-do run } */ +/* { dg-options "-fno-inline -O2 -ffixed-x2 -ffixed-x3 -ffixed-x4 -ffixed-x5 -ffixed-x6 -ffixed-x7 -ffixed-x8 -ffixed-x9 -ffixed-x10 -ffixed-x11 -ffixed-x12 -ffixed-x13 -ffixed-x14 -ffixed-x15 -ffixed-x16 -ffixed-x17 -ffixed-x18 -ffixed-x19 -ffixed-x20 -ffixed-x21 -ffixed-x22 -ffixed-x23 -ffixed-x24 -ffixed-x25 -ffixed-x26 -ffixed-x27 -ffixed-x28 --save-temps -mgeneral-regs-only -fno-ipa-cp -fdump-rtl-ira" } */ + +extern void abort (); + +int +cal (int a, int b) +{ + /* { dg-final { scan-assembler-times "stp\tx29, x30, \\\[sp, -\[0-9\]+\\\]!" 2 } } */ + int sum = a + b; + int sum1 = a * b; + /* { dg-final { scan-assembler-times "ldp\tx29, x30, \\\[sp\\\], \[0-9\]+" 2 } } */ + /* { dg-final { scan-rtl-dump "assign reg 30" "ira" } } */ + return (a + b + sum + sum1); +} + +int +main (int argc, char **argv) +{ + int ret = cal (1, 2); + + if (ret != 8) + abort (); + + return 0; +} + +/* { dg-final { cleanup-saved-temps } } */ +/* { dg-final { cleanup-rtl-dump "ira" } } */