diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2017-07-07 06:01:16 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2017-07-07 19:11:03 -0700 |
commit | b25644028cf67a35cc4e504564b22943fb4ccc30 (patch) | |
tree | b071ef73cb940d5762220c1a74741f23f09fc440 | |
parent | e664d5712d39545fd9e39f162733d49b69315d56 (diff) | |
download | gcc-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.c | 78 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr59501-4a.c | 2 |
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" } } */ |