From patchwork Thu Oct 6 21:39:29 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bernd Schmidt X-Patchwork-Id: 118170 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 3B02BB6FA3 for ; Fri, 7 Oct 2011 08:40:03 +1100 (EST) Received: (qmail 29685 invoked by alias); 6 Oct 2011 21:40:00 -0000 Received: (qmail 29674 invoked by uid 22791); 6 Oct 2011 21:39:58 -0000 X-SWARE-Spam-Status: No, hits=-1.6 required=5.0 tests=AWL,BAYES_00 X-Spam-Check-By: sourceware.org Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 06 Oct 2011 21:39:41 +0000 Received: from nat-ies.mentorg.com ([192.94.31.2] helo=EU1-MAIL.mgc.mentorg.com) by relay1.mentorg.com with esmtp id 1RBvfI-0006wb-8q from Bernd_Schmidt@mentor.com ; Thu, 06 Oct 2011 14:39:40 -0700 Received: from [127.0.0.1] ([172.16.63.104]) by EU1-MAIL.mgc.mentorg.com with Microsoft SMTPSVC(6.0.3790.1830); Thu, 6 Oct 2011 22:39:38 +0100 Message-ID: <4E8E2011.5070204@codesourcery.com> Date: Thu, 06 Oct 2011 23:39:29 +0200 From: Bernd Schmidt User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.20) Gecko/20110920 Lightning/1.0b3pre Thunderbird/3.1.12 MIME-Version: 1.0 To: Ian Lance Taylor CC: Richard Henderson , Richard Guenther , GCC Patches , richard.sandiford@linaro.org Subject: Re: Initial shrink-wrapping patch References: <4E5E7342.9050103@codesourcery.com> <4E6F37D9.9000108@t-online.de> <4E6F4B90.2050408@codesourcery.com> <4E6F786E.6080407@codesourcery.com> <4E712FD6.5030109@redhat.com> <4E8239ED.9020004@codesourcery.com> <4E85F395.3030006@redhat.com> <4E8B8469.2090605@codesourcery.com> <4E8B88E7.3090107@redhat.com> <4E8C7ED0.3090705@codesourcery.com> <4E8C83FA.3000607@redhat.com> <4E8C912C.2060805@codesourcery.com> <4E8CEC99.2000105@codesourcery.com> <4E8D8302.3090306@codesourcery.com> <4E8DD0E3.5010106@codesourcery.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 On 10/06/11 21:33, Ian Lance Taylor wrote: > Note that you can test Go yourself by adding --enable-languages=go to > your configure line. Nothing special is required to build Go. It works > better if you use the gold linker but that is not required. Oh, ok. For some reason I thought I was remembering that it doesn't build on my box. Here's the set of fixes I have now. find_many_sub_blocks needs to be run on the destination of the orig_entry_edge, and it also appears to munge basic block pointers, so unconverted_simple_returns now stores jump insns. For HJ's problem I gave in and used register numbers rather than comparing with stack_pointer_rtx etc., and converted some more code to use df as originally suggested by Richard S. Testing now with rth's csa patch also applied, both i686-linux and x86_64-linux. Bootstraps complete, all languages including Go for the i686-linux one. Ok if testing passes? Bernd * function.c (frame_required_for_rtx): Remove function. (requires_stack_frame_p): New arg set_up_by_prologue. All callers changed. Compute a set of mentioned registers and compare against the new arg rather than calling frame_required_for_rtx. (thread_prologue_and_epilogue_insns): Compute the set_up_by_prologue reg set. Convert the unconverted_simple_returns mechanism to store jump insns rather than their basic blocks. Also check the orig_entry_edge destination for new blocks. Index: function.c =================================================================== --- function.c (revision 179627) +++ function.c (working copy) @@ -5303,25 +5303,15 @@ record_hard_reg_uses (rtx *px, void *dat for_each_rtx (px, record_hard_reg_uses_1, data); } -/* A subroutine of requires_stack_frame_p, called via for_each_rtx. - Return 1 if we found an rtx that forces a prologue, zero otherwise. */ -static int -frame_required_for_rtx (rtx *loc, void *data ATTRIBUTE_UNUSED) -{ - rtx x = *loc; - if (x == stack_pointer_rtx || x == hard_frame_pointer_rtx - || x == arg_pointer_rtx || x == pic_offset_table_rtx) - return 1; - return 0; -} - /* Return true if INSN requires the stack frame to be set up. PROLOGUE_USED contains the hard registers used in the function - prologue. */ + prologue. SET_UP_BY_PROLOGUE is the set of registers we expect the + prologue to set up for the function. */ static bool -requires_stack_frame_p (rtx insn, HARD_REG_SET prologue_used) +requires_stack_frame_p (rtx insn, HARD_REG_SET prologue_used, + HARD_REG_SET set_up_by_prologue) { - df_ref *def_rec; + df_ref *df_rec; HARD_REG_SET hardregs; unsigned regno; @@ -5329,13 +5319,11 @@ requires_stack_frame_p (rtx insn, HARD_R return false; if (CALL_P (insn)) return !SIBLING_CALL_P (insn); - if (for_each_rtx (&PATTERN (insn), frame_required_for_rtx, NULL)) - return true; CLEAR_HARD_REG_SET (hardregs); - for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++) + for (df_rec = DF_INSN_DEFS (insn); *df_rec; df_rec++) { - rtx dreg = DF_REF_REG (*def_rec); + rtx dreg = DF_REF_REG (*df_rec); if (!REG_P (dreg)) continue; @@ -5350,6 +5338,20 @@ requires_stack_frame_p (rtx insn, HARD_R if (TEST_HARD_REG_BIT (hardregs, regno) && df_regs_ever_live_p (regno)) return true; + + for (df_rec = DF_INSN_USES (insn); *df_rec; df_rec++) + { + rtx reg = DF_REF_REG (*df_rec); + + if (!REG_P (reg)) + continue; + + add_to_hard_reg_set (&hardregs, GET_MODE (reg), + REGNO (reg)); + } + if (hard_reg_set_intersect_p (hardregs, set_up_by_prologue)) + return true; + return false; } #endif @@ -5455,7 +5457,7 @@ thread_prologue_and_epilogue_insns (void basic_block last_bb; bool last_bb_active ATTRIBUTE_UNUSED; #ifdef HAVE_simple_return - VEC (basic_block, heap) *unconverted_simple_returns = NULL; + VEC (rtx, heap) *unconverted_simple_returns = NULL; basic_block simple_return_block_hot = NULL; basic_block simple_return_block_cold = NULL; bool nonempty_prologue; @@ -5575,6 +5577,7 @@ thread_prologue_and_epilogue_insns (void && nonempty_prologue && !crtl->calls_eh_return) { HARD_REG_SET prologue_clobbered, prologue_used, live_on_edge; + HARD_REG_SET set_up_by_prologue; rtx p_insn; VEC(basic_block, heap) *vec; @@ -5610,6 +5613,16 @@ thread_prologue_and_epilogue_insns (void vec = VEC_alloc (basic_block, heap, n_basic_blocks); + CLEAR_HARD_REG_SET (set_up_by_prologue); + add_to_hard_reg_set (&set_up_by_prologue, Pmode, STACK_POINTER_REGNUM); + add_to_hard_reg_set (&set_up_by_prologue, Pmode, ARG_POINTER_REGNUM); + if (frame_pointer_needed) + add_to_hard_reg_set (&set_up_by_prologue, Pmode, + HARD_FRAME_POINTER_REGNUM); + if (pic_offset_table_rtx) + add_to_hard_reg_set (&set_up_by_prologue, Pmode, + PIC_OFFSET_TABLE_REGNUM); + FOR_EACH_BB (bb) { rtx insn; @@ -5628,7 +5641,8 @@ thread_prologue_and_epilogue_insns (void } else FOR_BB_INSNS (bb, insn) - if (requires_stack_frame_p (insn, prologue_used)) + if (requires_stack_frame_p (insn, prologue_used, + set_up_by_prologue)) { bitmap_set_bit (&bb_flags, bb->index); VEC_quick_push (basic_block, vec, bb); @@ -5872,8 +5886,8 @@ thread_prologue_and_epilogue_insns (void { #ifdef HAVE_simple_return if (simple_p) - VEC_safe_push (basic_block, heap, - unconverted_simple_returns, bb); + VEC_safe_push (rtx, heap, + unconverted_simple_returns, jump); #endif continue; } @@ -5891,8 +5905,8 @@ thread_prologue_and_epilogue_insns (void { #ifdef HAVE_simple_return if (simple_p) - VEC_safe_push (basic_block, heap, - unconverted_simple_returns, bb); + VEC_safe_push (rtx, heap, + unconverted_simple_returns, jump); #endif continue; } @@ -6022,6 +6036,7 @@ epilogue_done: blocks = sbitmap_alloc (last_basic_block); sbitmap_zero (blocks); SET_BIT (blocks, entry_edge->dest->index); + SET_BIT (blocks, orig_entry_edge->dest->index); find_many_sub_basic_blocks (blocks); sbitmap_free (blocks); @@ -6040,10 +6055,10 @@ epilogue_done: convert to conditional simple_returns, but couldn't for some reason, create a block to hold a simple_return insn and redirect those remaining edges. */ - if (!VEC_empty (basic_block, unconverted_simple_returns)) + if (!VEC_empty (rtx, unconverted_simple_returns)) { basic_block exit_pred = EXIT_BLOCK_PTR->prev_bb; - basic_block src_bb; + rtx jump; int i; gcc_assert (entry_edge != orig_entry_edge); @@ -6061,8 +6076,9 @@ epilogue_done: simple_return_block_cold = e->dest; } - FOR_EACH_VEC_ELT (basic_block, unconverted_simple_returns, i, src_bb) + FOR_EACH_VEC_ELT (rtx, unconverted_simple_returns, i, jump) { + basic_block src_bb = BLOCK_FOR_INSN (jump); edge e = find_edge (src_bb, last_bb); basic_block *pdest_bb; @@ -6087,7 +6103,7 @@ epilogue_done: } redirect_edge_and_branch_force (e, *pdest_bb); } - VEC_free (basic_block, heap, unconverted_simple_returns); + VEC_free (rtx, heap, unconverted_simple_returns); } #endif