Commit 0986ef45 by Julian Brown Committed by Ramana Radhakrishnan

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
parent 0b8a1859
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> 2009-12-23 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/42475 PR rtl-optimization/42475
...@@ -11772,11 +11772,14 @@ output_call (rtx *operands) ...@@ -11772,11 +11772,14 @@ output_call (rtx *operands)
return ""; 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 * const char *
output_call_mem (rtx *operands) 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 ("ldr%?\t%|ip, %0", operands);
output_asm_insn ("mov%?\t%|lr, %|pc", operands); output_asm_insn ("mov%?\t%|lr, %|pc", operands);
...@@ -11788,17 +11791,12 @@ output_call_mem (rtx *operands) ...@@ -11788,17 +11791,12 @@ output_call_mem (rtx *operands)
first instruction. It's safe to use IP as the target of the first instruction. It's safe to use IP as the target of the
load since the call will kill it anyway. */ load since the call will kill it anyway. */
output_asm_insn ("ldr%?\t%|ip, %0", operands); output_asm_insn ("ldr%?\t%|ip, %0", operands);
if (arm_arch5)
output_asm_insn ("blx%?\t%|ip", operands);
else
{
output_asm_insn ("mov%?\t%|lr, %|pc", operands); output_asm_insn ("mov%?\t%|lr, %|pc", operands);
if (arm_arch4t) if (arm_arch4t)
output_asm_insn ("bx%?\t%|ip", operands); output_asm_insn ("bx%?\t%|ip", operands);
else else
output_asm_insn ("mov%?\t%|pc, %|ip", operands); output_asm_insn ("mov%?\t%|pc, %|ip", operands);
} }
}
else else
{ {
output_asm_insn ("mov%?\t%|lr, %|pc", operands); output_asm_insn ("mov%?\t%|lr, %|pc", operands);
......
...@@ -8453,12 +8453,17 @@ ...@@ -8453,12 +8453,17 @@
(set_attr "type" "call")] (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" (define_insn "*call_mem"
[(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m")) [(call (mem:SI (match_operand:SI 0 "call_memory_operand" "m"))
(match_operand 1 "" "")) (match_operand 1 "" ""))
(use (match_operand 2 "" "")) (use (match_operand 2 "" ""))
(clobber (reg:SI LR_REGNUM))] (clobber (reg:SI LR_REGNUM))]
"TARGET_ARM" "TARGET_ARM && !arm_arch5"
"* "*
return output_call_mem (operands); return output_call_mem (operands);
" "
...@@ -8560,13 +8565,15 @@ ...@@ -8560,13 +8565,15 @@
(set_attr "type" "call")] (set_attr "type" "call")]
) )
;; Note: see *call_mem
(define_insn "*call_value_mem" (define_insn "*call_value_mem"
[(set (match_operand 0 "" "") [(set (match_operand 0 "" "")
(call (mem:SI (match_operand:SI 1 "call_memory_operand" "m")) (call (mem:SI (match_operand:SI 1 "call_memory_operand" "m"))
(match_operand 2 "" ""))) (match_operand 2 "" "")))
(use (match_operand 3 "" "")) (use (match_operand 3 "" ""))
(clobber (reg:SI LR_REGNUM))] (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]); return output_call_mem (&operands[1]);
" "
......
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> 2009-12-23 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/42475 PR rtl-optimization/42475
......
/* { dg-options "-O2 -march=armv5te" } */
/* { dg-final { scan-assembler "blx" } } */
int (*indirect_func)();
int indirect_call()
{
return indirect_func();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment