diff options
author | Jakub Jelinek <jakub@redhat.com> | 2011-11-09 22:28:57 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2011-11-09 22:28:57 +0100 |
commit | 0ff0609d035ffb794449e33ed8e13d2018bc3bce (patch) | |
tree | 2a5c62e5d8fd156f9d6fd45cbb723e18253aa233 /gcc | |
parent | 5ed56cbbee96b41fa9ef743c48245096d84205b7 (diff) | |
download | gcc-0ff0609d035ffb794449e33ed8e13d2018bc3bce.zip gcc-0ff0609d035ffb794449e33ed8e13d2018bc3bce.tar.gz gcc-0ff0609d035ffb794449e33ed8e13d2018bc3bce.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 64 | ||||
-rw-r--r-- | gcc/function.c | 2 | ||||
-rw-r--r-- | gcc/function.h | 4 |
4 files changed, 74 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ce1bac4..104de01 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index acf9ad8..008af27 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 0cbbbc5..0ee69ef 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 42e52ac..ce67add 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 *); |