This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch, arm] Fix PR45701
- From: Yao Qi <yao at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 22 Sep 2010 10:16:30 +0800
- Subject: [patch, arm] Fix PR45701
Hi,
We prefer using r3 to keep stack 8-byte alignment, as Richard E. did
here, and don't choose r3 if tail call insns are emitted, since it might
be used to pass value in a tail call.
2009-06-02 Richard Earnshaw <rearnsha@arm.com>
* arm.c (arm_get_frame_offsets): Prefer using r3 for padding a
push/pop multiple to 8-byte alignment.
In this patch, we can improve it a little bit, that is, we can still
choose r3 for stack padding, even tail call insns are emitted, if r3 is
*not* used to pass values to tail call.
New element 'rtx tail_call_insns' in struct rtl_data replaces 'bool
tail_call_emit' to track the tail call insns, so we can decide whether
or not use r3 in arm_get_frame_offsets.
Run regression test on arm-none-linux-gnueabi and i686-pc-linux-gnu. No
regression. OK for mainline?
--
Yao Qi
CodeSourcery
yao@codesourcery.com
(650) 331-3385 x739
2010-09-20 Yao Qi <yao@codesourcery.com>
* function.h (struct rtl_data): Replace field bool tail_call_emit
by rtx tail_call_insns.
* call.c (expand_call): Modified code to match new data structures.
* cfgcleanup.c (rest_of_handle_jump): Likewise.
* config/i386/i386.c (find_drap_reg): Likewise.
* config/arm/arm.c (arm_output_epilogue):Likewise.
(arm_get_frame_offsets): Use r3 for padding stack to 8-byte alignment
if r3 is not used to pass values to tail call.
diff --git a/gcc/calls.c b/gcc/calls.c
index 3888831..92389fd 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -3195,7 +3195,7 @@ expand_call (tree exp, rtx target, int ignore)
if (tail_call_insns)
{
emit_insn (tail_call_insns);
- crtl->tail_call_emit = true;
+ crtl->tail_call_insns = tail_call_insns;
}
else
emit_insn (normal_call_insns);
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index 9ded1e6..c6b8f28 100644
--- a/gcc/cfgcleanup.c
+++ b/gcc/cfgcleanup.c
@@ -2394,7 +2394,7 @@ cleanup_cfg (int mode)
static unsigned int
rest_of_handle_jump (void)
{
- if (crtl->tail_call_emit)
+ if (crtl->tail_call_insns)
fixup_tail_calls ();
return 0;
}
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 6f260ec..7c45648 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -14490,7 +14490,7 @@ arm_output_epilogue (rtx sibling)
&& !crtl->calls_eh_return
&& bit_count(saved_regs_mask) * 4 == count
&& !IS_INTERRUPT (func_type)
- && !crtl->tail_call_emit)
+ && !crtl->tail_call_insns)
{
unsigned long mask;
/* Preserve return values, of any size. */
@@ -15117,7 +15117,8 @@ arm_get_frame_offsets (void)
/* If it is safe to use r3, then do so. This sometimes
generates better code on Thumb-2 by avoiding the need to
use 32-bit push/pop instructions. */
- if (!crtl->tail_call_emit
+ if (!(crtl->tail_call_insns
+ && find_regno_fusage (crtl->tail_call_insns, USE, 3))
&& arm_size_return_regs () <= 12
&& (offsets->saved_regs_mask & (1 << 3)) == 0)
{
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 19d6387..973b8a7 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -8853,7 +8853,7 @@ find_drap_reg (void)
Since function with tail call may use any caller-saved
registers in epilogue, DRAP must not use caller-saved
register in such case. */
- if (DECL_STATIC_CHAIN (decl) || crtl->tail_call_emit)
+ if (DECL_STATIC_CHAIN (decl) || crtl->tail_call_insns)
return R13_REG;
return R10_REG;
@@ -8864,7 +8864,7 @@ find_drap_reg (void)
Since function with tail call may use any caller-saved
registers in epilogue, DRAP must not use caller-saved
register in such case. */
- if (DECL_STATIC_CHAIN (decl) || crtl->tail_call_emit)
+ if (DECL_STATIC_CHAIN (decl) || crtl->tail_call_insns)
return DI_REG;
/* Reuse static chain register if it isn't used for parameter
diff --git a/gcc/function.h b/gcc/function.h
index 93a9b82..7aebdfc 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -393,8 +393,9 @@ struct GTY(()) rtl_data {
/* Nonzero if the current function needs an lsda for exception handling. */
bool uses_eh_lsda;
- /* Set when the tail call has been produced. */
- bool tail_call_emit;
+ /* Insns that produced for tail call. Set NULL_RTX when the tail call
+ hasn't been produced. */
+ rtx tail_call_insns;
/* Nonzero if code to initialize arg_pointer_save_area has been emitted. */
bool arg_pointer_save_area_init;