From b25644028cf67a35cc4e504564b22943fb4ccc30 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 7 Jul 2017 06:01:16 -0700 Subject: i386: Avoid stack realignment if possible 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. --- gcc/config/i386/i386.c | 78 +++++++++++++++++++++--------- 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" } } */ -- cgit v1.2.1