From patchwork Wed Sep 7 10:28:30 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bernd Schmidt X-Patchwork-Id: 113734 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 F31EAB6F90 for ; Wed, 7 Sep 2011 20:30:54 +1000 (EST) Received: (qmail 10145 invoked by alias); 7 Sep 2011 10:30:51 -0000 Received: (qmail 10134 invoked by uid 22791); 7 Sep 2011 10:30:48 -0000 X-SWARE-Spam-Status: No, hits=1.1 required=5.0 tests=AWL, BAYES_00, BOTNET, RDNS_NONE X-Spam-Check-By: sourceware.org Received: from Unknown (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 07 Sep 2011 10:30:34 +0000 Received: (qmail 19785 invoked from network); 7 Sep 2011 10:30:32 -0000 Received: from unknown (HELO ?84.152.220.73?) (bernds@127.0.0.2) by mail.codesourcery.com with ESMTPA; 7 Sep 2011 10:30:32 -0000 Message-ID: <4E67474E.1070106@codesourcery.com> Date: Wed, 07 Sep 2011 12:28:30 +0200 From: Bernd Schmidt User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.20) Gecko/20110905 Lightning/1.0b3pre Thunderbird/3.1.12 MIME-Version: 1.0 To: Richard Henderson , GCC Patches , richard.sandiford@linaro.org Subject: Re: Add unwind information to mips epilogues References: <4E5E6E6D.8050905@codesourcery.com> <87zkipl8uv.fsf@firetop.home> <4E642AF3.2020706@redhat.com> <4E6593EF.6000101@redhat.com> In-Reply-To: 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 Here's a new version, which adds support for mips16 and tries to avoid the window with the frame pointer restore. Testing mips16 is problematic, all the execute tests fail before and after - I interpret one of your earlier mails to say that this is expected. There are no new compilation failures with this patch, but incorrect earlier versions triggered a few, indicating that the testing is at least somewhat useful. I get the following output for restore insns: move $sp,$17 restore 8,$16,$17 $LCFI2 = . .cfi_remember_state .cfi_restore 16 .cfi_restore 17 .cfi_def_cfa 29, 0 which I think is correct. Question for Richard H.: What is this actually good for, other than presenting consistent information to dwarf2cfi? Do we actually expect code to unwind through the middle of an epilogue? Bernd * config/mips/mips.c (cfa_restores, cfa_sp_offset): New static variables. (mips16e_save_restore_reg): Add to cfa_restores. (mips_restore_reg): Add to cfa_restores, and add a REG_CFA_DEF_CFA note to insns restoring the frame pointer. (mips_expand_epilogue): Initialize the new variables. Annotate RTL to ensure dwarf2cfi sees the effects of the epilogue. Generate a simple_return only if the return address is in r31. Index: gcc/config/mips/mips.c =================================================================== --- gcc/config/mips/mips.c (revision 178135) +++ gcc/config/mips/mips.c (working copy) @@ -501,6 +501,11 @@ int sdb_label_count; int mips_dbx_regno[FIRST_PSEUDO_REGISTER]; int mips_dwarf_regno[FIRST_PSEUDO_REGISTER]; +/* Used to collect REG_CFA notes during epilogue generation. */ +static rtx cfa_restores = NULL_RTX; +/* Used to produce REG_CFA_DEF_CFA notes during epilogue generation. */ +static HOST_WIDE_INT cfa_sp_offset; + /* The nesting depth of the PRINT_OPERAND '%(', '%<' and '%[' constructs. */ struct mips_asm_switch mips_noreorder = { "reorder", 0 }; struct mips_asm_switch mips_nomacro = { "macro", 0 }; @@ -8371,8 +8376,8 @@ mips16e_collect_argument_saves (void) } /* Return a move between register REGNO and memory location SP + OFFSET. - Make the move a load if RESTORE_P, otherwise make it a frame-related - store. */ + Make the move a load and update cfa_restores if RESTORE_P, otherwise + make it a frame-related store. */ static rtx mips16e_save_restore_reg (bool restore_p, HOST_WIDE_INT offset, @@ -8382,6 +8387,9 @@ mips16e_save_restore_reg (bool restore_p mem = gen_frame_mem (SImode, plus_constant (stack_pointer_rtx, offset)); reg = gen_rtx_REG (SImode, regno); + if (restore_p) + cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores); + return (restore_p ? gen_rtx_SET (VOIDmode, reg, mem) : mips_frame_set (mem, reg)); @@ -10227,17 +10236,30 @@ mips_expand_prologue (void) emit_insn (gen_blockage ()); } -/* Emit instructions to restore register REG from slot MEM. */ +/* Emit instructions to restore register REG from slot MEM. Also update + the cfa_restores list. */ static void mips_restore_reg (rtx reg, rtx mem) { + rtx orig_reg = reg; + rtx last; + /* There's no MIPS16 instruction to load $31 directly. Load into $7 instead and adjust the return insn appropriately. */ if (TARGET_MIPS16 && REGNO (reg) == RETURN_ADDR_REGNUM) reg = gen_rtx_REG (GET_MODE (reg), GP_REG_FIRST + 7); mips_emit_save_slot_move (reg, mem, MIPS_EPILOGUE_TEMP (GET_MODE (reg))); + if (reg == orig_reg) + cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores); + + if (!frame_pointer_needed || REGNO (reg) != HARD_FRAME_POINTER_REGNUM) + return; + last = get_last_insn (); + add_reg_note (last, REG_CFA_DEF_CFA, plus_constant (stack_pointer_rtx, + cfa_sp_offset)); + RTX_FRAME_RELATED_P (last) = 1; } /* Emit any instructions needed before a return. */ @@ -10268,6 +10290,8 @@ mips_expand_epilogue (bool sibcall_p) HOST_WIDE_INT step1, step2; rtx base, target, insn; + cfa_restores = NULL_RTX; + if (!sibcall_p && mips_can_use_return_insn ()) { emit_jump_insn (gen_return ()); @@ -10306,6 +10330,8 @@ mips_expand_epilogue (bool sibcall_p) step1 -= step2; } + cfa_sp_offset = step2; + /* Set TARGET to BASE + STEP1. */ target = base; if (step1 > 0) @@ -10324,12 +10350,26 @@ mips_expand_epilogue (bool sibcall_p) if (!TARGET_MIPS16) target = stack_pointer_rtx; - emit_insn (gen_add3_insn (target, base, adjust)); + insn = emit_insn (gen_add3_insn (target, base, adjust)); + if (!frame_pointer_needed && target == stack_pointer_rtx) + { + RTX_FRAME_RELATED_P (insn) = 1; + add_reg_note (insn, REG_CFA_DEF_CFA, + plus_constant (stack_pointer_rtx, step2)); + } } /* Copy TARGET into the stack pointer. */ if (target != stack_pointer_rtx) - mips_emit_move (stack_pointer_rtx, target); + { + insn = mips_emit_move (stack_pointer_rtx, target); + if (!frame_pointer_needed) + { + add_reg_note (insn, REG_CFA_DEF_CFA, + plus_constant (stack_pointer_rtx, step2)); + RTX_FRAME_RELATED_P (insn) = 1; + } + } /* If we're using addressing macros, $gp is implicitly used by all SYMBOL_REFs. We must emit a blockage insn before restoring $gp @@ -10357,7 +10397,10 @@ mips_expand_epilogue (bool sibcall_p) /* Restore the remaining registers and deallocate the final bit of the frame. */ - emit_insn (restore); + restore = emit_insn (restore); + REG_NOTES (restore) = cfa_restores; + RTX_FRAME_RELATED_P (restore) = 1; + add_reg_note (restore, REG_CFA_DEF_CFA, stack_pointer_rtx); } else { @@ -10393,9 +10436,14 @@ mips_expand_epilogue (bool sibcall_p) /* 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))); + { + insn = emit_insn (gen_add3_insn (stack_pointer_rtx, + stack_pointer_rtx, + GEN_INT (step2))); + REG_NOTES (insn) = cfa_restores; + RTX_FRAME_RELATED_P (insn) = 1; + add_reg_note (insn, REG_CFA_DEF_CFA, stack_pointer_rtx); + } /* Move to COP0 Status. */ emit_insn (gen_cop0_move (gen_rtx_REG (SImode, COP0_STATUS_REG_NUM), @@ -10405,9 +10453,14 @@ mips_expand_epilogue (bool sibcall_p) { /* Deallocate the final bit of the frame. */ if (step2 > 0) - emit_insn (gen_add3_insn (stack_pointer_rtx, - stack_pointer_rtx, - GEN_INT (step2))); + { + insn = emit_insn (gen_add3_insn (stack_pointer_rtx, + stack_pointer_rtx, + GEN_INT (step2))); + REG_NOTES (insn) = cfa_restores; + RTX_FRAME_RELATED_P (insn) = 1; + add_reg_note (insn, REG_CFA_DEF_CFA, stack_pointer_rtx); + } } } @@ -10442,7 +10495,7 @@ mips_expand_epilogue (bool sibcall_p) } else { - unsigned int regno; + rtx pat; /* When generating MIPS16 code, the normal mips_for_each_saved_gpr_and_fpr path will restore the return @@ -10450,11 +10503,16 @@ mips_expand_epilogue (bool sibcall_p) if (TARGET_MIPS16 && !GENERATE_MIPS16E_SAVE_RESTORE && BITSET_P (frame->mask, RETURN_ADDR_REGNUM)) - regno = GP_REG_FIRST + 7; + { + rtx reg = gen_rtx_REG (Pmode, GP_REG_FIRST + 7); + pat = gen_return_internal (reg); + } else - regno = RETURN_ADDR_REGNUM; - emit_jump_insn (gen_simple_return_internal (gen_rtx_REG (Pmode, - regno))); + { + rtx reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); + pat = gen_simple_return_internal (reg); + } + emit_jump_insn (pat); } }