diff mbox

Goodbye REG_LIVE_LENGTH

Message ID 20160325220050.GI31470@bubble.grove.modra.org
State New
Headers show

Commit Message

Alan Modra March 25, 2016, 10 p.m. UTC
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.

Comments

Bernd Schmidt March 29, 2016, 11:36 a.m. UTC | #1
On 03/25/2016 11:00 PM, Alan Modra wrote:
>> I'll also prepare a patch to delete REG_LIVE_LENGTH everywhere.
>
> Like this.  Bootstrapped and regression tested x86_64-linux.
> OK for stage1?

Oh wow that's a lot of stuff removed. Ok for this and the 
FREQ_CALLS_CROSSED patch.


Bernd
Jeff Law April 17, 2016, 7:56 p.m. UTC | #2
On 03/29/2016 05:36 AM, Bernd Schmidt wrote:
> On 03/25/2016 11:00 PM, Alan Modra wrote:
>>> I'll also prepare a patch to delete REG_LIVE_LENGTH everywhere.
>>
>> Like this.  Bootstrapped and regression tested x86_64-linux.
>> OK for stage1?
>
> Oh wow that's a lot of stuff removed. Ok for this and the
> FREQ_CALLS_CROSSED patch.
Sweet.  I suspect much of this stuff went dead with the IRA merge or at 
least fainted at that point and died with LRA merge and/or regmove 
removal.  Good to see the cleanups.

jeff
diff mbox

Patch

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));