aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Brown <julian@codesourcery.com>2009-12-24 10:46:00 +0000
committerRamana Radhakrishnan <ramana@gcc.gnu.org>2009-12-24 10:46:00 +0000
commit0986ef456ea9f7cb0a1ba2547690191139bc4dc5 (patch)
treef6f0314bf4dd56f06ecd57f3fd34fd361484f9f2
parent0b8a1859cf0412d2eca92c22e532dd56f013337e (diff)
downloadgcc-0986ef456ea9f7cb0a1ba2547690191139bc4dc5.zip
gcc-0986ef456ea9f7cb0a1ba2547690191139bc4dc5.tar.gz
gcc-0986ef456ea9f7cb0a1ba2547690191139bc4dc5.tar.bz2
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
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/arm/arm.c20
-rw-r--r--gcc/config/arm/arm.md11
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.target/arm/pr40887.c9
5 files changed, 41 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b1dabd3..f7583c2 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 a9ad903..e9ea2bd 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 e79ef15..cbb0a1b 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 98d85f4..f2d8927 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 0000000..ca896fc
--- /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();
+}