Goodbye REG_LIVE_LENGTH
authorAlan Modra <amodra@gmail.com>
Sat, 30 Apr 2016 00:01:07 +0000 (09:31 +0930)
committerAlan Modra <amodra@gcc.gnu.org>
Sat, 30 Apr 2016 00:01:07 +0000 (09:31 +0930)
* 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.

From-SVN: r235663

gcc/ChangeLog
gcc/ira.c
gcc/regs.h
gcc/regstat.c

index 9daedf3f91833e1b92f12492072079a1e3c0c139..8e93e91598897f28886008ce757a64572034613f 100644 (file)
@@ -1,3 +1,18 @@
+2016-04-30  Alan Modra  <amodra@gmail.com>
+
+       * 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.
+
 2016-04-30  Alan Modra  <amodra@gmail.com>
 
        * ira.c (enum valid_equiv): New.
index 7acf680638560e01a36e13b1ac7a5e9d649e2d80..e597604b2ead0d18e732c92585b58bd108b2794a 100644 (file)
--- 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;
index 6f992bd810b45c7a64eb1307436c205d501f4533..244250d127ccb3c85390a2374a0732ed05e83b6a 100644 (file)
@@ -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.
index c05b69f6c1a84691e46c5d7b24490ae5672eb9cb..b25a63c8258e91f70cdd1163c73bb1addeed61b0 100644 (file)
@@ -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));