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-07-07 19:11:03 -0700
commitb25644028cf67a35cc4e504564b22943fb4ccc30 (patch)
treeb071ef73cb940d5762220c1a74741f23f09fc440
parente664d5712d39545fd9e39f162733d49b69315d56 (diff)
downloadgcc-hjl/pr81313/gcc-6-branch.tar.gz
i386: Avoid stack realignment if possiblehjl/pr81313/gcc-6-branch
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 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.c78
-rw-r--r--gcc/testsuite/gcc.target/i386/pr59501-4a.c2
2 files changed, 55 insertions, 25 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 5e96c7a0983..eaf8c6789b4 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -12610,6 +12610,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;
@@ -12618,38 +12623,63 @@ ix86_finalize_stack_realign_flags (void)
&& requires_stack_frame_p (insn, prologue_used,
set_up_by_prologue))
{
- crtl->stack_realign_needed = stack_realign;
- crtl->stack_realign_finalized = true;
- 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 ();
+ {
+ /* 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 ();
+ }
}
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" } } */