summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2017-07-07 06:01:16 -0700
committerH.J. Lu <hjl.tools@gmail.com>2017-08-06 05:50:14 -0700
commitdbcf54cf1bb1ad6a82c5ea61218bd4c13e66d521 (patch)
tree738487f1bea8dfefe431866ba059aebd13831de7
parent70b22dd95d6b1e364b3952de59e531775bb1fa8a (diff)
downloadgcc-hjl/pr81313/master.tar.gz
i386: Avoid stack realignment if possiblehjl/pr81313/master
Since DRAP isn't used with -maccumulate-outgoing-args, pr59501-4a.c was xfailed due to stack frame access via frame pointer instead of DARP. This patch finds the maximum stack alignment from the stack frame access instructions and avoids stack realignment if stack alignment needed is less than or equal to incoming stack boundary. gcc/ PR target/59501 * config/i386/i386.c (ix86_finalize_stack_realign_flags): Don't realign stack if stack alignment needed is less than incoming stack boundary. gcc/testsuite/ PR target/59501 * gcc.target/i386/pr59501-4a.c: Remove xfail.
-rw-r--r--gcc/config/i386/i386.c84
-rw-r--r--gcc/testsuite/gcc.target/i386/pr59501-4a.c2
2 files changed, 56 insertions, 30 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index a5984659eb2..e63eda6d40b 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -14173,6 +14173,11 @@ ix86_finalize_stack_realign_flags (void)
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);
+
+ /* The preferred stack alignment is the minimum stack alignment. */
+ unsigned int stack_alignment = crtl->preferred_stack_boundary;
+ bool require_stack_frame = false;
+
FOR_EACH_BB_FN (bb, cfun)
{
rtx_insn *insn;
@@ -14181,43 +14186,64 @@ ix86_finalize_stack_realign_flags (void)
&& requires_stack_frame_p (insn, prologue_used,
set_up_by_prologue))
{
- if (crtl->stack_realign_needed != stack_realign)
- recompute_frame_layout_p = true;
- crtl->stack_realign_needed = stack_realign;
- crtl->stack_realign_finalized = true;
- if (recompute_frame_layout_p)
- ix86_compute_frame_layout ();
- return;
+ require_stack_frame = true;
+
+ /* Find the maximum stack alignment. */
+ subrtx_iterator::array_type array;
+ FOR_EACH_SUBRTX (iter, array, PATTERN (insn), ALL)
+ if ((MEM_P (*iter)))
+ {
+ unsigned int alignment = MEM_ALIGN (*iter);
+ if (alignment > stack_alignment)
+ stack_alignment = alignment;
+ }
}
}
- /* If drap has been set, but it actually isn't live at the start
- of the function, there is no reason to set it up. */
- if (crtl->drap_reg)
+ if (require_stack_frame)
{
- basic_block bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb;
- if (! REGNO_REG_SET_P (DF_LR_IN (bb), REGNO (crtl->drap_reg)))
+ /* Stack frame is required. If stack alignment needed is less
+ than incoming stack boundary, don't realign stack. */
+ stack_realign = incoming_stack_boundary < stack_alignment;
+ if (!stack_realign)
{
- crtl->drap_reg = NULL_RTX;
- crtl->need_drap = false;
+ crtl->max_used_stack_slot_alignment
+ = incoming_stack_boundary;
+ crtl->stack_alignment_needed
+ = incoming_stack_boundary;
}
}
else
- cfun->machine->no_drap_save_restore = true;
-
- 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 ();
- recompute_frame_layout_p = true;
+ {
+ /* If drap has been set, but it actually isn't live at the
+ start of the function, there is no reason to set it up. */
+ if (crtl->drap_reg)
+ {
+ basic_block bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb;
+ if (! REGNO_REG_SET_P (DF_LR_IN (bb),
+ REGNO (crtl->drap_reg)))
+ {
+ crtl->drap_reg = NULL_RTX;
+ crtl->need_drap = false;
+ }
+ }
+ else
+ cfun->machine->no_drap_save_restore = true;
+
+ 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 ();
+ recompute_frame_layout_p = true;
+ }
}
if (crtl->stack_realign_needed != stack_realign)
diff --git a/gcc/testsuite/gcc.target/i386/pr59501-4a.c b/gcc/testsuite/gcc.target/i386/pr59501-4a.c
index 5c3cb683a2e..908c7f457b6 100644
--- a/gcc/testsuite/gcc.target/i386/pr59501-4a.c
+++ b/gcc/testsuite/gcc.target/i386/pr59501-4a.c
@@ -5,4 +5,4 @@
#include "pr59501-3a.c"
/* Verify no dynamic realignment is performed. */
-/* { dg-final { scan-assembler-not "and\[^\n\r]*sp" { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-not "and\[^\n\r]*sp" } } */