From 0986ef456ea9f7cb0a1ba2547690191139bc4dc5 Mon Sep 17 00:00:00 2001 From: Julian Brown <julian@codesourcery.com> Date: Thu, 24 Dec 2009 10:46:00 +0000 Subject: [PATCH] re PR target/40887 (GCC generates suboptimal code for indirect function calls on ARM) Fix PR target/40887 2009-12-24 Julian Brown <julian@codesourcery.com> Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> PR target/40887 * config/arm/arm.c (output_call_mem): Remove armv5 support. * config/arm/arm.md (*call_mem): Disable for armv5. Add note. (*call_value_mem): Likewise. PR target/40887 * gcc.target/gcc.arm/pr40887.c: New test. Co-Authored-By: Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> From-SVN: r155453 --- gcc/ChangeLog | 8 ++++++++ gcc/config/arm/arm.c | 20 +++++++++----------- gcc/config/arm/arm.md | 11 +++++++++-- gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/gcc.target/arm/pr40887.c | 9 +++++++++ 5 files changed, 41 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/gcc.target/arm/pr40887.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b1dabd3def05..f7583c26fbc2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2009-12-24 Julian Brown <julian@codesourcery.com> + Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> + + PR target/40887 + * config/arm/arm.c (output_call_mem): Remove armv5 support. + * config/arm/arm.md (*call_mem): Disable for armv5. Add note. + (*call_value_mem): Likewise. + 2009-12-23 Jakub Jelinek <jakub@redhat.com> PR rtl-optimization/42475 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index a9ad903e81d4..e9ea2bd1ca0c 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -11772,11 +11772,14 @@ output_call (rtx *operands) return ""; } -/* Output a 'call' insn that is a reference in memory. */ +/* Output a 'call' insn that is a reference in memory. This is + disabled for ARMv5 and we prefer a blx instead because otherwise + there's a significant performance overhead. */ const char * output_call_mem (rtx *operands) { - if (TARGET_INTERWORK && !arm_arch5) + gcc_assert (!arm_arch5); + if (TARGET_INTERWORK) { output_asm_insn ("ldr%?\t%|ip, %0", operands); output_asm_insn ("mov%?\t%|lr, %|pc", operands); @@ -11788,16 +11791,11 @@ output_call_mem (rtx *operands) first instruction. It's safe to use IP as the target of the load since the call will kill it anyway. */ output_asm_insn ("ldr%?\t%|ip, %0", operands); - if (arm_arch5) - output_asm_insn ("blx%?\t%|ip", operands); + output_asm_insn ("mov%?\t%|lr, %|pc", operands); + if (arm_arch4t) + output_asm_insn ("bx%?\t%|ip", operands); else - { - output_asm_insn ("mov%?\t%|lr, %|pc", operands); - if (arm_arch4t) - output_asm_insn ("bx%?\t%|ip", operands); - else - output_asm_insn ("mov%?\t%|pc, %|ip", operands); - } + output_asm_insn ("mov%?\t%|pc, %|ip", operands); } else { diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index e79ef15fa7d5..cbb0a1bdf143 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -8453,12 +8453,17 @@ (set_attr "type" "call")] ) + +;; Note: not used for armv5+ because the sequence used (ldr pc, ...) is not +;; considered a function call by the branch predictor of some cores (PR40887). +;; Falls back to blx rN (*call_reg_armv5). + (define_insn "*call_mem" [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m")) (match_operand 1 "" "")) (use (match_operand 2 "" "")) (clobber (reg:SI LR_REGNUM))] - "TARGET_ARM" + "TARGET_ARM && !arm_arch5" "* return output_call_mem (operands); " @@ -8560,13 +8565,15 @@ (set_attr "type" "call")] ) +;; Note: see *call_mem + (define_insn "*call_value_mem" [(set (match_operand 0 "" "") (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m")) (match_operand 2 "" ""))) (use (match_operand 3 "" "")) (clobber (reg:SI LR_REGNUM))] - "TARGET_ARM && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))" + "TARGET_ARM && !arm_arch5 && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))" "* return output_call_mem (&operands[1]); " diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 98d85f4465f9..f2d89276540b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2009-12-24 Julian Brown <julian@codesourcery.com> + Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> + + PR target/40887 + * gcc.target/arm/pr40887.c: New test. + 2009-12-23 Jakub Jelinek <jakub@redhat.com> PR rtl-optimization/42475 diff --git a/gcc/testsuite/gcc.target/arm/pr40887.c b/gcc/testsuite/gcc.target/arm/pr40887.c new file mode 100644 index 000000000000..ca896fc16669 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr40887.c @@ -0,0 +1,9 @@ +/* { dg-options "-O2 -march=armv5te" } */ +/* { dg-final { scan-assembler "blx" } } */ + +int (*indirect_func)(); + +int indirect_call() +{ + return indirect_func(); +} -- GitLab