From patchwork Mon May 21 02:48:05 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 160308 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 81684B6F77 for ; Mon, 21 May 2012 12:48:32 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1338173313; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Received:Date:From:To:Subject:Message-ID: Mail-Followup-To:References:MIME-Version:Content-Type: Content-Disposition:In-Reply-To:User-Agent:Mailing-List: Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:Sender:Delivered-To; bh=hA/bJXU8xKLa5riM4LTxJNp/SNo=; b=FrDhCKhc8lDcizXplV6LJ7BgGYta8PPxjMYjgg0m/aFS3indcLoy3tkJm4pCXb 8CwfDAm2cK7aUJHK1SqHWBf0BSNDZ9fhSlPa99fK0GvT0rl1DmcGqYTfreeZHMu6 JAEs+fOOXHXNh5R/dRn2nPin3+liNTAeihIEBubBHruFU= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:Received:Date:From:To:Subject:Message-ID:Mail-Followup-To:References:MIME-Version:Content-Type:Content-Disposition:In-Reply-To:User-Agent:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=G9/qnTW+k6uiw7KbiFEhAfMChPR+16NFXHjAIUv0Yskw/DG/elVSkA2F4CIbEN rT11q3XVi+/9dabDXHnwrUZqqFbnWe4sYZb0mbXWDC9VPsd4iiKaAEa40bhhqbxU XdA/Y/45yJWfiT6tUUitrL279IS5t/N04lZjpeRfZpB+s=; Received: (qmail 7641 invoked by alias); 21 May 2012 02:48:28 -0000 Received: (qmail 7632 invoked by uid 22791); 21 May 2012 02:48:26 -0000 X-SWARE-Spam-Status: No, hits=-4.3 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, KHOP_RCVD_TRUST, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_YE X-Spam-Check-By: sourceware.org Received: from mail-pb0-f47.google.com (HELO mail-pb0-f47.google.com) (209.85.160.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 21 May 2012 02:48:12 +0000 Received: by pbbrq2 with SMTP id rq2so6179902pbb.20 for ; Sun, 20 May 2012 19:48:11 -0700 (PDT) Received: by 10.68.232.161 with SMTP id tp1mr63959858pbc.44.1337568491739; Sun, 20 May 2012 19:48:11 -0700 (PDT) Received: from bubble.grove.modra.org ([115.187.252.19]) by mx.google.com with ESMTPS id qr2sm21476007pbb.19.2012.05.20.19.48.08 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 20 May 2012 19:48:11 -0700 (PDT) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id 308D9EA1FF9; Mon, 21 May 2012 12:18:05 +0930 (CST) Date: Mon, 21 May 2012 12:18:05 +0930 From: Alan Modra To: David Edelsohn , gcc-patches@gcc.gnu.org Subject: [RS6000] save/restore reg tidy Message-ID: <20120521024804.GD3285@bubble.grove.modra.org> Mail-Followup-To: David Edelsohn , gcc-patches@gcc.gnu.org References: <37BF2514-EA22-4DE4-8B77-53A6B63DE48C@adacore.com> <20120508103239.GO17181@bubble.grove.modra.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20120508103239.GO17181@bubble.grove.modra.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes 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 On Tue, May 08, 2012 at 08:02:39PM +0930, Alan Modra wrote: > I also make use of gen_frame_store and siblings that I invented for > generating the eh info, elsewhere in rs6000.c where doing so is > blindingly obvious. We could probably use them in other places too, > but I'll leave that for later. Like so. The part that isn't completely obvious is removing calls to emit_move_insn, which can transform the rtl (rs6000_emit_move). However, we're past reload, the insns emitted are always one set involving a hard reg and mem, and we don't want any addressing mode subsititions going on that avoid rs6000_emit_prologue tracking of r0, r11 and r12 usage. This patch also fixes a couple of places that call df_regs_ever_live_p without checking call_used_regs to test for global asm regs. Not serious bugs as they just result in larger stack frames. Bootstrapped and regression tested powerpc-linux. OK to apply? * config/rs6000/rs6000.c (save_reg_p): New function. (first_reg_to_save, first_fp_reg_to_save): Use it here. (first_altivec_reg_to_save, restore_saved_cr): Likewise. (emit_frame_save): Use gen_frame_store. (gen_frame_mem_offset): Correct SPE condition requiring reg+reg. (rs6000_emit_prologue): Use save_reg_p. Use gen_frame_store for vrsave and toc. (rs6000_emit_epilogue): Use save_reg_p. Use gen_frame_load for vrsave, toc, gp and fp restores. Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 187699) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -17236,6 +17079,12 @@ /* This page contains routines that are used to determine what the function prologue and epilogue code will do and write them out. */ +static inline bool +save_reg_p (int r) +{ + return !call_used_regs[r] && df_regs_ever_live_p (r); +} + /* Return the first fixed-point register that is required to be saved. 32 if none. */ @@ -17246,14 +17095,16 @@ /* Find lowest numbered live register. */ for (first_reg = 13; first_reg <= 31; first_reg++) - if (df_regs_ever_live_p (first_reg) - && (! call_used_regs[first_reg] - || (first_reg == RS6000_PIC_OFFSET_TABLE_REGNUM - && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0) - || (DEFAULT_ABI == ABI_DARWIN && flag_pic) - || (TARGET_TOC && TARGET_MINIMAL_TOC))))) + if (save_reg_p (first_reg)) break; + if (first_reg > RS6000_PIC_OFFSET_TABLE_REGNUM + && ((DEFAULT_ABI == ABI_V4 && flag_pic != 0) + || (DEFAULT_ABI == ABI_DARWIN && flag_pic) + || (TARGET_TOC && TARGET_MINIMAL_TOC)) + && df_regs_ever_live_p (RS6000_PIC_OFFSET_TABLE_REGNUM)) + first_reg = RS6000_PIC_OFFSET_TABLE_REGNUM; + #if TARGET_MACHO if (flag_pic && crtl->uses_pic_offset_table @@ -17273,7 +17124,7 @@ /* Find lowest numbered live register. */ for (first_reg = 14 + 32; first_reg <= 63; first_reg++) - if (df_regs_ever_live_p (first_reg)) + if (save_reg_p (first_reg)) break; return first_reg; @@ -17299,7 +17150,7 @@ /* Find lowest numbered live register. */ for (i = FIRST_ALTIVEC_REGNO + 20; i <= LAST_ALTIVEC_REGNO; ++i) - if (df_regs_ever_live_p (i)) + if (save_reg_p (i)) break; return i; @@ -18995,7 +18904,7 @@ emit_frame_save (rtx frame_reg, enum machine_mode mode, unsigned int regno, int offset, HOST_WIDE_INT frame_reg_to_sp) { - rtx reg, insn, mem, addr; + rtx reg, insn; /* Some cases that need register indexed addressing. */ gcc_checking_assert (!((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode)) @@ -19006,9 +18915,7 @@ && !SPE_CONST_OFFSET_OK (offset)))); reg = gen_rtx_REG (mode, regno); - addr = gen_rtx_PLUS (Pmode, frame_reg, GEN_INT (offset)); - mem = gen_frame_mem (mode, addr); - insn = emit_move_insn (mem, reg); + insn = emit_insn (gen_frame_store (reg, frame_reg, offset)); return rs6000_frame_related (insn, frame_reg, frame_reg_to_sp, NULL_RTX, NULL_RTX); } @@ -19023,7 +18930,7 @@ int_rtx = GEN_INT (offset); - if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode)) + if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode) && !SPE_CONST_OFFSET_OK (offset)) || (TARGET_E500_DOUBLE && mode == DFmode)) { offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH); @@ -19652,8 +19559,7 @@ { int i; for (i = 0; i < 64 - info->first_fp_reg_save; i++) - if (df_regs_ever_live_p (info->first_fp_reg_save + i) - && ! call_used_regs[info->first_fp_reg_save + i]) + if (save_reg_p (info->first_fp_reg_save + i)) emit_frame_save (frame_reg_rtx, (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT ? DFmode : SFmode), @@ -20103,7 +20009,7 @@ && TARGET_ALTIVEC_VRSAVE && info->vrsave_mask != 0) { - rtx reg, mem, vrsave; + rtx reg, vrsave; int offset; int save_regno; @@ -20130,10 +20036,7 @@ /* Save VRSAVE. */ offset = info->vrsave_save_offset + frame_off; - mem = gen_frame_mem (SImode, - gen_rtx_PLUS (Pmode, frame_reg_rtx, - GEN_INT (offset))); - insn = emit_move_insn (mem, reg); + insn = emit_insn (gen_frame_store (reg, frame_reg_rtx, offset)); /* Include the registers in the mask. */ emit_insn (gen_iorsi3 (reg, reg, GEN_INT ((int) info->vrsave_mask))); @@ -20214,9 +20115,8 @@ linux-unwind.h frob_update_context. */ if (rs6000_save_toc_in_prologue_p ()) { - rtx addr = gen_rtx_PLUS (Pmode, sp_reg_rtx, GEN_INT (5 * reg_size)); - rtx mem = gen_frame_mem (reg_mode, addr); - emit_move_insn (mem, gen_rtx_REG (reg_mode, TOC_REGNUM)); + rtx reg = gen_rtx_REG (reg_mode, TOC_REGNUM); + emit_insn (gen_frame_store (reg, sp_reg_rtx, 5 * reg_size)); } } @@ -20314,7 +20233,7 @@ if (using_mfcr_multiple) { for (i = 0; i < 8; i++) - if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i]) + if (save_reg_p (CR0_REGNO + i)) count++; gcc_assert (count); } @@ -20328,13 +20247,13 @@ ndx = 0; for (i = 0; i < 8; i++) - if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i]) + if (save_reg_p (CR0_REGNO + i)) { rtvec r = rtvec_alloc (2); RTVEC_ELT (r, 0) = reg; RTVEC_ELT (r, 1) = GEN_INT (1 << (7-i)); RTVEC_ELT (p, ndx) = - gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO+i), + gen_rtx_SET (VOIDmode, gen_rtx_REG (CCmode, CR0_REGNO + i), gen_rtx_UNSPEC (CCmode, r, UNSPEC_MOVESI_TO_CR)); ndx++; } @@ -20343,8 +20262,8 @@ } else for (i = 0; i < 8; i++) - if (df_regs_ever_live_p (CR0_REGNO+i) && ! call_used_regs[CR0_REGNO+i]) - emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode, CR0_REGNO+i), + if (save_reg_p (CR0_REGNO + i)) + emit_insn (gen_movsi_to_cr_one (gen_rtx_REG (CCmode, CR0_REGNO + i), reg)); if (!exit_func && (DEFAULT_ABI == ABI_V4 || flag_shrink_wrap)) @@ -20677,7 +20596,7 @@ || (DEFAULT_ABI != ABI_V4 && offset_below_red_zone_p (info->vrsave_save_offset)))) { - rtx addr, mem, reg; + rtx reg; if (frame_reg_rtx == sp_reg_rtx) { @@ -20692,11 +20611,9 @@ frame_reg_rtx = hard_frame_pointer_rtx; } - addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, - GEN_INT (info->vrsave_save_offset + frame_off)); - mem = gen_frame_mem (SImode, addr); reg = gen_rtx_REG (SImode, 12); - emit_move_insn (reg, mem); + emit_insn (gen_frame_load (reg, frame_reg_rtx, + info->vrsave_save_offset + frame_off)); emit_insn (generate_set_vrsave (reg, info, 1)); } @@ -20874,13 +20791,11 @@ && (DEFAULT_ABI == ABI_V4 || !offset_below_red_zone_p (info->vrsave_save_offset))) { - rtx addr, mem, reg; + rtx reg; - addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, - GEN_INT (info->vrsave_save_offset + frame_off)); - mem = gen_frame_mem (SImode, addr); reg = gen_rtx_REG (SImode, 12); - emit_move_insn (reg, mem); + emit_insn (gen_frame_load (reg, frame_reg_rtx, + info->vrsave_save_offset + frame_off)); emit_insn (generate_set_vrsave (reg, info, 1)); } @@ -20934,11 +20849,9 @@ if (TARGET_AIX) { - rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, - GEN_INT (frame_off + 5 * reg_size)); - rtx mem = gen_frame_mem (reg_mode, addr); - - emit_move_insn (gen_rtx_REG (reg_mode, 2), mem); + rtx reg = gen_rtx_REG (reg_mode, 2); + emit_insn (gen_frame_load (reg, frame_reg_rtx, + frame_off + 5 * reg_size)); } for (i = 0; ; ++i) @@ -20949,6 +20862,7 @@ if (regno == INVALID_REGNUM) break; + /* Note: possible use of r0 here to address SPE regs. */ mem = gen_frame_mem_offset (reg_mode, frame_reg_rtx, info->ehrd_offset + frame_off + reg_size * (int) i); @@ -21067,16 +20981,10 @@ { for (i = 0; i < 32 - info->first_gp_reg_save; i++) if (rs6000_reg_live_or_pic_offset_p (info->first_gp_reg_save + i)) - { - rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, - GEN_INT (info->gp_save_offset - + frame_off - + reg_size * i)); - rtx mem = gen_frame_mem (reg_mode, addr); - rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i); - - emit_move_insn (reg, mem); - } + emit_insn (gen_frame_load + (gen_rtx_REG (reg_mode, info->first_gp_reg_save + i), + frame_reg_rtx, + info->gp_save_offset + frame_off + reg_size * i)); } if (DEFAULT_ABI == ABI_V4 || flag_shrink_wrap) @@ -21139,21 +21047,13 @@ /* Restore fpr's if we need to do it without calling a function. */ if (restoring_FPRs_inline) for (i = 0; i < 64 - info->first_fp_reg_save; i++) - if ((df_regs_ever_live_p (info->first_fp_reg_save + i) - && !call_used_regs[info->first_fp_reg_save + i])) + if (save_reg_p (info->first_fp_reg_save + i)) { - rtx addr, mem, reg; - addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, - GEN_INT (info->fp_save_offset - + frame_off - + 8 * i)); - mem = gen_frame_mem ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT - ? DFmode : SFmode), addr); - reg = gen_rtx_REG ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT - ? DFmode : SFmode), - info->first_fp_reg_save + i); - - emit_move_insn (reg, mem); + rtx reg = gen_rtx_REG ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT + ? DFmode : SFmode), + info->first_fp_reg_save + i); + emit_insn (gen_frame_load (reg, frame_reg_rtx, + info->fp_save_offset + frame_off + 8 * i)); if (DEFAULT_ABI == ABI_V4 || flag_shrink_wrap) cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores); }