From patchwork Tue Aug 3 23:53:16 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 60808 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id AA714B6EEA for ; Wed, 4 Aug 2010 09:55:10 +1000 (EST) Received: (qmail 10414 invoked by alias); 3 Aug 2010 23:53:46 -0000 Received: (qmail 9909 invoked by uid 22791); 3 Aug 2010 23:53:39 -0000 X-SWARE-Spam-Status: No, hits=-1.7 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from eggs.gnu.org (HELO eggs.gnu.org) (140.186.70.92) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 03 Aug 2010 23:53:27 +0000 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OgRIS-0000dD-10 for gcc-patches@gcc.gnu.org; Tue, 03 Aug 2010 19:53:26 -0400 Received: from b.mail.sonic.net ([64.142.19.5]:45996) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OgRIR-0000d0-Or for gcc-patches@gcc.gnu.org; Tue, 03 Aug 2010 19:53:23 -0400 Received: from are.twiddle.net (are.twiddle.net [75.101.38.216]) by b.mail.sonic.net (8.13.8.Beta0-Sonic/8.13.7) with ESMTP id o73NrMaI027965 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 3 Aug 2010 16:53:22 -0700 Received: from are.twiddle.net (localhost [127.0.0.1]) by are.twiddle.net (8.14.4/8.14.4) with ESMTP id o73NrMN9001169; Tue, 3 Aug 2010 16:53:22 -0700 Received: (from rth@localhost) by are.twiddle.net (8.14.4/8.14.4/Submit) id o73NrM4M001168; Tue, 3 Aug 2010 16:53:22 -0700 From: Richard Henderson To: gcc-patches@gcc.gnu.org Cc: kai.tietz@onevision.com, ubizjak@gmail.com Subject: [PATCH 9/9] Force the use of stack_pointer_offset in computing the frame size. Date: Tue, 3 Aug 2010 16:53:16 -0700 Message-Id: <1280879596-1089-10-git-send-email-rth@twiddle.net> In-Reply-To: <1280879596-1089-1-git-send-email-rth@twiddle.net> References: <1280879596-1089-1-git-send-email-rth@twiddle.net> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4-2.6 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org By exporting padding[012] and to_allocate from ix86_compute_frame_layout, we encouraged re-computation of the size of the local frame. All of the truly relevant offsets are now exported directly, and should be compared against directly. --- gcc/config/i386/i386.c | 61 ++++++++++++++++------------------------------- 1 files changed, 21 insertions(+), 40 deletions(-) * config/i386/i386.c (struct ix86_frame): Remove padding and to_allocate members. (ix86_compute_frame_layout): Don't store them. (ix86_can_use_return_insn_p): Use a more direct and more obviously correct condition for the position of the stack pointer. (ix86_expand_prologue): Compute remaining stack allocation based on the ultimate stack pointer offset. (ix86_expand_epilogue): Use more obvious expressions testing for the stack pointer already pointing to the saved registers. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 47ab5e0..c6aef9b 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -1846,17 +1846,13 @@ struct GTY(()) stack_local_entry { */ struct ix86_frame { - int padding0; int nsseregs; int nregs; - int padding1; int va_arg_size; int red_zone_size; - HOST_WIDE_INT frame; - int padding2; int outgoing_arguments_size; + HOST_WIDE_INT frame; - HOST_WIDE_INT to_allocate; /* The offsets relative to ARG_POINTER. */ HOST_WIDE_INT frame_pointer_offset; HOST_WIDE_INT hard_frame_pointer_offset; @@ -7873,15 +7869,14 @@ ix86_can_use_return_insn_p (void) if (! reload_completed || frame_pointer_needed) return 0; - /* Don't allow more than 32 pop, since that's all we can do + /* Don't allow more than 32k pop, since that's all we can do with one instruction. */ - if (crtl->args.pops_args - && crtl->args.size >= 32768) + if (crtl->args.pops_args && crtl->args.size >= 32768) return 0; ix86_compute_frame_layout (&frame); - return frame.to_allocate == 0 && frame.padding0 == 0 - && (frame.nregs + frame.nsseregs) == 0; + return (frame.stack_pointer_offset == UNITS_PER_WORD + && (frame.nregs + frame.nsseregs) == 0); } /* Value should be nonzero if functions must have frame pointers. @@ -8330,6 +8325,7 @@ ix86_compute_frame_layout (struct ix86_frame *frame) HOST_WIDE_INT offset; unsigned int preferred_alignment; HOST_WIDE_INT size = get_frame_size (); + HOST_WIDE_INT to_allocate; frame->nregs = ix86_nsaved_regs (); frame->nsseregs = ix86_nsaved_sseregs (); @@ -8416,14 +8412,12 @@ ix86_compute_frame_layout (struct ix86_frame *frame) offset += frame->nregs * UNITS_PER_WORD; frame->reg_save_offset = offset; - /* Align SSE reg save area. */ + /* Align and set SSE register save area. */ if (frame->nsseregs) - frame->padding0 = ((offset + 16 - 1) & -16) - offset; - else - frame->padding0 = 0; - - /* SSE register save area. */ - offset += frame->padding0 + frame->nsseregs * 16; + { + offset = (offset + 16 - 1) & -16; + offset += frame->nsseregs * 16; + } frame->sse_reg_save_offset = offset; /* Va-arg area */ @@ -8431,10 +8425,7 @@ ix86_compute_frame_layout (struct ix86_frame *frame) offset += frame->va_arg_size; /* Align start of frame for local function. */ - frame->padding1 = ((offset + stack_alignment_needed - 1) - & -stack_alignment_needed) - offset; - - offset += frame->padding1; + offset = (offset + stack_alignment_needed - 1) & -stack_alignment_needed; /* Frame pointer points here. */ frame->frame_pointer_offset = offset; @@ -8460,23 +8451,16 @@ ix86_compute_frame_layout (struct ix86_frame *frame) or using alloca. */ if (!current_function_is_leaf || cfun->calls_alloca || ix86_current_function_calls_tls_descriptor) - frame->padding2 = ((offset + preferred_alignment - 1) - & -preferred_alignment) - offset; - else - frame->padding2 = 0; - - offset += frame->padding2; + offset = (offset + preferred_alignment - 1) & -preferred_alignment; /* We've reached end of stack frame. */ frame->stack_pointer_offset = offset; /* Size prologue needs to allocate. */ - frame->to_allocate = - (size + frame->padding1 + frame->padding2 - + frame->outgoing_arguments_size + frame->va_arg_size); + to_allocate = offset - frame->sse_reg_save_offset; - if ((!frame->to_allocate && frame->nregs <= 1) - || (TARGET_64BIT && frame->to_allocate >= (HOST_WIDE_INT) 0x80000000)) + if ((!to_allocate && frame->nregs <= 1) + || (TARGET_64BIT && to_allocate >= (HOST_WIDE_INT) 0x80000000)) frame->save_regs_using_mov = false; if (ix86_using_red_zone () @@ -8484,7 +8468,7 @@ ix86_compute_frame_layout (struct ix86_frame *frame) && current_function_is_leaf && !ix86_current_function_calls_tls_descriptor) { - frame->red_zone_size = frame->to_allocate; + frame->red_zone_size = to_allocate; if (frame->save_regs_using_mov) frame->red_zone_size += frame->nregs * UNITS_PER_WORD; if (frame->red_zone_size > RED_ZONE_SIZE - RED_ZONE_RESERVE) @@ -8492,7 +8476,6 @@ ix86_compute_frame_layout (struct ix86_frame *frame) } else frame->red_zone_size = 0; - frame->to_allocate -= frame->red_zone_size; frame->stack_pointer_offset -= frame->red_zone_size; } @@ -9597,16 +9580,13 @@ ix86_expand_prologue (void) m->fs.realigned = true; } - allocate = frame.to_allocate + frame.nsseregs * 16 + frame.padding0; - if (!frame.save_regs_using_mov) { ix86_emit_save_regs (); int_registers_saved = true; gcc_assert (m->fs.sp_offset == frame.reg_save_offset); } - else - allocate += frame.nregs * UNITS_PER_WORD; + allocate = frame.stack_pointer_offset - m->fs.sp_offset; /* The stack has already been decremented by the instruction calling us so we need to probe unconditionally to preserve the protection area. */ @@ -9992,11 +9972,12 @@ ix86_expand_epilogue (int style) restore_regs_via_mov = true; else if (TARGET_EPILOGUE_USING_MOVE && cfun->machine->use_fast_prologue_epilogue - && (frame.nregs > 1 || (frame.to_allocate + frame.padding0) != 0)) + && (frame.nregs > 1 + || m->fs.sp_offset != frame.reg_save_offset)) restore_regs_via_mov = true; else if (frame_pointer_needed && !frame.nregs - && (frame.to_allocate + frame.padding0) != 0) + && m->fs.sp_offset != frame.reg_save_offset) restore_regs_via_mov = true; else if (frame_pointer_needed && TARGET_USE_LEAVE