From patchwork Tue Apr 17 15:12:38 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 153229 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 52539B7005 for ; Wed, 18 Apr 2012 01:13:18 +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=1335280399; 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=f82dRY0v1vHGUYCqOPN1hT67P3w=; b=XO5Z3BJwKQKuGQl2jsRNZcVrm/8tiO7XKnzQwM/7HfBv+BBYEkVVT0qHbHSZxv I3MNdq+ciyYltRrXa+twC0XpoHRZHIw2PEEIidYD+nlpAy1TJMY5vdWbU6KVn37E ldS3TBIFohp9JHC2dRsKQyfiPye3kTwN0p2747yUAf8nA= 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=EqJplPFVv/7yiwT5tbwnTpAGQrFS/G61HT3N83Vz4n0ASSrX8IRanF1IDWzJhx 4AoJqOAGo9LkyJ1BnRvOsxaohvRfqab+Kvmf+JHrzjx0y7Zh3vDdCyUxu/Usw+KE rvnITMvRJTc5AzoEP33WvONW4nu2938S/tqPhb0b2EKes=; Received: (qmail 13438 invoked by alias); 17 Apr 2012 15:13:08 -0000 Received: (qmail 13415 invoked by uid 22791); 17 Apr 2012 15:13:04 -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-gx0-f175.google.com (HELO mail-gx0-f175.google.com) (209.85.161.175) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 17 Apr 2012 15:12:45 +0000 Received: by ggcy3 with SMTP id y3so3350675ggc.20 for ; Tue, 17 Apr 2012 08:12:44 -0700 (PDT) Received: by 10.50.88.168 with SMTP id bh8mr10060175igb.29.1334675564528; Tue, 17 Apr 2012 08:12:44 -0700 (PDT) Received: from bubble.grove.modra.org ([115.187.252.19]) by mx.google.com with ESMTPS id p5sm15829336igl.2.2012.04.17.08.12.42 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 17 Apr 2012 08:12:43 -0700 (PDT) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id 45AF1EA2E16; Wed, 18 Apr 2012 00:42:38 +0930 (CST) Date: Wed, 18 Apr 2012 00:42:38 +0930 From: Alan Modra To: gcc-patches@gcc.gnu.org, David Edelsohn Subject: PowerPC prologue and epilogue 2 Message-ID: <20120417151238.GG3218@bubble.grove.modra.org> Mail-Followup-To: gcc-patches@gcc.gnu.org, David Edelsohn References: <20120417150803.GF3218@bubble.grove.modra.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20120417150803.GF3218@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 This fixes a lot of confusion in rs6000_frame_related call arguments. At the time rs6000_frame_related first appeared, the prologue only used sp_reg_rtx (r1) or frame_ptr_rtx (r12) as frame_reg_rtx to access register save slots. If r12 was used, it was necessary to add a note that gave the equivalent offset relative to r1. Nowadays, r11 is used as frame_reg_rtx too, when abiv4 and saving regs out-of-line with a large frame. When that change was made the calls to rs6000_frame_related were not updated. So rs6000_frame_related won't replace r11 in register save rtl. As it happens this isn't a bug because when you look closely, out-of-line saves are disabled with a large frame! A fix for that will come later in this patch series. I also optimize rs6000_frame_related a little to save generating duplicate rtl. * config/rs6000/rs6000.c (rs6000_frame_related): Don't emit a REG_FRAME_RELATED_EXPR note when the instruction exactly matches the replacement. (emit_frame_save): Delete frame_ptr param. Rename total_size to frame_reg_to_sp. (rs6000_emit_prologue): Add sp_off. Update rs6000_frame_related and emit_frame_save calls. Cope with possibly missing note. diff -urp gcc-alan1/gcc/config/rs6000/rs6000.c gcc-alan2/gcc/config/rs6000/rs6000.c --- gcc-alan1/gcc/config/rs6000/rs6000.c 2012-04-16 11:57:37.282242636 +0930 +++ gcc-alan2/gcc/config/rs6000/rs6000.c 2012-04-16 11:58:01.501222208 +0930 @@ -18751,7 +18751,10 @@ output_probe_stack_range (rtx reg1, rtx with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2 is not NULL. It would be nice if dwarf2out_frame_debug_expr could deduce these equivalences by itself so it wasn't necessary to hold - its hand so much. */ + its hand so much. Don't be tempted to always supply d2_f_d_e with + the actual cfa register, ie. r31 when we are using a hard frame + pointer. That fails when saving regs off r1, and sched moves the + r31 setup past the reg saves. */ static rtx rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val, @@ -18759,6 +18762,25 @@ rs6000_frame_related (rtx insn, rtx reg, { rtx real, temp; + if (REGNO (reg) == 1 && reg2 == NULL_RTX) + { + /* No need for any replacement. Just set RTX_FRAME_RELATED_P. */ + int i; + + gcc_checking_assert (val == 0); + real = PATTERN (insn); + if (GET_CODE (real) == PARALLEL) + for (i = 0; i < XVECLEN (real, 0); i++) + if (GET_CODE (XVECEXP (real, 0, i)) == SET) + { + rtx set = XVECEXP (real, 0, i); + + RTX_FRAME_RELATED_P (set) = 1; + } + RTX_FRAME_RELATED_P (insn) = 1; + return insn; + } + /* copy_rtx will not make unique copies of registers, so we need to ensure we don't have unwanted sharing here. */ if (reg == reg2) @@ -18772,10 +18794,13 @@ rs6000_frame_related (rtx insn, rtx reg, if (reg2 != NULL_RTX) real = replace_rtx (real, reg2, rreg); - real = replace_rtx (real, reg, - gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, - STACK_POINTER_REGNUM), - GEN_INT (val))); + if (REGNO (reg) == 1) + gcc_checking_assert (val == 0); + else + real = replace_rtx (real, reg, + gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, + STACK_POINTER_REGNUM), + GEN_INT (val))); /* We expect that 'real' is either a SET or a PARALLEL containing SETs (and possibly other stuff). In a PARALLEL, all the SETs @@ -18893,8 +18918,8 @@ generate_set_vrsave (rtx reg, rs6000_sta Save REGNO into [FRAME_REG + OFFSET] in mode MODE. */ static rtx -emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode, - unsigned int regno, int offset, HOST_WIDE_INT total_size) +emit_frame_save (rtx frame_reg, enum machine_mode mode, + unsigned int regno, int offset, HOST_WIDE_INT frame_reg_to_sp) { rtx reg, offset_rtx, insn, mem, addr, int_rtx; rtx replacea, replaceb; @@ -18930,7 +18955,8 @@ emit_frame_save (rtx frame_reg, rtx fram insn = emit_move_insn (mem, reg); - return rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb); + return rs6000_frame_related (insn, frame_reg, frame_reg_to_sp, + replacea, replaceb); } /* Emit an offset memory reference suitable for a frame store, while @@ -19295,7 +19321,9 @@ rs6000_emit_prologue (void) int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE && df_regs_ever_live_p (STATIC_CHAIN_REGNUM) && call_used_regs[STATIC_CHAIN_REGNUM]); + /* Offset to top of frame for frame_reg and sp respectively. */ HOST_WIDE_INT frame_off = 0; + HOST_WIDE_INT sp_off = 0; if (flag_stack_usage_info) current_function_static_stack_size = info->total_size; @@ -19436,9 +19464,9 @@ rs6000_emit_prologue (void) } insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); - rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, + rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off, treg, GEN_INT (-info->total_size)); - frame_off = info->total_size; + sp_off = frame_off = info->total_size; } strategy = info->savres_strategy; @@ -19483,6 +19511,7 @@ rs6000_emit_prologue (void) frame_off = info->total_size; } rs6000_emit_allocate_stack (info->total_size, copy_reg); + sp_off = info->total_size; if (frame_reg_rtx != sp_reg_rtx) rs6000_emit_stack_tie (frame_reg_rtx, false); } @@ -19507,7 +19536,7 @@ rs6000_emit_prologue (void) __builtin_return_address. */ insn = emit_move_insn (mem, reg); - rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, + rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off, NULL_RTX, NULL_RTX); } } @@ -19543,12 +19572,12 @@ rs6000_emit_prologue (void) 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]) - emit_frame_save (frame_reg_rtx, frame_ptr_rtx, + emit_frame_save (frame_reg_rtx, (TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT ? DFmode : SFmode), info->first_fp_reg_save + i, info->fp_save_offset + frame_off + 8 * i, - info->total_size); + sp_off - frame_off); } else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64) { @@ -19559,7 +19588,7 @@ rs6000_emit_prologue (void) /*lr=*/((strategy & SAVE_NOINLINE_FPRS_SAVES_LR) != 0)); - rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, + rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off, NULL_RTX, NULL_RTX); } @@ -19587,7 +19616,7 @@ rs6000_emit_prologue (void) if (spe_regs_addressable) { spe_save_area_ptr = frame_reg_rtx; - save_ptr_to_sp = info->total_size - frame_off; + save_ptr_to_sp = sp_off - frame_off; spe_offset = info->spe_gp_save_offset + frame_off; } else @@ -19602,7 +19631,7 @@ rs6000_emit_prologue (void) - (FIRST_SAVRES_REGISTER + 1)); offset = info->spe_gp_save_offset + frame_off - ool_adjust; spe_save_area_ptr = gen_rtx_REG (Pmode, 11); - save_ptr_to_sp = info->total_size - frame_off + offset; + save_ptr_to_sp = sp_off - frame_off + offset; spe_offset = 0; if (using_static_chain_p) @@ -19695,7 +19724,7 @@ rs6000_emit_prologue (void) /*lr=*/((strategy & SAVE_NOINLINE_GPRS_SAVES_LR) != 0)); - rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, + rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off, NULL_RTX, NULL_RTX); } else if (!WORLD_SAVE_P (info) && using_store_multiple) @@ -19716,7 +19745,7 @@ rs6000_emit_prologue (void) RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg); } insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p)); - rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, + rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off, NULL_RTX, NULL_RTX); } else if (!WORLD_SAVE_P (info)) @@ -19735,7 +19764,7 @@ rs6000_emit_prologue (void) mem = gen_frame_mem (reg_mode, addr); insn = emit_move_insn (mem, reg); - rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, + rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off, NULL_RTX, NULL_RTX); } } @@ -19752,9 +19781,9 @@ rs6000_emit_prologue (void) if (regno == INVALID_REGNUM) break; - emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno, + emit_frame_save (frame_reg_rtx, reg_mode, regno, info->ehrd_offset + frame_off + reg_size * (int) i, - info->total_size); + sp_off - frame_off); } } @@ -19797,9 +19826,9 @@ rs6000_emit_prologue (void) JUMP_LABEL (jump) = toc_save_done; LABEL_NUSES (toc_save_done) += 1; - save_insn = emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, + save_insn = emit_frame_save (frame_reg_rtx, reg_mode, TOC_REGNUM, frame_off + 5 * reg_size, - info->total_size); + sp_off - frame_off); emit_label (toc_save_done); @@ -19812,8 +19841,11 @@ rs6000_emit_prologue (void) code that minimizes the number of DW_CFA_advance opcodes better freedom in placing the annotations. */ note = find_reg_note (save_insn, REG_FRAME_RELATED_EXPR, NULL); - gcc_assert (note); - remove_note (save_insn, note); + if (note) + remove_note (save_insn, note); + else + note = alloc_reg_note (REG_FRAME_RELATED_EXPR, + copy_rtx (PATTERN (save_insn)), NULL_RTX); RTX_FRAME_RELATED_P (save_insn) = 0; join_insn = emit_insn (gen_blockage ()); @@ -19847,7 +19879,7 @@ rs6000_emit_prologue (void) } insn = emit_move_insn (mem, cr_save_rtx); - rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, + rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off, NULL_RTX, NULL_RTX); } @@ -19869,6 +19901,7 @@ rs6000_emit_prologue (void) else frame_off = info->total_size; rs6000_emit_allocate_stack (info->total_size, copy_reg); + sp_off = info->total_size; if (frame_reg_rtx != sp_reg_rtx) rs6000_emit_stack_tie (frame_reg_rtx, false); } @@ -19909,7 +19942,7 @@ rs6000_emit_prologue (void) insn = emit_move_insn (mem, savereg); - rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, + rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off, areg, GEN_INT (offset)); } }