aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2011-11-09 22:28:57 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2011-11-09 22:28:57 +0100
commit0ff0609d035ffb794449e33ed8e13d2018bc3bce (patch)
tree2a5c62e5d8fd156f9d6fd45cbb723e18253aa233 /gcc
parent5ed56cbbee96b41fa9ef743c48245096d84205b7 (diff)
downloadgcc-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/ChangeLog9
-rw-r--r--gcc/config/i386/i386.c64
-rw-r--r--gcc/function.c2
-rw-r--r--gcc/function.h4
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 *);