From patchwork Tue Aug 3 23:53:15 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 60807 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 D6649B70A9 for ; Wed, 4 Aug 2010 09:54:59 +1000 (EST) Received: (qmail 10305 invoked by alias); 3 Aug 2010 23:53:45 -0000 Received: (qmail 9855 invoked by uid 22791); 3 Aug 2010 23:53:38 -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:26 +0000 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OgRIS-0000d8-0w for gcc-patches@gcc.gnu.org; Tue, 03 Aug 2010 19:53:25 -0400 Received: from b.mail.sonic.net ([64.142.19.5]:45995) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OgRIR-0000cw-Os 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 o73NrMrN027958 (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 o73NrLXw001165; Tue, 3 Aug 2010 16:53:22 -0700 Received: (from rth@localhost) by are.twiddle.net (8.14.4/8.14.4/Submit) id o73NrLPV001164; Tue, 3 Aug 2010 16:53:21 -0700 From: Richard Henderson To: gcc-patches@gcc.gnu.org Cc: kai.tietz@onevision.com, ubizjak@gmail.com Subject: [PATCH 8/9] Remove code duplication in ix86_expand_epilogue. Date: Tue, 3 Aug 2010 16:53:15 -0700 Message-Id: <1280879596-1089-9-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 Union the undo of the frame pointer between the pop and move code paths. Combine the local frame stack deallocation with the one for ix86_static_chain_on_stack, if possible. --- gcc/config/i386/i386.c | 129 ++++++++++++++++-------------------------------- 1 files changed, 42 insertions(+), 87 deletions(-) * config/i386/i386.c (ix86_expand_epilogue): Eliminate code duplication deconstructing the frame pointer. Simplify deallocation of the local stack frame. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index b4fddfc..47ab5e0 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -10095,49 +10095,11 @@ ix86_expand_epilogue (int style) } m->fs.sp_offset = UNITS_PER_WORD; } - else if (!frame_pointer_needed) - { - pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx, - GEN_INT (m->fs.sp_offset - - frame.reg_save_offset - + frame.nregs * UNITS_PER_WORD), - style, !using_drap); - } - else - { - if (stack_realign_fp) - { - /* We're re-defining what it means to be the local stack - frame. Thus the FP is suddenly valid and the SP isn't. */ - m->fs.fp_valid = true; - m->fs.sp_valid = false; - m->fs.realigned = false; - } - - /* Leave results in shorter dependency chains on CPUs that are - able to grok it fast. */ - if (TARGET_USE_LEAVE - || optimize_function_for_size_p (cfun) - || !cfun->machine->use_fast_prologue_epilogue) - ix86_emit_leave (); - else - { - pro_epilogue_adjust_stack (stack_pointer_rtx, - hard_frame_pointer_rtx, - const0_rtx, style, !using_drap); - ix86_emit_restore_reg_using_pop (hard_frame_pointer_rtx); - } - } } else { /* First step is to deallocate the stack frame so that we can - pop the registers. - - If we realign stack with frame pointer, then stack pointer - won't be able to recover via lea $offset(%bp), %sp, because - there is a padding area between bp and sp for realign. - "add $to_allocate, %sp" must be used instead. */ + pop the registers. */ if (!m->fs.sp_valid) { pro_epilogue_adjust_stack (stack_pointer_rtx, hard_frame_pointer_rtx, @@ -10155,34 +10117,38 @@ ix86_expand_epilogue (int style) } ix86_emit_restore_regs_using_pop (); + } - if (frame_pointer_needed) + /* If we used a stack pointer and haven't already got rid of it, + then do so now. */ + if (m->fs.fp_valid || stack_realign_fp) + { + if (stack_realign_fp) { - if (stack_realign_fp) - { - /* We're re-defining what it means to be the local stack - frame. Thus the FP is suddenly valid and the SP isn't. */ - m->fs.fp_valid = true; - m->fs.sp_valid = false; - m->fs.realigned = false; - } - - /* Leave results in shorter dependency chains on CPUs that are - able to grok it fast. */ - if (TARGET_USE_LEAVE - || (stack_realign_fp - && (optimize_function_for_size_p (cfun) - || !cfun->machine->use_fast_prologue_epilogue))) - ix86_emit_leave (); - else - { - if (stack_realign_fp) - pro_epilogue_adjust_stack (stack_pointer_rtx, - hard_frame_pointer_rtx, - const0_rtx, style, !using_drap); - ix86_emit_restore_reg_using_pop (hard_frame_pointer_rtx); - } - } + /* We're re-defining what it means to be the local stack + frame. Thus the FP is suddenly valid and the SP isn't. */ + m->fs.fp_valid = true; + m->fs.sp_valid = false; + m->fs.realigned = false; + } + + /* If the stack pointer is valid and pointing at the frame + pointer store address, then we only need a pop. */ + if (m->fs.sp_valid && m->fs.sp_offset == frame.hard_frame_pointer_offset) + ix86_emit_restore_reg_using_pop (hard_frame_pointer_rtx); + /* Leave results in shorter dependency chains on CPUs that are + able to grok it fast. */ + else if (TARGET_USE_LEAVE + || optimize_function_for_size_p (cfun) + || !cfun->machine->use_fast_prologue_epilogue) + ix86_emit_leave (); + else + { + pro_epilogue_adjust_stack (stack_pointer_rtx, + hard_frame_pointer_rtx, + const0_rtx, style, !using_drap); + ix86_emit_restore_reg_using_pop (hard_frame_pointer_rtx); + } } if (using_drap) @@ -10216,31 +10182,20 @@ ix86_expand_epilogue (int style) ix86_emit_restore_reg_using_pop (crtl->drap_reg); } - /* Remove the saved static chain from the stack. The use of ECX is - merely as a scratch register, not as the actual static chain. */ - if (ix86_static_chain_on_stack) - { - rtx r, insn; - - gcc_assert (m->fs.cfa_reg == stack_pointer_rtx); - m->fs.cfa_offset -= UNITS_PER_WORD; - m->fs.sp_offset -= UNITS_PER_WORD; - - r = gen_rtx_REG (Pmode, CX_REG); - insn = emit_insn (ix86_gen_pop1 (r)); - - r = plus_constant (stack_pointer_rtx, UNITS_PER_WORD); - r = gen_rtx_SET (VOIDmode, stack_pointer_rtx, r); - add_reg_note (insn, REG_CFA_ADJUST_CFA, r); - RTX_FRAME_RELATED_P (insn) = 1; - } - - /* At this point we should have de-allocated the entire stack frame, - so the stack pointer points to the return address. */ - gcc_assert (m->fs.sp_offset == UNITS_PER_WORD); + /* At this point the stack pointer must be valid, and we must have + restored all of the registers. We may not have deallocated the + entire stack frame. We've delayed this until now because it may + be possible to merge the local stack deallocation with the + deallocation forced by ix86_static_chain_on_stack. */ gcc_assert (m->fs.sp_valid); gcc_assert (!m->fs.fp_valid); gcc_assert (!m->fs.realigned); + if (m->fs.sp_offset != UNITS_PER_WORD) + { + pro_epilogue_adjust_stack (stack_pointer_rtx, stack_pointer_rtx, + GEN_INT (m->fs.sp_offset - UNITS_PER_WORD), + style, true); + } /* Sibcall epilogues don't want a return instruction. */ if (style == 0)