From patchwork Sun Oct 2 17:46:14 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 117356 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 4AE96B6F6B for ; Mon, 3 Oct 2011 04:46:35 +1100 (EST) Received: (qmail 14192 invoked by alias); 2 Oct 2011 17:46:33 -0000 Received: (qmail 14183 invoked by uid 22791); 2 Oct 2011 17:46:32 -0000 X-SWARE-Spam-Status: No, hits=-2.3 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: sourceware.org Received: from mail-wy0-f175.google.com (HELO mail-wy0-f175.google.com) (74.125.82.175) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 02 Oct 2011 17:46:17 +0000 Received: by mail-wy0-f175.google.com with SMTP id 5so2768627wyh.20 for ; Sun, 02 Oct 2011 10:46:16 -0700 (PDT) Received: by 10.216.221.223 with SMTP id r73mr2297170wep.106.1317577576748; Sun, 02 Oct 2011 10:46:16 -0700 (PDT) Received: from localhost (rsandifo.gotadsl.co.uk. [82.133.89.107]) by mx.google.com with ESMTPS id fy13sm19311797wbb.18.2011.10.02.10.46.15 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 02 Oct 2011 10:46:16 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, rdsandiford@googlemail.com Subject: [committed, MIPS] Emit stack barriers Date: Sun, 02 Oct 2011 18:46:14 +0100 Message-ID: <87zkhj70d5.fsf@firetop.home> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 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 As discussed recently, this patch adds the stack barriers that are missing from MIPS' prologue and epilogue patterns. The attached testcase failed before but passes afterwards. Tested on mips64-linux-gnu and applied. Thanks to Jiangning for highlighting the problem. Richard gcc/ * config/mips/mips.c (mips_frame_barrier): New function. (mips_expand_prologue): Call it after allocating stack space. (mips_deallocate_stack): New function. (mips_expand_epilogue): Call mips_frame_barrier and mips_deallocate_stack. gcc/testsuite/ * gcc.target/mips/stack-1.c: New test. Index: gcc/config/mips/mips.c =================================================================== --- gcc/config/mips/mips.c 2011-10-01 10:59:15.000000000 +0100 +++ gcc/config/mips/mips.c 2011-10-02 10:50:15.000000000 +0100 @@ -9892,6 +9892,14 @@ mips_output_function_epilogue (FILE *fil mips_end_function_definition (fnname); } +/* Emit an optimisation barrier for accesses to the current frame. */ + +static void +mips_frame_barrier (void) +{ + emit_clobber (gen_frame_mem (BLKmode, stack_pointer_rtx)); +} + /* Save register REG to MEM. Make the instruction frame-related. */ static void @@ -10035,6 +10043,7 @@ mips_expand_prologue (void) insn = mips16e_build_save_restore (false, &mask, &offset, nargs, step1); RTX_FRAME_RELATED_P (emit_insn (insn)) = 1; + mips_frame_barrier (); size -= step1; /* Check if we need to save other registers. */ @@ -10075,6 +10084,7 @@ mips_expand_prologue (void) insn = gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (-step1)); RTX_FRAME_RELATED_P (emit_insn (insn)) = 1; + mips_frame_barrier (); size -= step1; /* Start at the uppermost location for saving. */ @@ -10135,6 +10145,7 @@ mips_expand_prologue (void) stack_pointer_rtx, GEN_INT (-step1)); RTX_FRAME_RELATED_P (emit_insn (insn)) = 1; + mips_frame_barrier (); size -= step1; } mips_for_each_saved_acc (size, mips_save_reg); @@ -10175,6 +10186,7 @@ mips_expand_prologue (void) (gen_rtx_SET (VOIDmode, stack_pointer_rtx, plus_constant (stack_pointer_rtx, -size))); } + mips_frame_barrier (); } /* Set up the frame pointer, if we're using one. */ @@ -10315,6 +10327,35 @@ mips_restore_reg (rtx reg, rtx mem) mips_epilogue.cfa_restore_sp_offset); } +/* Emit code to set the stack pointer to BASE + OFFSET, given that + BASE + OFFSET is NEW_FRAME_SIZE bytes below the top of the frame. + BASE, if not the stack pointer, is available as a temporary. */ + +static void +mips_deallocate_stack (rtx base, rtx offset, HOST_WIDE_INT new_frame_size) +{ + if (base == stack_pointer_rtx && offset == const0_rtx) + return; + + mips_frame_barrier (); + if (offset == const0_rtx) + { + emit_move_insn (stack_pointer_rtx, base); + mips_epilogue_set_cfa (stack_pointer_rtx, new_frame_size); + } + else if (TARGET_MIPS16 && base != stack_pointer_rtx) + { + emit_insn (gen_add3_insn (base, base, offset)); + mips_epilogue_set_cfa (base, new_frame_size); + emit_move_insn (stack_pointer_rtx, base); + } + else + { + emit_insn (gen_add3_insn (stack_pointer_rtx, base, offset)); + mips_epilogue_set_cfa (stack_pointer_rtx, new_frame_size); + } +} + /* Emit any instructions needed before a return. */ void @@ -10341,7 +10382,7 @@ mips_expand_epilogue (bool sibcall_p) { const struct mips_frame_info *frame; HOST_WIDE_INT step1, step2; - rtx base, target, insn; + rtx base, adjust, insn; if (!sibcall_p && mips_can_use_return_insn ()) { @@ -10384,31 +10425,14 @@ mips_expand_epilogue (bool sibcall_p) step1 -= step2; } - /* Set TARGET to BASE + STEP1. */ - target = base; - if (step1 > 0) - { - rtx adjust; - - /* Get an rtx for STEP1 that we can add to BASE. */ - adjust = GEN_INT (step1); - if (!SMALL_OPERAND (step1)) - { - mips_emit_move (MIPS_EPILOGUE_TEMP (Pmode), adjust); - adjust = MIPS_EPILOGUE_TEMP (Pmode); - } - - /* Normal mode code can copy the result straight into $sp. */ - if (!TARGET_MIPS16) - target = stack_pointer_rtx; - - emit_insn (gen_add3_insn (target, base, adjust)); - mips_epilogue_set_cfa (target, step2); + /* Get an rtx for STEP1 that we can add to BASE. */ + adjust = GEN_INT (step1); + if (!SMALL_OPERAND (step1)) + { + mips_emit_move (MIPS_EPILOGUE_TEMP (Pmode), adjust); + adjust = MIPS_EPILOGUE_TEMP (Pmode); } - - /* Copy TARGET into the stack pointer. */ - if (target != stack_pointer_rtx) - mips_emit_move (stack_pointer_rtx, target); + mips_deallocate_stack (base, adjust, step2); /* If we're using addressing macros, $gp is implicitly used by all SYMBOL_REFs. We must emit a blockage insn before restoring $gp @@ -10437,6 +10461,7 @@ mips_expand_epilogue (bool sibcall_p) /* Restore the remaining registers and deallocate the final bit of the frame. */ + mips_frame_barrier (); emit_insn (restore); mips_epilogue_set_cfa (stack_pointer_rtx, 0); } @@ -10473,13 +10498,8 @@ mips_expand_epilogue (bool sibcall_p) offset -= UNITS_PER_WORD; /* If we don't use shoadow register set, we need to update SP. */ - if (!cfun->machine->use_shadow_register_set_p && step2 > 0) - { - emit_insn (gen_add3_insn (stack_pointer_rtx, - stack_pointer_rtx, - GEN_INT (step2))); - mips_epilogue_set_cfa (stack_pointer_rtx, 0); - } + if (!cfun->machine->use_shadow_register_set_p) + mips_deallocate_stack (stack_pointer_rtx, GEN_INT (step2), 0); else /* The choice of position is somewhat arbitrary in this case. */ mips_epilogue_emit_cfa_restores (); @@ -10489,16 +10509,8 @@ mips_expand_epilogue (bool sibcall_p) gen_rtx_REG (SImode, K0_REG_NUM))); } else - { - /* Deallocate the final bit of the frame. */ - if (step2 > 0) - { - emit_insn (gen_add3_insn (stack_pointer_rtx, - stack_pointer_rtx, - GEN_INT (step2))); - mips_epilogue_set_cfa (stack_pointer_rtx, 0); - } - } + /* Deallocate the final bit of the frame. */ + mips_deallocate_stack (stack_pointer_rtx, GEN_INT (step2), 0); } gcc_assert (!mips_epilogue.cfa_restores); Index: gcc/testsuite/gcc.target/mips/stack-1.c =================================================================== --- /dev/null 2011-10-02 10:31:49.966695399 +0100 +++ gcc/testsuite/gcc.target/mips/stack-1.c 2011-10-01 11:38:30.000000000 +0100 @@ -0,0 +1,11 @@ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler "addiu\t(\\\$sp,)?\\\$sp,\[1-9\]" } } */ +/* { dg-final { scan-assembler "\tlw\t" } } */ +/* { dg-final { scan-assembler-not "addiu\t(\\\$sp,)?\\\$sp,\[1-9\].*\tlw\t" } } */ + +int foo (int y) +{ + volatile int a = y; + volatile int *volatile b = &a; + return *b; +}