This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PowerPC] rs6000_stack_info and rs6000_emit_epilogue tidy
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 2 Dec 2005 23:44:31 +1030
- Subject: [PowerPC] rs6000_stack_info and rs6000_emit_epilogue tidy
Some cleanups, mostly aimed at speeding rs6000_stack_info a little.
Comments interspersed in changelog entry.
* config/rs6000/rs6000.c (rs6000_stack_t): Remove toc_save_p,
toc_save_offset, toc_size, lr_size.
Unused fields.
(rs6000_stack_info): Use memset rather than bss struct copy to init.
Test rs6000_ra_ever_killed last in condition setting lr_save_p.
Avoids the function call in many cases.
Adjust for removal of unused rs6000_stack_t fields.
(debug_stack_info): Adjust.
(rs6000_ra_ever_killed): Expand FIND_REG_INC_NOTE. Test for calls
Expanding saves one mem load.
first, and don't bother checking for set/inc of lr on sibcalls.
Sibling calls don't twiddle lr.
(rs6000_emit_epilogue): Tidy code restoring stack pointer.
Besides simplifying the conditions, this fixes a minor bug where we
could emit (set (sp) (sp)) with DEFAULT_ABI != ABI_V4
&& current_function_calls_eh_return && use_backchain_to_restore_sp.
Bootstrapped and regression tested both powerpc-linux and
powerpc64-linux. OK for trunk?
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c (revision 107839)
+++ gcc/config/rs6000/rs6000.c (working copy)
@@ -77,7 +77,6 @@ typedef struct rs6000_stack {
int lr_save_p; /* true if the link reg needs to be saved */
int cr_save_p; /* true if the CR reg needs to be saved */
unsigned int vrsave_mask; /* mask of vec registers to save */
- int toc_save_p; /* true if the TOC needs to be saved */
int push_p; /* true if we need to allocate stack space */
int calls_p; /* true if the function makes any calls */
int world_save_p; /* true if we're saving *everything*:
@@ -90,7 +89,6 @@ typedef struct rs6000_stack {
int cr_save_offset; /* offset to save CR from initial SP */
int vrsave_save_offset; /* offset to save VRSAVE from initial SP */
int spe_gp_save_offset; /* offset to save spe 64-bit gprs */
- int toc_save_offset; /* offset to save the TOC pointer */
int varargs_save_offset; /* offset to save the varargs registers */
int ehrd_offset; /* offset to EH return data */
int reg_size; /* register size (4 or 8) */
@@ -102,13 +100,11 @@ typedef struct rs6000_stack {
int fp_size; /* size of saved FP registers */
int altivec_size; /* size of saved AltiVec registers */
int cr_size; /* size to hold CR if not in save_size */
- int lr_size; /* size to hold LR if not in save_size */
int vrsave_size; /* size to hold VRSAVE if not in save_size */
int altivec_padding_size; /* size of altivec alignment padding if
not in save_size */
int spe_gp_size; /* size of 64-bit GPR save size for SPE */
int spe_padding_size;
- int toc_size; /* size to hold TOC if not in save_size */
HOST_WIDE_INT total_size; /* total bytes allocated for stack */
int spe_64bit_regs_used;
} rs6000_stack_t;
@@ -12672,15 +12680,14 @@ is_altivec_return_reg (rtx reg, void *xy
static rs6000_stack_t *
rs6000_stack_info (void)
{
- static rs6000_stack_t info, zero_info;
+ static rs6000_stack_t info;
rs6000_stack_t *info_ptr = &info;
int reg_size = TARGET_32BIT ? 4 : 8;
int ehrd_size;
int save_align;
HOST_WIDE_INT non_fixed_size;
- /* Zero all fields portably. */
- info = zero_info;
+ memset (&info, 0, sizeof (info));
if (TARGET_SPE)
{
@@ -12733,10 +12740,9 @@ rs6000_stack_info (void)
|| cfun->machine->ra_needs_full_frame);
/* Determine if we need to save the link register. */
- if (rs6000_ra_ever_killed ()
- || (DEFAULT_ABI == ABI_AIX
- && current_function_profile
- && !TARGET_PROFILE_KERNEL)
+ if ((DEFAULT_ABI == ABI_AIX
+ && current_function_profile
+ && !TARGET_PROFILE_KERNEL)
#ifdef TARGET_RELOCATABLE
|| (TARGET_RELOCATABLE && (get_pool_size () != 0))
#endif
@@ -12744,7 +12750,8 @@ rs6000_stack_info (void)
&& !FP_SAVE_INLINE (info_ptr->first_fp_reg_save))
|| info_ptr->first_altivec_reg_save <= LAST_ALTIVEC_REGNO
|| (DEFAULT_ABI == ABI_V4 && current_function_calls_alloca)
- || info_ptr->calls_p)
+ || info_ptr->calls_p
+ || rs6000_ra_ever_killed ())
{
info_ptr->lr_save_p = 1;
regs_ever_live[LINK_REGISTER_REGNUM] = 1;
@@ -12867,8 +12874,7 @@ rs6000_stack_info (void)
- info_ptr->spe_gp_size;
/* Adjust for SPE case. */
- info_ptr->toc_save_offset
- = info_ptr->spe_gp_save_offset - info_ptr->toc_size;
+ info_ptr->ehrd_offset = info_ptr->spe_gp_save_offset;
}
else if (TARGET_ALTIVEC_ABI)
{
@@ -12888,12 +12894,11 @@ rs6000_stack_info (void)
- info_ptr->altivec_size;
/* Adjust for AltiVec case. */
- info_ptr->toc_save_offset
- = info_ptr->altivec_save_offset - info_ptr->toc_size;
+ info_ptr->ehrd_offset = info_ptr->altivec_save_offset;
}
else
- info_ptr->toc_save_offset = info_ptr->cr_save_offset - info_ptr->toc_size;
- info_ptr->ehrd_offset = info_ptr->toc_save_offset - ehrd_size;
+ info_ptr->ehrd_offset = info_ptr->cr_save_offset;
+ info_ptr->ehrd_offset -= ehrd_size;
info_ptr->lr_save_offset = reg_size;
break;
}
@@ -12907,9 +12912,7 @@ rs6000_stack_info (void)
+ info_ptr->spe_padding_size
+ ehrd_size
+ info_ptr->cr_size
- + info_ptr->lr_size
- + info_ptr->vrsave_size
- + info_ptr->toc_size,
+ + info_ptr->vrsave_size,
save_align);
non_fixed_size = (info_ptr->vars_size
@@ -12970,9 +12973,6 @@ rs6000_stack_info (void)
if (! info_ptr->cr_save_p)
info_ptr->cr_save_offset = 0;
- if (! info_ptr->toc_save_p)
- info_ptr->toc_save_offset = 0;
-
return info_ptr;
}
@@ -13068,9 +13068,6 @@ debug_stack_info (rs6000_stack_t *info)
if (info->cr_save_p)
fprintf (stderr, "\tcr_save_p = %5d\n", info->cr_save_p);
- if (info->toc_save_p)
- fprintf (stderr, "\ttoc_save_p = %5d\n", info->toc_save_p);
-
if (info->vrsave_mask)
fprintf (stderr, "\tvrsave_mask = 0x%x\n", info->vrsave_mask);
@@ -13104,9 +13101,6 @@ debug_stack_info (rs6000_stack_t *info)
if (info->cr_save_offset)
fprintf (stderr, "\tcr_save_offset = %5d\n", info->cr_save_offset);
- if (info->toc_save_offset)
- fprintf (stderr, "\ttoc_save_offset = %5d\n", info->toc_save_offset);
-
if (info->varargs_save_offset)
fprintf (stderr, "\tvarargs_save_offset = %5d\n", info->varargs_save_offset);
@@ -13147,15 +13141,9 @@ debug_stack_info (rs6000_stack_t *info)
fprintf (stderr, "\tspe_padding_size = %5d\n",
info->spe_padding_size);
- if (info->lr_size)
- fprintf (stderr, "\tlr_size = %5d\n", info->lr_size);
-
if (info->cr_size)
fprintf (stderr, "\tcr_size = %5d\n", info->cr_size);
- if (info->toc_size)
- fprintf (stderr, "\ttoc_size = %5d\n", info->toc_size);
-
if (info->save_size)
fprintf (stderr, "\tsave_size = %5d\n", info->save_size);
@@ -13278,10 +13266,12 @@ rs6000_ra_ever_killed (void)
{
if (INSN_P (insn))
{
- if (FIND_REG_INC_NOTE (insn, reg))
- return 1;
- else if (GET_CODE (insn) == CALL_INSN
- && !SIBLING_CALL_P (insn))
+ if (CALL_P (insn))
+ {
+ if (!SIBLING_CALL_P (insn))
+ return 1;
+ }
+ else if (find_regno_note (insn, REG_INC, LINK_REGISTER_REGNUM))
return 1;
else if (set_of (reg, insn) != NULL_RTX
&& !prologue_epilogue_contains (insn))
@@ -14713,7 +14703,6 @@ rs6000_emit_epilogue (int sibcall)
emit_move_insn (frame_reg_rtx,
gen_rtx_MEM (Pmode, sp_reg_rtx));
-
}
else if (info->push_p)
{
@@ -14947,30 +14936,20 @@ rs6000_emit_epilogue (int sibcall)
}
/* If this is V.4, unwind the stack pointer after all of the loads
- have been done. We need to emit a block here so that sched
- doesn't decide to move the sp change before the register restores
- (which may not have any obvious dependency on the stack). This
- doesn't hurt performance, because there is no scheduling that can
- be done after this point. */
- if (DEFAULT_ABI == ABI_V4
- || current_function_calls_eh_return)
+ have been done. */
+ if (frame_reg_rtx != sp_reg_rtx)
{
- if (frame_reg_rtx != sp_reg_rtx)
- rs6000_emit_stack_tie ();
-
- if (use_backchain_to_restore_sp)
- {
- emit_move_insn (sp_reg_rtx, frame_reg_rtx);
- }
- else if (sp_offset != 0)
- {
- emit_insn (TARGET_32BIT
- ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
- GEN_INT (sp_offset))
- : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
- GEN_INT (sp_offset)));
- }
- }
+ /* This blockage is needed so that sched doesn't decide to move
+ the sp change before the register restores. */
+ rs6000_emit_stack_tie ();
+ emit_move_insn (sp_reg_rtx, frame_reg_rtx);
+ }
+ else if (sp_offset != 0)
+ emit_insn (TARGET_32BIT
+ ? gen_addsi3 (sp_reg_rtx, sp_reg_rtx,
+ GEN_INT (sp_offset))
+ : gen_adddi3 (sp_reg_rtx, sp_reg_rtx,
+ GEN_INT (sp_offset)));
if (current_function_calls_eh_return)
{
--
Alan Modra
IBM OzLabs - Linux Technology Centre