From patchwork Tue Apr 3 08:40:21 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 150340 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 EE857B6EEB for ; Tue, 3 Apr 2012 18:40:47 +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=1334047248; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Received:Date:From:To:Cc:Subject:Message-ID: Mail-Followup-To:MIME-Version:Content-Type:Content-Disposition: User-Agent:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=riBc5ha tLT9QcUUpV+6q54ISkCQ=; b=cr3X7wpzbKvl0zLtqnd/xpW4KxCLILWBy4xghNx WB9vj+AoQxVdABNqwA/dqwOkmI881V79u0vnPCoXyTSXCEzh464cHgOIKvkUwZ3H dP6O6E4fONs2ix0zFH0UfxphcqnMQYOrBROQd/fcEqEDSB69iX6Vr+lr2rB24IRO 9a20= 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:Cc:Subject:Message-ID:Mail-Followup-To:MIME-Version:Content-Type:Content-Disposition:User-Agent:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=TjmoPbVqPVZfqUazqI/EY1b3Z2mW2b/7D4+e6C4btzx9Im1I+z+nXTfWU6Kiv+ Eex2VgRgRbE+odxqMRwjxt5sn6I1dcZTbkatQiDVqLjmT1nDyFkBFB9RK38MrKrp y/tw+7e+ZtU9UhPOBTuO/0QA/4eQ1lnYW+vds7wgk/qv4=; Received: (qmail 9870 invoked by alias); 3 Apr 2012 08:40:44 -0000 Received: (qmail 9859 invoked by uid 22791); 3 Apr 2012 08:40:42 -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; Tue, 03 Apr 2012 08:40:29 +0000 Received: by pbcum15 with SMTP id um15so5078614pbc.20 for ; Tue, 03 Apr 2012 01:40:28 -0700 (PDT) Received: by 10.68.225.39 with SMTP id rh7mr27390240pbc.104.1333442428388; Tue, 03 Apr 2012 01:40:28 -0700 (PDT) Received: from bubble.grove.modra.org ([115.187.252.19]) by mx.google.com with ESMTPS id mg3sm9841458pbc.51.2012.04.03.01.40.26 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 03 Apr 2012 01:40:27 -0700 (PDT) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id D7C38EA2D93; Tue, 3 Apr 2012 18:10:21 +0930 (CST) Date: Tue, 3 Apr 2012 18:10:21 +0930 From: Alan Modra To: gcc-patches@gcc.gnu.org Cc: David Edelsohn Subject: [RS6000] Stack tie fix. Message-ID: <20120403084021.GK12569@bubble.grove.modra.org> Mail-Followup-To: gcc-patches@gcc.gnu.org, David Edelsohn MIME-Version: 1.0 Content-Disposition: inline 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 patch merges the rs6000 stack_tie and frame_tie rtl, so that we now should use a tie insn that mentions all base regs involved in register saves and restores. That should avoid any alias analysis problems eg. http://gcc.gnu.org/ml/gcc-patches/2011-11/msg01156.html. I chose to put the regs of interest on the destination of the fake set, rather than in the source as is currently done, because I figure that relying on the compiler to not reorder reads is fragile. Here's an example of the new stack tie: (set (mem:BLK (unspec:SI [(reg:SI 1) (reg:SI 12)] UNSPEC_TIE)) (const_int 0)) Some notes: - I tried putting the mem on both source and destination of the set, but that runs afoul of rtl dead code elimination. - The rs6000_emit_epilogue places that called gen_frame_tie and gen_stack_tie both used alias set 0 mems. I believe this was unnecessarily restrictive. - CODE_FOR_stack_tie is mentioned in rs6000.c but not CODE_FOR_frame_tie. Removing frame_tie fixes this sched bug too. Bootstrapped and regression tested powerpc-linux with usual -O2 BOOT_CFLAGS and also -Os, and testcases from pr44199, pr30282, pr52828, the url above and http://gcc.gnu.org/ml/gcc/2011-03/msg00123.html examined for sanity. OK to apply? PR target/52828 * config/rs6000/rs6000.c (rs6000_emit_stack_tie): Rewrite with tie regs on destination of set. Delete forward declaration. (rs6000_emit_stack_reset): Update rs6000_emit_stack_tie calls. (rs6000_emit_prologue): Likewise. (rs6000_emit_epilogue): Likewise. Use in place of gen_frame_tie and gen_stack_tie. * config/rs6000/predicates.md (tie_operand): New. * config/rs6000/rs6000.md (restore_stack_block): Generate new stack tie rtl. (restore_stack_nonlocal): Likewise. (stack_tie): Update. (frame_tie): Delete. Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 185830) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -925,7 +925,6 @@ static const char *rs6000_invalid_within_doloop (c static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool); static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool); static rtx rs6000_generate_compare (rtx, enum machine_mode); -static void rs6000_emit_stack_tie (void); static bool spe_func_has_64bit_regs_p (void); static rtx gen_frame_mem_offset (enum machine_mode, rtx, int); static unsigned rs6000_hash_constant (rtx); @@ -18517,12 +18516,28 @@ rs6000_aix_asm_output_dwarf_table_ref (char * fram and the change to the stack pointer. */ static void -rs6000_emit_stack_tie (void) +rs6000_emit_stack_tie (rtx fp, bool hard_frame_needed) { - rtx mem = gen_frame_mem (BLKmode, - gen_rtx_REG (Pmode, STACK_POINTER_REGNUM)); + rtx u; + rtvec p; + int i; - emit_insn (gen_stack_tie (mem)); + if (REGNO (fp) == STACK_POINTER_REGNUM + || (hard_frame_needed + && REGNO (fp) == HARD_FRAME_POINTER_REGNUM)) + fp = NULL_RTX; + + p = rtvec_alloc (1 + hard_frame_needed + (fp != NULL_RTX)); + + i = 0; + RTVEC_ELT (p, i++) = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM); + if (hard_frame_needed) + RTVEC_ELT (p, i++) = gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM); + if (fp != NULL_RTX) + RTVEC_ELT (p, i++) = fp; + u = gen_rtx_UNSPEC (Pmode, p, UNSPEC_TIE); + + emit_insn (gen_stack_tie (gen_frame_mem (BLKmode, u))); } /* Emit the correct code for allocating stack space, as insns. @@ -19142,7 +19157,7 @@ rs6000_emit_stack_reset (rs6000_stack_t *info, || (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0 && info->first_gp_reg_save != 32)) - rs6000_emit_stack_tie (); + rs6000_emit_stack_tie (frame_reg_rtx, frame_pointer_needed); if (frame_reg_rtx != sp_reg_rtx) { @@ -19362,7 +19377,7 @@ rs6000_emit_prologue (void) } rs6000_emit_allocate_stack (info->total_size, copy_reg); if (frame_reg_rtx != sp_reg_rtx) - rs6000_emit_stack_tie (); + rs6000_emit_stack_tie (frame_reg_rtx, false); } /* Handle world saves specially here. */ @@ -19866,7 +19881,7 @@ rs6000_emit_prologue (void) sp_offset = info->total_size; rs6000_emit_allocate_stack (info->total_size, copy_reg); if (frame_reg_rtx != sp_reg_rtx) - rs6000_emit_stack_tie (); + rs6000_emit_stack_tie (frame_reg_rtx, false); } /* Set frame pointer, if needed. */ @@ -20437,13 +20452,7 @@ rs6000_emit_epilogue (int sibcall) /* Prevent reordering memory accesses against stack pointer restore. */ else if (cfun->calls_alloca || offset_below_red_zone_p (-info->total_size)) - { - rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx); - rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx); - MEM_NOTRAP_P (mem1) = 1; - MEM_NOTRAP_P (mem2) = 1; - emit_insn (gen_frame_tie (mem1, mem2)); - } + rs6000_emit_stack_tie (frame_reg_rtx, true); insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx, GEN_INT (info->total_size))); @@ -20456,11 +20465,7 @@ rs6000_emit_epilogue (int sibcall) /* Prevent reordering memory accesses against stack pointer restore. */ if (cfun->calls_alloca || offset_below_red_zone_p (-info->total_size)) - { - rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx); - MEM_NOTRAP_P (mem) = 1; - emit_insn (gen_stack_tie (mem)); - } + rs6000_emit_stack_tie (frame_reg_rtx, false); insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, GEN_INT (info->total_size))); sp_offset = 0; Index: gcc/config/rs6000/predicates.md =================================================================== --- gcc/config/rs6000/predicates.md (revision 185830) +++ gcc/config/rs6000/predicates.md (working copy) @@ -1451,3 +1451,11 @@ return 1; }) + +;; Return 1 if OP is a stack tie operand. +(define_predicate "tie_operand" + (match_code "mem") +{ + return (GET_CODE (XEXP (op, 0)) == UNSPEC + && XINT (XEXP (op, 0), 1) == UNSPEC_TIE); +}) Index: gcc/config/rs6000/rs6000.md =================================================================== --- gcc/config/rs6000/rs6000.md (revision 185830) +++ gcc/config/rs6000/rs6000.md (working copy) @@ -11989,17 +11989,20 @@ (define_expand "restore_stack_block" [(set (match_dup 2) (match_dup 3)) (set (match_dup 4) (match_dup 2)) - (set (match_dup 5) (unspec:BLK [(match_dup 5)] UNSPEC_TIE)) + (set (match_dup 5) (const_int 0)) (set (match_operand 0 "register_operand" "") (match_operand 1 "register_operand" ""))] "" " { + rtx u; + operands[1] = force_reg (Pmode, operands[1]); operands[2] = gen_reg_rtx (Pmode); operands[3] = gen_frame_mem (Pmode, operands[0]); operands[4] = gen_frame_mem (Pmode, operands[1]); - operands[5] = gen_frame_mem (BLKmode, operands[0]); + u = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[0]), UNSPEC_TIE); + operands[5] = gen_frame_mem (BLKmode, u); }") (define_expand "save_stack_nonlocal" @@ -12022,12 +12025,13 @@ [(set (match_dup 2) (match_operand 1 "memory_operand" "")) (set (match_dup 3) (match_dup 4)) (set (match_dup 5) (match_dup 2)) - (set (match_dup 6) (unspec:BLK [(match_dup 6)] UNSPEC_TIE)) + (set (match_dup 6) (const_int 0)) (set (match_operand 0 "register_operand" "") (match_dup 3))] "" " { int units_per_word = (TARGET_32BIT) ? 4 : 8; + rtx u; /* Restore the backchain from the first word, sp from the second. */ operands[2] = gen_reg_rtx (Pmode); @@ -12035,7 +12039,8 @@ operands[1] = adjust_address_nv (operands[1], Pmode, 0); operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word); operands[5] = gen_frame_mem (Pmode, operands[3]); - operands[6] = gen_frame_mem (BLKmode, operands[0]); + u = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[0]), UNSPEC_TIE); + operands[6] = gen_frame_mem (BLKmode, u); }") ;; TOC register handling. @@ -15899,25 +15904,15 @@ [(set_attr "type" "branch") (set_attr "length" "4")]) -; These are to explain that changes to the stack pointer should -; not be moved over stores to stack memory. +; This is to explain that changes to the stack pointer should +; not be moved over loads from or stores to stack memory. (define_insn "stack_tie" - [(set (match_operand:BLK 0 "memory_operand" "+m") - (unspec:BLK [(match_dup 0)] UNSPEC_TIE))] + [(set (match_operand:BLK 0 "tie_operand" "") + (const_int 0))] "" "" [(set_attr "length" "0")]) -; Like stack_tie, but depend on both fp and sp based memory. -(define_insn "frame_tie" - [(set (match_operand:BLK 0 "memory_operand" "+m") - (unspec:BLK [(match_dup 0) - (match_operand:BLK 1 "memory_operand" "m")] UNSPEC_TIE))] - "" - "" - [(set_attr "length" "0")]) - - (define_expand "epilogue" [(use (const_int 0))] ""