function.h (requires_stack_frame_p): New prototype.

* function.h (requires_stack_frame_p): New prototype.
	* function.c (requires_stack_frame_p): No longer static.
	* config/i386/i386.c (ix86_finalize_stack_realign_flags): If
	stack_realign_fp was just a conservative guess for a function
	which doesn't use sp/fp/argp at all, clear frame_pointer_needed
	and stack realignment.

From-SVN: r181236
This commit is contained in:
Jakub Jelinek 2011-11-09 22:28:57 +01:00 committed by Jakub Jelinek
parent 5ed56cbbee
commit 0ff0609d03
4 changed files with 73 additions and 4 deletions

View File

@ -1,3 +1,12 @@
2011-11-09 Jakub Jelinek <jakub@redhat.com>
* function.h (requires_stack_frame_p): New prototype.
* function.c (requires_stack_frame_p): No longer static.
* config/i386/i386.c (ix86_finalize_stack_realign_flags): If
stack_realign_fp was just a conservative guess for a function
which doesn't use sp/fp/argp at all, clear frame_pointer_needed
and stack realignment.
2011-11-09 Paolo Carlini <paolo.carlini@oracle.com>
PR preprocessor/51061

View File

@ -9928,12 +9928,68 @@ ix86_finalize_stack_realign_flags (void)
/* After stack_realign_needed is finalized, we can't no longer
change it. */
gcc_assert (crtl->stack_realign_needed == stack_realign);
return;
}
else
/* If the only reason for frame_pointer_needed is that we conservatively
assumed stack realignment might be needed, but in the end nothing that
needed the stack alignment had been spilled, clear frame_pointer_needed
and say we don't need stack realignment. */
if (stack_realign
&& !crtl->need_drap
&& frame_pointer_needed
&& current_function_is_leaf
&& flag_omit_frame_pointer
&& current_function_sp_is_unchanging
&& !ix86_current_function_calls_tls_descriptor
&& !crtl->accesses_prior_frames
&& !cfun->calls_alloca
&& !crtl->calls_eh_return
&& !(flag_stack_check && STACK_CHECK_MOVING_SP)
&& !ix86_frame_pointer_required ()
&& get_frame_size () == 0
&& ix86_nsaved_sseregs () == 0
&& ix86_varargs_gpr_size + ix86_varargs_fpr_size == 0)
{
crtl->stack_realign_needed = stack_realign;
crtl->stack_realign_finalized = true;
HARD_REG_SET set_up_by_prologue, prologue_used;
basic_block bb;
CLEAR_HARD_REG_SET (prologue_used);
CLEAR_HARD_REG_SET (set_up_by_prologue);
add_to_hard_reg_set (&set_up_by_prologue, Pmode, STACK_POINTER_REGNUM);
add_to_hard_reg_set (&set_up_by_prologue, Pmode, ARG_POINTER_REGNUM);
add_to_hard_reg_set (&set_up_by_prologue, Pmode,
HARD_FRAME_POINTER_REGNUM);
FOR_EACH_BB (bb)
{
rtx insn;
FOR_BB_INSNS (bb, insn)
if (NONDEBUG_INSN_P (insn)
&& requires_stack_frame_p (insn, prologue_used,
set_up_by_prologue))
{
crtl->stack_realign_needed = stack_realign;
crtl->stack_realign_finalized = true;
return;
}
}
frame_pointer_needed = false;
stack_realign = false;
crtl->max_used_stack_slot_alignment = incoming_stack_boundary;
crtl->stack_alignment_needed = incoming_stack_boundary;
crtl->stack_alignment_estimated = incoming_stack_boundary;
if (crtl->preferred_stack_boundary > incoming_stack_boundary)
crtl->preferred_stack_boundary = incoming_stack_boundary;
df_finish_pass (true);
df_scan_alloc (NULL);
df_scan_blocks ();
df_compute_regs_ever_live (true);
df_analyze ();
}
crtl->stack_realign_needed = stack_realign;
crtl->stack_realign_finalized = true;
}
/* Expand the prologue into a bunch of separate insns. */

View File

@ -5284,7 +5284,7 @@ prologue_epilogue_contains (const_rtx insn)
PROLOGUE_USED contains the hard registers used in the function
prologue. SET_UP_BY_PROLOGUE is the set of registers we expect the
prologue to set up for the function. */
static bool
bool
requires_stack_frame_p (rtx insn, HARD_REG_SET prologue_used,
HARD_REG_SET set_up_by_prologue)
{

View File

@ -753,6 +753,10 @@ extern void used_types_insert (tree);
extern int get_next_funcdef_no (void);
extern int get_last_funcdef_no (void);
#ifdef HAVE_simple_return
extern bool requires_stack_frame_p (rtx, HARD_REG_SET, HARD_REG_SET);
#endif
/* In predict.c */
extern bool optimize_function_for_size_p (struct function *);
extern bool optimize_function_for_speed_p (struct function *);