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.
@@ -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);
@@ -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;
}
@@ -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)
{
@@ -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
@@ -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;