From patchwork Sat Sep 17 07:19:14 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 115098 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 DDEE5B70F5 for ; Sat, 17 Sep 2011 17:19:47 +1000 (EST) Received: (qmail 11381 invoked by alias); 17 Sep 2011 07:19:44 -0000 Received: (qmail 11366 invoked by uid 22791); 17 Sep 2011 07:19:41 -0000 X-SWARE-Spam-Status: No, hits=-2.6 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW 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; Sat, 17 Sep 2011 07:19:23 +0000 Received: by gxk4 with SMTP id 4so4477406gxk.20 for ; Sat, 17 Sep 2011 00:19:22 -0700 (PDT) Received: by 10.236.76.170 with SMTP id b30mr1307458yhe.32.1316243962255; Sat, 17 Sep 2011 00:19:22 -0700 (PDT) Received: from bubble.grove.modra.org ([115.187.252.19]) by mx.google.com with ESMTPS id w70sm1167333yhk.6.2011.09.17.00.19.18 (version=TLSv1/SSLv3 cipher=OTHER); Sat, 17 Sep 2011 00:19:21 -0700 (PDT) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id BC996170C2BC; Sat, 17 Sep 2011 16:49:14 +0930 (CST) Date: Sat, 17 Sep 2011 16:49:14 +0930 From: Alan Modra To: gcc-patches@gcc.gnu.org, Bernd Schmidt , David Edelsohn Subject: PowerPC shrink-wrap support 3 of 3 Message-ID: <20110917071914.GW10321@bubble.grove.modra.org> Mail-Followup-To: gcc-patches@gcc.gnu.org, Bernd Schmidt , David Edelsohn References: <20110917071643.GT10321@bubble.grove.modra.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20110917071643.GT10321@bubble.grove.modra.org> User-Agent: Mutt/1.5.20 (2009-06-14) 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 Finally, the powerpc backend changes. These are mostly just mechanical. I'll note that we need both "simple_return" and "return" variants of the conditional returns because they can only be used when no epilogue is required. The "return" variant must use direct_return() as a predicate to check this requirement. The "simple_return" variant is used by the shrink_wrap optimization to enable a conditional return before the function prologue, and should *not* use direct_return() because the optimization is valid for functions that do require an epilogue. All other instructions in the rs6000 backend that currently use "return" are generated from the epilogue or are sibling calls, so "simple_return" is appropriate as per md.texi. * config/rs6000/rs6000.c (rs6000_make_savres_rtx): Delete unneeded declaration. (rs6000_make_savres_rtx): Rename to rs6000_emit_savres_rtx. Use simple_return in pattern, emit instruction, and set jump_label. (rs6000_emit_prologue): Update for rs6000_emit_savres_rtx. Use simple_return rather than return. (rs6000_output_mi_thunk): Use simple_return rather than return. * config/rs6000/altivec.md (restore_world): Likewise. * config/rs6000/spe.md (return_and_restore_gpregs_spe): Likewise. * config/rs6000/rs6000.md (sibcall*, sibcall_value*): Likewise. (return_internal*, return_and_restore*): Likewise. (any_return, return_pred, return_str): New iterators. (return, conditional return insns): Provide both return and simple_return variants. diff -urp -x.svn -x'*~' -x'*.orig' gcc-bernd/gcc/config/rs6000/rs6000.c gcc-current/gcc/config/rs6000/rs6000.c --- gcc-bernd/gcc/config/rs6000/rs6000.c 2011-09-16 11:52:15.000000000 +0930 +++ gcc-current/gcc/config/rs6000/rs6000.c 2011-09-15 22:25:50.000000000 +0930 @@ -899,8 +900,6 @@ static const char *rs6000_mangle_type (c static void rs6000_set_default_type_attributes (tree); static rtx rs6000_savres_routine_sym (rs6000_stack_t *, bool, bool, bool); static rtx rs6000_emit_stack_reset (rs6000_stack_t *, rtx, rtx, int, bool); -static rtx rs6000_make_savres_rtx (rs6000_stack_t *, rtx, int, - enum machine_mode, bool, bool, bool); static bool rs6000_reg_live_or_pic_offset_p (int); static tree rs6000_builtin_vectorized_libmass (tree, tree, tree); static tree rs6000_builtin_vectorized_function (tree, tree, tree); @@ -19729,10 +19764,11 @@ rs6000_emit_stack_reset (rs6000_stack_t } /* Construct a parallel rtx describing the effect of a call to an - out-of-line register save/restore routine. */ + out-of-line register save/restore routine, and emit the insn + or jump_insn as appropriate. */ static rtx -rs6000_make_savres_rtx (rs6000_stack_t *info, +rs6000_emit_savres_rtx (rs6000_stack_t *info, rtx frame_reg_rtx, int save_area_offset, enum machine_mode reg_mode, bool savep, bool gpr, bool lr) @@ -19742,6 +19778,7 @@ rs6000_make_savres_rtx (rs6000_stack_t * int reg_size = GET_MODE_SIZE (reg_mode); rtx sym; rtvec p; + rtx par, insn; offset = 0; start_reg = (gpr @@ -19752,7 +19789,7 @@ rs6000_make_savres_rtx (rs6000_stack_t * p = rtvec_alloc ((lr ? 4 : 3) + n_regs); if (!savep && lr) - RTVEC_ELT (p, offset++) = ret_rtx; + RTVEC_ELT (p, offset++) = simple_return_rtx; RTVEC_ELT (p, offset++) = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, 65)); @@ -19788,7 +19825,16 @@ rs6000_make_savres_rtx (rs6000_stack_t * RTVEC_ELT (p, i + offset) = gen_rtx_SET (VOIDmode, mem, reg); } - return gen_rtx_PARALLEL (VOIDmode, p); + par = gen_rtx_PARALLEL (VOIDmode, p); + + if (!savep && lr) + { + insn = emit_jump_insn (par); + JUMP_LABEL (insn) = simple_return_rtx; + } + else + insn = emit_insn (par); + return insn; } /* Determine whether the gp REG is really used. */ @@ -20087,16 +20133,13 @@ rs6000_emit_prologue (void) } else if (!WORLD_SAVE_P (info) && info->first_fp_reg_save != 64) { - rtx par; - - par = rs6000_make_savres_rtx (info, frame_reg_rtx, - info->fp_save_offset + sp_offset, - DFmode, - /*savep=*/true, /*gpr=*/false, - /*lr=*/(strategy - & SAVE_NOINLINE_FPRS_SAVES_LR) - != 0); - insn = emit_insn (par); + insn = rs6000_emit_savres_rtx (info, frame_reg_rtx, + info->fp_save_offset + sp_offset, + DFmode, + /*savep=*/true, /*gpr=*/false, + /*lr=*/((strategy + & SAVE_NOINLINE_FPRS_SAVES_LR) + != 0)); rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, NULL_RTX, NULL_RTX); } @@ -20186,13 +20229,10 @@ rs6000_emit_prologue (void) } else { - rtx par; - - par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11), - 0, reg_mode, - /*savep=*/true, /*gpr=*/true, - /*lr=*/false); - insn = emit_insn (par); + insn = rs6000_emit_savres_rtx (info, gen_rtx_REG (Pmode, 11), + 0, reg_mode, + /*savep=*/true, /*gpr=*/true, + /*lr=*/false); rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, NULL_RTX, NULL_RTX); } @@ -20204,8 +20244,6 @@ rs6000_emit_prologue (void) } else if (!WORLD_SAVE_P (info) && !saving_GPRs_inline) { - rtx par; - /* Need to adjust r11 (r12) if we saved any FPRs. */ if (info->first_fp_reg_save != 64) { @@ -20216,14 +20254,13 @@ rs6000_emit_prologue (void) emit_insn (gen_add3_insn (dest_reg, frame_reg_rtx, offset)); } - par = rs6000_make_savres_rtx (info, frame_reg_rtx, - info->gp_save_offset + sp_offset, - reg_mode, - /*savep=*/true, /*gpr=*/true, - /*lr=*/(strategy - & SAVE_NOINLINE_GPRS_SAVES_LR) - != 0); - insn = emit_insn (par); + insn = rs6000_emit_savres_rtx (info, frame_reg_rtx, + info->gp_save_offset + sp_offset, + reg_mode, + /*savep=*/true, /*gpr=*/true, + /*lr=*/((strategy + & SAVE_NOINLINE_GPRS_SAVES_LR) + != 0)); rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, NULL_RTX, NULL_RTX); } @@ -20750,7 +20805,7 @@ rs6000_emit_epilogue (int sibcall) alloc_rname = ggc_strdup (rname); j = 0; - RTVEC_ELT (p, j++) = ret_rtx; + RTVEC_ELT (p, j++) = simple_return_rtx; RTVEC_ELT (p, j++) = gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, LR_REGNO)); @@ -21165,13 +21214,11 @@ rs6000_emit_epilogue (int sibcall) } else { - rtx par; + rs6000_emit_savres_rtx (info, gen_rtx_REG (Pmode, 11), + 0, reg_mode, + /*savep=*/false, /*gpr=*/true, + /*lr=*/true); - par = rs6000_make_savres_rtx (info, gen_rtx_REG (Pmode, 11), - 0, reg_mode, - /*savep=*/false, /*gpr=*/true, - /*lr=*/true); - emit_jump_insn (par); /* We don't want anybody else emitting things after we jumped back. */ return; @@ -21181,12 +21228,22 @@ rs6000_emit_epilogue (int sibcall) { /* We are jumping to an out-of-line function. */ bool can_use_exit = info->first_fp_reg_save == 64; - rtx par; /* Emit stack reset code if we need it. */ if (can_use_exit) - rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx, - sp_offset, can_use_exit); + { + rs6000_emit_stack_reset (info, sp_reg_rtx, frame_reg_rtx, + sp_offset, can_use_exit); + if (info->cr_save_p) + { + rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple); + if (DEFAULT_ABI == ABI_V4) + cfa_restores + = alloc_reg_note (REG_CFA_RESTORE, + gen_rtx_REG (SImode, CR2_REGNO), + cfa_restores); + } + } else { emit_insn (gen_add3_insn (gen_rtx_REG (Pmode, DEFAULT_ABI == ABI_AIX @@ -21197,31 +21254,18 @@ rs6000_emit_epilogue (int sibcall) sp_offset += info->fp_size; } - par = rs6000_make_savres_rtx (info, frame_reg_rtx, - info->gp_save_offset, reg_mode, - /*savep=*/false, /*gpr=*/true, - /*lr=*/can_use_exit); + insn = rs6000_emit_savres_rtx (info, frame_reg_rtx, + info->gp_save_offset, reg_mode, + /*savep=*/false, /*gpr=*/true, + /*lr=*/can_use_exit); if (can_use_exit) { - if (info->cr_save_p) - { - rs6000_restore_saved_cr (cr_save_reg, using_mtcr_multiple); - if (DEFAULT_ABI == ABI_V4) - cfa_restores - = alloc_reg_note (REG_CFA_RESTORE, - gen_rtx_REG (SImode, CR2_REGNO), - cfa_restores); - } - - emit_jump_insn (par); - /* We don't want anybody else emitting things after we jumped back. */ return; } - insn = emit_insn (par); if (DEFAULT_ABI == ABI_V4) { if (frame_pointer_needed) @@ -21366,7 +21410,7 @@ rs6000_emit_epilogue (int sibcall) else p = rtvec_alloc (2); - RTVEC_ELT (p, 0) = ret_rtx; + RTVEC_ELT (p, 0) = simple_return_rtx; RTVEC_ELT (p, 1) = ((restoring_FPRs_inline || !lr) ? gen_rtx_USE (VOIDmode, gen_rtx_REG (Pmode, 65)) : gen_rtx_CLOBBER (VOIDmode, @@ -21768,7 +21812,7 @@ rs6000_output_mi_thunk (FILE *file, tree gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, LR_REGNO)), - ret_rtx))); + simple_return_rtx))); SIBLING_CALL_P (insn) = 1; emit_barrier (); diff -urp -x.svn -x'*~' -x'*.orig' gcc-bernd/gcc/config/rs6000/altivec.md gcc-current/gcc/config/rs6000/altivec.md --- gcc-bernd/gcc/config/rs6000/altivec.md 2011-09-16 11:52:15.000000000 +0930 +++ gcc-current/gcc/config/rs6000/altivec.md 2011-09-15 18:28:43.000000000 +0930 @@ -306,7 +306,7 @@ (define_insn "*restore_world" [(match_parallel 0 "restore_world_operation" - [(return) + [(simple_return) (use (reg:SI 65)) (use (match_operand:SI 1 "call_operand" "s")) (clobber (match_operand:SI 2 "gpc_reg_operand" "=r"))])] diff -urp -x.svn -x'*~' -x'*.orig' gcc-bernd/gcc/config/rs6000/rs6000.md gcc-current/gcc/config/rs6000/rs6000.md --- gcc-bernd/gcc/config/rs6000/rs6000.md 2011-09-16 11:52:15.000000000 +0930 +++ gcc-current/gcc/config/rs6000/rs6000.md 2011-09-16 11:32:31.000000000 +0930 @@ -264,6 +265,12 @@ ; Iterator for just SF/DF (define_mode_iterator SFDF [SF DF]) +; Conditional returns. +(define_code_iterator any_return [return simple_return]) +(define_code_attr return_pred [(return "direct_return ()") + (simple_return "")]) +(define_code_attr return_str [(return "") (simple_return "simple_")]) + ; Various instructions that come in SI and DI forms. ; A generic w/d attribute, for things like cmpw/cmpd. (define_mode_attr wd [(QI "b") (HI "h") (SI "w") (DI "d")]) @@ -12814,7 +12831,7 @@ (match_operand 1 "" "")) (use (match_operand 2 "" "")) (use (reg:SI LR_REGNO)) - (return)])] + (simple_return)])] "" " { @@ -12838,7 +12855,7 @@ (match_operand 1 "" "g,g")) (use (match_operand:SI 2 "immediate_operand" "O,n")) (use (reg:SI LR_REGNO)) - (return)] + (simple_return)] "(INTVAL (operands[2]) & CALL_LONG) == 0" "* { @@ -12858,7 +12875,7 @@ (match_operand 1 "" "g,g")) (use (match_operand:SI 2 "immediate_operand" "O,n")) (use (reg:SI LR_REGNO)) - (return)] + (simple_return)] "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0" "* { @@ -12879,7 +12896,7 @@ (match_operand 2 "" "g,g"))) (use (match_operand:SI 3 "immediate_operand" "O,n")) (use (reg:SI LR_REGNO)) - (return)] + (simple_return)] "(INTVAL (operands[3]) & CALL_LONG) == 0" "* { @@ -12901,7 +12918,7 @@ (match_operand 2 "" "g,g"))) (use (match_operand:SI 3 "immediate_operand" "O,n")) (use (reg:SI LR_REGNO)) - (return)] + (simple_return)] "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0" "* { @@ -12921,7 +12938,7 @@ (match_operand 1 "" "g,g")) (use (match_operand:SI 2 "immediate_operand" "O,O")) (use (reg:SI LR_REGNO)) - (return)] + (simple_return)] "DEFAULT_ABI == ABI_AIX && (INTVAL (operands[2]) & CALL_LONG) == 0" "@ @@ -12936,7 +12953,7 @@ (match_operand 2 "" "g,g"))) (use (match_operand:SI 3 "immediate_operand" "O,O")) (use (reg:SI LR_REGNO)) - (return)] + (simple_return)] "DEFAULT_ABI == ABI_AIX && (INTVAL (operands[3]) & CALL_LONG) == 0" "@ @@ -12950,7 +12967,7 @@ (match_operand 1 "" "")) (use (match_operand 2 "immediate_operand" "O,n,O,n")) (use (reg:SI LR_REGNO)) - (return)] + (simple_return)] "(DEFAULT_ABI == ABI_DARWIN || DEFAULT_ABI == ABI_V4) && (INTVAL (operands[2]) & CALL_LONG) == 0" @@ -12981,7 +12998,7 @@ (match_operand 2 "" ""))) (use (match_operand 3 "" "")) (use (reg:SI LR_REGNO)) - (return)])] + (simple_return)])] "" " { @@ -13002,7 +13019,7 @@ (match_operand 2 "" ""))) (use (match_operand:SI 3 "immediate_operand" "O,n,O,n")) (use (reg:SI LR_REGNO)) - (return)] + (simple_return)] "(DEFAULT_ABI == ABI_DARWIN || DEFAULT_ABI == ABI_V4) && (INTVAL (operands[3]) & CALL_LONG) == 0" @@ -15328,9 +15345,9 @@ [(match_operand 1 "cc_reg_operand" "y") (const_int 0)]) - (return) + (any_return) (pc)))] - "direct_return ()" + "" "* { return output_cbranch (operands[0], NULL, 0, insn); @@ -15360,8 +15377,8 @@ "cc_reg_operand" "y") (const_int 0)]) (pc) - (return)))] - "direct_return ()" + (any_return)))] + "" "* { return output_cbranch (operands[0], NULL, 1, insn); @@ -15491,9 +15508,9 @@ "b %l0" [(set_attr "type" "branch")]) -(define_insn "return" - [(return)] - "direct_return ()" +(define_insn "return" + [(any_return)] + "" "{br|blr}" [(set_attr "type" "jmpreg")]) @@ -16015,7 +16032,7 @@ (set_attr "cell_micro" "always")]) (define_insn "*return_internal_" - [(return) + [(simple_return) (use (match_operand:P 0 "register_operand" "lc"))] "" "b%T0" @@ -16077,7 +16094,7 @@ (define_insn "*return_and_restore_gpregs__r11" [(match_parallel 0 "any_parallel_operand" - [(return) + [(simple_return) (clobber (match_operand:P 1 "register_operand" "=l")) (use (match_operand:P 2 "symbol_ref_operand" "s")) (use (reg:P 11)) @@ -16090,7 +16107,7 @@ (define_insn "*return_and_restore_gpregs__r12" [(match_parallel 0 "any_parallel_operand" - [(return) + [(simple_return) (clobber (match_operand:P 1 "register_operand" "=l")) (use (match_operand:P 2 "symbol_ref_operand" "s")) (use (reg:P 12)) @@ -16103,7 +16120,7 @@ (define_insn "*return_and_restore_gpregs__r1" [(match_parallel 0 "any_parallel_operand" - [(return) + [(simple_return) (clobber (match_operand:P 1 "register_operand" "=l")) (use (match_operand:P 2 "symbol_ref_operand" "s")) (use (reg:P 1)) @@ -16116,7 +16133,7 @@ (define_insn "*return_and_restore_fpregs__r11" [(match_parallel 0 "any_parallel_operand" - [(return) + [(simple_return) (clobber (match_operand:P 1 "register_operand" "=l")) (use (match_operand:P 2 "symbol_ref_operand" "s")) (use (reg:P 11)) @@ -16129,7 +16146,7 @@ (define_insn "*return_and_restore_fpregs__r12" [(match_parallel 0 "any_parallel_operand" - [(return) + [(simple_return) (clobber (match_operand:P 1 "register_operand" "=l")) (use (match_operand:P 2 "symbol_ref_operand" "s")) (use (reg:P 12)) @@ -16142,7 +16159,7 @@ (define_insn "*return_and_restore_fpregs__r1" [(match_parallel 0 "any_parallel_operand" - [(return) + [(simple_return) (clobber (match_operand:P 1 "register_operand" "=l")) (use (match_operand:P 2 "symbol_ref_operand" "s")) (use (reg:P 1)) @@ -16155,7 +16172,7 @@ (define_insn "*return_and_restore_fpregs_aix__r11" [(match_parallel 0 "any_parallel_operand" - [(return) + [(simple_return) (use (match_operand:P 1 "register_operand" "l")) (use (match_operand:P 2 "symbol_ref_operand" "s")) (use (reg:P 11)) @@ -16168,7 +16185,7 @@ (define_insn "*return_and_restore_fpregs_aix__r1" [(match_parallel 0 "any_parallel_operand" - [(return) + [(simple_return) (use (match_operand:P 1 "register_operand" "l")) (use (match_operand:P 2 "symbol_ref_operand" "s")) (use (reg:P 1)) diff -urp -x.svn -x'*~' -x'*.orig' gcc-bernd/gcc/config/rs6000/spe.md gcc-current/gcc/config/rs6000/spe.md --- gcc-bernd/gcc/config/rs6000/spe.md 2011-09-16 11:52:15.000000000 +0930 +++ gcc-current/gcc/config/rs6000/spe.md 2011-09-15 18:28:43.000000000 +0930 @@ -3178,7 +3178,7 @@ (define_insn "*return_and_restore_gpregs_spe" [(match_parallel 0 "any_parallel_operand" - [(return) + [(simple_return) (clobber (reg:P 65)) (use (match_operand:P 1 "symbol_ref_operand" "s")) (use (reg:P 11))