From: jakub Date: Wed, 9 Nov 2011 21:28:57 +0000 (+0000) Subject: * function.h (requires_stack_frame_p): New prototype. X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=commitdiff_plain;h=ca8f816ffbc8e76d27c8314c1b8b0a137964198b * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@181236 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ce1bac49427..104de01bfe6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2011-11-09 Jakub Jelinek + + * 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 PR preprocessor/51061 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index acf9ad8a0ea..008af27042a 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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 - { - crtl->stack_realign_needed = stack_realign; - crtl->stack_realign_finalized = true; + + /* 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) + { + 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. */ diff --git a/gcc/function.c b/gcc/function.c index 0cbbbc5e404..0ee69ef22b6 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -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) { diff --git a/gcc/function.h b/gcc/function.h index 42e52acaad5..ce67add2748 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -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 *);