From patchwork Fri Mar 25 22:00:50 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Modra X-Patchwork-Id: 602121 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]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3qWy1P5fvSz9sBG for ; Sat, 26 Mar 2016 09:01:12 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=v46zf62s; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; q=dns; s=default; b=uY0DdpKhpBRVtDZYA ES0r6+YJMN8GjvSOSorZvn/a3BFZn6fsqpuXhnaTMY8AIvgaGkFpRmCk40TypwW4 HRScM8c6cRB1y3sNglWNuIY/QbfvkTtah3vK16UFbQLwNyUEZlcB+7WMKy5CPYH7 NOvE81stJn9E7baGw8oZRfaOR8= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; s=default; bh=BHzVybGNGHJTmlvoF/oC/ZW aqJs=; b=v46zf62sBCj4YLkbkTNznaHcV65shIZ4CiPfZGJ/Ystzy8lGfjZj237 aSnnMjvERJijIubFziQYGnVH/pgDUyo368QaWTHC1DmJ3klbNEi1uazzQ+0xqwco BBWWztLSISHbSpmdpmxDqGV03XlfuNJUDEZ+eQGIiytx08+d+1GA= Received: (qmail 105996 invoked by alias); 25 Mar 2016 22:01:04 -0000 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 Received: (qmail 105983 invoked by uid 89); 25 Mar 2016 22:01:03 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.1 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=no version=3.3.2 spammy=Total, dies, Scan, lifetime X-HELO: mail-pf0-f193.google.com Received: from mail-pf0-f193.google.com (HELO mail-pf0-f193.google.com) (209.85.192.193) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Fri, 25 Mar 2016 22:00:58 +0000 Received: by mail-pf0-f193.google.com with SMTP id q129so12896589pfb.3 for ; Fri, 25 Mar 2016 15:00:57 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=SDjmiVpzUk6iBJDRWW54vxv10fFqdxVtqHrnonhMQJU=; b=QKtQKvgdmMJBgsF8wsOA9l9Bqqy7H29p2KxNeRxKWZBbzzkLGU+cL+IMRPt1lgaqla IdpLThQjrh2uvon1uOdHo/ki6+bDwhKf08NCLWnegEyWUDvPz4Zeyz3XLihzF+5E1VMu tytrOAiKpj/5UDxxrd/u/GqByM69I/yp+nWP4f2Afyrt+CSISL1KkFC8wqjsXx6ErFGr pUXGrd6b79/8+rHsmkeSTYGQZLlAHwG8qY2bSy/7lDiIYBuhNLL2BFEiCVA9eICwlyGN 5/bHyO0l4U8V4O+hxFlgRsOxr15idDEdHg0KIGfsXiNXreidL+mRwTWoVz6m9ce47uNQ oszA== X-Gm-Message-State: AD7BkJLwubqpPunoe4gkM6LTmiWeJcbcr9vt35ARQliJMzdCrbH1z/X+bp7E9mhxz+cHqQ== X-Received: by 10.98.89.129 with SMTP id k1mr24278752pfj.66.1458943256218; Fri, 25 Mar 2016 15:00:56 -0700 (PDT) Received: from bubble.grove.modra.org (CPE-58-160-146-233.sa.bigpond.net.au. [58.160.146.233]) by smtp.gmail.com with ESMTPSA id o69sm18487731pfi.14.2016.03.25.15.00.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 25 Mar 2016 15:00:55 -0700 (PDT) Received: by bubble.grove.modra.org (Postfix, from userid 1000) id 00E90EA0157; Sat, 26 Mar 2016 08:30:50 +1030 (ACDT) Date: Sat, 26 Mar 2016 08:30:50 +1030 From: Alan Modra To: Bernd Schmidt Cc: gcc-patches@gcc.gnu.org Subject: Goodbye REG_LIVE_LENGTH Message-ID: <20160325220050.GI31470@bubble.grove.modra.org> References: <20160321013723.GC22605@bubble.grove.modra.org> <20160321014311.GJ22605@bubble.grove.modra.org> <56F1DD46.6040702@redhat.com> <20160323225036.GA31470@bubble.grove.modra.org> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20160323225036.GA31470@bubble.grove.modra.org> User-Agent: Mutt/1.5.23 (2014-03-12) X-IsSubscribed: yes On Thu, Mar 24, 2016 at 09:20:36AM +1030, Alan Modra wrote: > On Wed, Mar 23, 2016 at 01:03:18AM +0100, Bernd Schmidt wrote: > > >@@ -3536,7 +3557,8 @@ update_equiv_regs (void) > > > { > > > /* Note that the statement below does not affect the priority > > > in local-alloc! */ > > >- REG_LIVE_LENGTH (regno) *= 2; > > >+ if (note) > > >+ REG_LIVE_LENGTH (regno) *= 2; > > > > That's a very suspicious comment. It would be worth testing whether > > REG_LIVE_LENGTH has any effect on our current register allocation at all, > > and remove this code if not. > > Yes, REG_LIVE_LENGTH is used in just one place in the whole of gcc, > and that's the test in update_equiv_regs just above the code you > quote. > /* Don't mess with things live during setjmp. */ > if (REG_LIVE_LENGTH (regno) >= 0 && optimize) > > That could be replaced with > if (optimize && !bitmap_bit_p (setjmp_crosses, regno)) > and outside the loop > bitmap setjmp_crosses = regstat_get_setjmp_crosses (); > > For now, I've removed the REG_LIVE_LENGTH adjustment from patch 7/7. > I'll also prepare a patch to delete REG_LIVE_LENGTH everywhere. Like this. Bootstrapped and regression tested x86_64-linux. OK for stage1? * regs.h (struct reg_info_t): Delete live_length. (REG_LIVE_LENGTH): Delete macro. * regstat.c (regstat_bb_compute_ri): Delete artificial_uses, local_live, local_processed and local_live_last_luid params. Replace bb_index param with bb. Don't set REG_LIVE_LENGTH. Formatting fixes. (regstat_compute_ri): Adjust for above. Don't set REG_LIVE_LENGTH. (dump_reg_info): Don't print live length. * ira.c (update_equiv_regs): Replace test of REG_LIVE_LENGTH with test of setjmp_crosses. Don't set REG_LIVE_LENGTH. Localize loop_depth var. diff --git a/gcc/ira.c b/gcc/ira.c index cab8dc1..3173276 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -3315,7 +3315,6 @@ update_equiv_regs (void) { rtx_insn *insn; basic_block bb; - int loop_depth; /* Scan insns and set pdx_subregs if the reg is used in a paradoxical subreg. Don't set such reg equivalent to a mem, @@ -3329,9 +3328,10 @@ update_equiv_regs (void) /* Scan the insns and find which registers have equivalences. Do this in a separate scan of the insns because (due to -fcse-follow-jumps) a register can be set below its use. */ + bitmap setjmp_crosses = regstat_get_setjmp_crosses (); FOR_EACH_BB_FN (bb, cfun) { - loop_depth = bb_loop_depth (bb); + int loop_depth = bb_loop_depth (bb); for (insn = BB_HEAD (bb); insn != NEXT_INSN (BB_END (bb)); @@ -3553,12 +3553,8 @@ update_equiv_regs (void) reg_equiv[regno].loop_depth = (short) loop_depth; /* Don't mess with things live during setjmp. */ - if (REG_LIVE_LENGTH (regno) >= 0 && optimize) + if (optimize && !bitmap_bit_p (setjmp_crosses, regno)) { - /* Note that the statement below does not affect the priority - in local-alloc! */ - REG_LIVE_LENGTH (regno) *= 2; - /* If the register is referenced exactly twice, meaning it is set once and used once, indicate that the reference may be replaced by the equivalence we computed above. Do this @@ -3744,7 +3740,6 @@ combine_and_move_insns (void) REG_N_CALLS_CROSSED (regno) = 0; REG_FREQ_CALLS_CROSSED (regno) = 0; REG_N_THROWING_CALLS_CROSSED (regno) = 0; - REG_LIVE_LENGTH (regno) = 2; if (use_insn == BB_HEAD (use_bb)) BB_HEAD (use_bb) = new_insn; diff --git a/gcc/regs.h b/gcc/regs.h index 6f992bd..244250d 100644 --- a/gcc/regs.h +++ b/gcc/regs.h @@ -105,7 +105,6 @@ struct reg_info_t { int freq; /* # estimated frequency (REG n) is used or set */ int deaths; /* # of times (REG n) dies */ - int live_length; /* # of instructions (REG n) is live */ int calls_crossed; /* # of calls (REG n) is live across */ int freq_calls_crossed; /* # estimated frequency (REG n) crosses call */ int throw_calls_crossed; /* # of calls that may throw (REG n) is live across */ @@ -170,20 +169,6 @@ extern size_t reg_info_p_size; #define REG_N_THROWING_CALLS_CROSSED(N) (reg_info_p[N].throw_calls_crossed) -/* Total number of instructions at which (REG n) is live. - - This is set in regstat.c whenever register info is requested and - remains valid for the rest of the compilation of the function; it is - used to control register allocation. The larger this is, the less - priority (REG n) gets for allocation in a hard register (in IRA in - priority-coloring mode). - - Negative values are special: -1 is used to mark a pseudo reg that - should not be allocated to a hard register, because it crosses a - setjmp call. */ - -#define REG_LIVE_LENGTH(N) (reg_info_p[N].live_length) - /* Indexed by n, gives number of basic block that (REG n) is used in. If the value is REG_BLOCK_GLOBAL (-1), it means (REG n) is used in more than one basic block. diff --git a/gcc/regstat.c b/gcc/regstat.c index c05b69f..b25a63c 100644 --- a/gcc/regstat.c +++ b/gcc/regstat.c @@ -94,7 +94,7 @@ regstat_free_n_sets_and_refs (void) /*---------------------------------------------------------------------------- REGISTER INFORMATION - Process REG_N_DEATHS, REG_LIVE_LENGTH, REG_N_CALLS_CROSSED, + Process REG_N_DEATHS, REG_N_CALLS_CROSSED, REG_N_THROWING_CALLS_CROSSED and REG_BASIC_BLOCK. ----------------------------------------------------------------------------*/ @@ -106,24 +106,17 @@ struct reg_info_t *reg_info_p; size_t reg_info_p_size; /* Compute register info: lifetime, bb, and number of defs and uses - for basic block BB. The three bitvectors are scratch regs used - here. */ + for basic block BB. LIVE is a scratch bitvector used here. */ static void -regstat_bb_compute_ri (unsigned int bb_index, - bitmap live, bitmap artificial_uses, - bitmap local_live, bitmap local_processed, - int *local_live_last_luid) +regstat_bb_compute_ri (basic_block bb, bitmap live) { - basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index); rtx_insn *insn; df_ref def, use; - int luid = 0; bitmap_iterator bi; unsigned int regno; bitmap_copy (live, df_get_live_out (bb)); - bitmap_clear (artificial_uses); /* Process the regs live at the end of the block. Mark them as not local to any one basic block. */ @@ -132,30 +125,26 @@ regstat_bb_compute_ri (unsigned int bb_index, /* Process the artificial defs and uses at the bottom of the block to begin processing. */ - FOR_EACH_ARTIFICIAL_DEF (def, bb_index) + FOR_EACH_ARTIFICIAL_DEF (def, bb->index) if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0) bitmap_clear_bit (live, DF_REF_REGNO (def)); - FOR_EACH_ARTIFICIAL_USE (use, bb_index) + FOR_EACH_ARTIFICIAL_USE (use, bb->index) if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0) { regno = DF_REF_REGNO (use); bitmap_set_bit (live, regno); - bitmap_set_bit (artificial_uses, regno); } FOR_BB_INSNS_REVERSE (bb, insn) { struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn); bitmap_iterator bi; - df_mw_hardreg *mw; rtx link; if (!NONDEBUG_INSN_P (insn)) continue; - luid++; - link = REG_NOTES (insn); while (link) { @@ -194,82 +183,24 @@ regstat_bb_compute_ri (unsigned int bb_index, } } - /* We only care about real sets for calls. Clobbers cannot - be depended on. - Only do this if the value is totally dead. */ - FOR_EACH_INSN_INFO_MW (mw, insn_info) - if (DF_MWS_REG_DEF_P (mw)) - { - bool all_dead = true; - unsigned int r; - - for (r = mw->start_regno; r <= mw->end_regno; r++) - if (bitmap_bit_p (artificial_uses, r) - || bitmap_bit_p (live, r)) - { - all_dead = false; - break; - } - - if (all_dead) - { - regno = mw->start_regno; - REG_LIVE_LENGTH (regno)++; - } - } - /* All of the defs except the return value are some sort of clobber. This code is for the return. */ FOR_EACH_INSN_INFO_DEF (def, insn_info) { if ((!CALL_P (insn)) - || (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))) + || (!(DF_REF_FLAGS (def) + & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))) { unsigned int dregno = DF_REF_REGNO (def); - if (bitmap_bit_p (live, dregno)) - { - /* If we have seen a use of DREGNO somewhere before (i.e. - later in this basic block), and DEF is not a subreg - store or conditional store, then kill the register - here and add the proper length to its REG_LIVE_LENGTH. - - If we have not seen a use of DREGNO later in this basic - block, then we need to add the length from here to the - end of the block to the live length. */ - if (bitmap_bit_p (local_live, dregno)) - { - /* Note that LOCAL_LIVE implies LOCAL_PROCESSED, so - we don't have to set LOCAL_PROCESSED in this clause. */ - if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL))) - { - REG_LIVE_LENGTH (dregno) += - (luid - local_live_last_luid[dregno]); - local_live_last_luid[dregno] = luid; - bitmap_clear_bit (local_live, dregno); - } - } - else - { - bitmap_set_bit (local_processed, dregno); - REG_LIVE_LENGTH (dregno) += luid; - local_live_last_luid[dregno] = luid; - } - - /* Kill this register if it is not a subreg store or - conditional store. - ??? This means that any partial store is live from - the last use in a basic block to the start of this - basic block. This results in poor calculations of - REG_LIVE_LENGTH in large basic blocks. */ - if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL))) - bitmap_clear_bit (live, dregno); - } - else if ((!(DF_REF_FLAGS (def) & DF_REF_MW_HARDREG)) - && (!bitmap_bit_p (artificial_uses, dregno))) - { - REG_LIVE_LENGTH (dregno)++; - } + /* Kill this register if it is not a subreg store or + conditional store. + ??? This means that any partial store is live from + the last use in a basic block to the start of this + basic block. */ + if (!(DF_REF_FLAGS (def) + & (DF_REF_PARTIAL | DF_REF_CONDITIONAL))) + bitmap_clear_bit (live, dregno); if (dregno >= FIRST_PSEUDO_REGISTER) { @@ -300,37 +231,8 @@ regstat_bb_compute_ri (unsigned int bb_index, else if (REG_BASIC_BLOCK (uregno) != bb->index) REG_BASIC_BLOCK (uregno) = REG_BLOCK_GLOBAL; } - - if (bitmap_set_bit (live, uregno)) - { - /* This register is now live. Begin to process it locally. - - Note that we don't even get here if the variable was live - at the end of the block since just a ref inside the block - does not effect the calculations. */ - REG_LIVE_LENGTH (uregno) ++; - local_live_last_luid[uregno] = luid; - bitmap_set_bit (local_live, uregno); - bitmap_set_bit (local_processed, uregno); - } } } - - /* Add the liveness length to all registers that were used somewhere - in this bock, but not between that use and the head of this block. */ - EXECUTE_IF_SET_IN_BITMAP (local_live, 0, regno, bi) - { - REG_LIVE_LENGTH (regno) += (luid - local_live_last_luid[regno]); - } - - /* Add the length of the block to all of the registers that were not - referenced, but still live in this block. */ - bitmap_and_compl_into (live, local_processed); - EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi) - REG_LIVE_LENGTH (regno) += luid; - - bitmap_clear (local_processed); - bitmap_clear (local_live); } @@ -340,12 +242,8 @@ regstat_compute_ri (void) { basic_block bb; bitmap live = BITMAP_ALLOC (&df_bitmap_obstack); - bitmap artificial_uses = BITMAP_ALLOC (&df_bitmap_obstack); - bitmap local_live = BITMAP_ALLOC (&df_bitmap_obstack); - bitmap local_processed = BITMAP_ALLOC (&df_bitmap_obstack); unsigned int regno; bitmap_iterator bi; - int *local_live_last_luid; /* Initialize everything. */ @@ -356,26 +254,18 @@ regstat_compute_ri (void) max_regno = max_reg_num (); reg_info_p_size = max_regno; reg_info_p = XCNEWVEC (struct reg_info_t, max_regno); - local_live_last_luid = XNEWVEC (int, max_regno); FOR_EACH_BB_FN (bb, cfun) { - regstat_bb_compute_ri (bb->index, live, artificial_uses, - local_live, local_processed, - local_live_last_luid); + regstat_bb_compute_ri (bb, live); } BITMAP_FREE (live); - BITMAP_FREE (artificial_uses); - BITMAP_FREE (local_live); - BITMAP_FREE (local_processed); - free (local_live_last_luid); /* See the setjmp comment in regstat_bb_compute_ri. */ EXECUTE_IF_SET_IN_BITMAP (setjmp_crosses, FIRST_PSEUDO_REGISTER, regno, bi) { REG_BASIC_BLOCK (regno) = REG_BLOCK_UNKNOWN; - REG_LIVE_LENGTH (regno) = -1; } timevar_pop (TV_REG_STATS); @@ -533,11 +423,11 @@ dump_reg_info (FILE *file) enum reg_class rclass, altclass; if (regstat_n_sets_and_refs) - fprintf (file, "\nRegister %d used %d times across %d insns", - i, REG_N_REFS (i), REG_LIVE_LENGTH (i)); + fprintf (file, "\nRegister %d used %d times", + i, REG_N_REFS (i)); else if (df) - fprintf (file, "\nRegister %d used %d times across %d insns", - i, DF_REG_USE_COUNT (i) + DF_REG_DEF_COUNT (i), REG_LIVE_LENGTH (i)); + fprintf (file, "\nRegister %d used %d times", + i, DF_REG_USE_COUNT (i) + DF_REG_DEF_COUNT (i)); if (REG_BASIC_BLOCK (i) >= NUM_FIXED_BLOCKS) fprintf (file, " in block %d", REG_BASIC_BLOCK (i));