OSDN Git Service

PR rtl-optimization/31396
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 16 Jan 2008 16:32:05 +0000 (16:32 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 16 Jan 2008 16:32:05 +0000 (16:32 +0000)
* regstat.c (regstat_bb_compute_ri): Compute FREQ_CALLS_CROSSED.
* cfg.c (dump_reg_info): Print it.
* regs.h (struct reg_info_t): add freq_calls_crossed.
(REG_FREQ_CALLS_CROSSED): New macro.
* global.c (global_alloc): Compute freq_calls_crossed for allocno.
(find_reg): Update call of CALLER_SAVE_PROFITABLE.
* regmove.c (optimize_reg_copy_1, optimize_reg_copy_2, fixup_match_2,
regmove_optimize): Update call crossed frequencies.
* local-alloc.c (struct qty): Add freq_calls_crossed.
(alloc_qty): Copute freq_calls_crossed.
(update_equiv_regs, combine_regs): Update REG_FREQ_CALLS_CROSSED.
(find_free_reg): Update call of CALLER_SAVE_PROFITABLE.
* ra.h (struct allocno): Add freq_calls_crossed.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@131576 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cfg.c
gcc/global.c
gcc/local-alloc.c
gcc/ra.h
gcc/regmove.c
gcc/regs.h
gcc/regstat.c

index 37a6f4e..8e2caec 100644 (file)
@@ -1,3 +1,20 @@
+2008-01-16  Jan Hubicka  <jh@suse.cz>
+
+       PR rtl-optimization/31396
+       * regstat.c (regstat_bb_compute_ri): Compute FREQ_CALLS_CROSSED.
+       * cfg.c (dump_reg_info): Print it.
+       * regs.h (struct reg_info_t): add freq_calls_crossed.
+       (REG_FREQ_CALLS_CROSSED): New macro.
+       * global.c (global_alloc): Compute freq_calls_crossed for allocno.
+       (find_reg): Update call of CALLER_SAVE_PROFITABLE.
+       * regmove.c (optimize_reg_copy_1, optimize_reg_copy_2, fixup_match_2,
+       regmove_optimize): Update call crossed frequencies.
+       * local-alloc.c (struct qty): Add freq_calls_crossed.
+       (alloc_qty): Copute freq_calls_crossed.
+       (update_equiv_regs, combine_regs): Update REG_FREQ_CALLS_CROSSED.
+       (find_free_reg): Update call of CALLER_SAVE_PROFITABLE.
+       * ra.h (struct allocno): Add freq_calls_crossed.
+
 2008-01-16  Sebastian Pop  <sebastian.pop@amd.com>
 
        * gcc.c (LINK_COMMAND_SPEC): Add includes and link options for
index 0b0e950..8a83137 100644 (file)
--- a/gcc/cfg.c
+++ b/gcc/cfg.c
@@ -613,6 +613,8 @@ dump_reg_info (FILE *file)
        fprintf (file, "; crosses 1 call");
       else if (REG_N_CALLS_CROSSED (i))
        fprintf (file, "; crosses %d calls", REG_N_CALLS_CROSSED (i));
+      if (REG_FREQ_CALLS_CROSSED (i))
+       fprintf (file, "; crosses call with %d frequency", REG_FREQ_CALLS_CROSSED (i));
       if (regno_reg_rtx[i] != NULL
          && PSEUDO_REGNO_BYTES (i) != UNITS_PER_WORD)
        fprintf (file, "; %d bytes", PSEUDO_REGNO_BYTES (i));
index de6beb9..8be113d 100644 (file)
@@ -404,6 +404,7 @@ global_alloc (void)
       allocno[i].reg = regno;
       allocno[i].size = PSEUDO_REGNO_SIZE (regno);
       allocno[i].calls_crossed += REG_N_CALLS_CROSSED (regno);
+      allocno[i].freq_calls_crossed += REG_FREQ_CALLS_CROSSED (regno);
       allocno[i].throwing_calls_crossed
        += REG_N_THROWING_CALLS_CROSSED (regno);
       allocno[i].n_refs += REG_N_REFS (regno);
@@ -1164,8 +1165,9 @@ find_reg (int num, HARD_REG_SET losers, int alt_regs_p, int accept_call_clobbere
       if (! accept_call_clobbered
          && allocno[num].calls_crossed != 0
          && allocno[num].throwing_calls_crossed == 0
-         && CALLER_SAVE_PROFITABLE (allocno[num].n_refs,
-                                    allocno[num].calls_crossed))
+         && CALLER_SAVE_PROFITABLE (optimize_size ? allocno[num].n_refs : allocno[num].freq,
+                                    optimize_size ? allocno[num].calls_crossed
+                                    : allocno[num].freq_calls_crossed))
        {
          HARD_REG_SET new_losers;
          if (! losers)
index 4ef1f02..9569a36 100644 (file)
@@ -126,6 +126,10 @@ struct qty
 
   int n_calls_crossed;
 
+  /* Number of times a reg tied to given qty lives across a CALL_INSN.  */
+
+  int freq_calls_crossed;
+
   /* Number of times a reg tied to given qty lives across a CALL_INSN
      that might throw.  */
 
@@ -332,6 +336,7 @@ alloc_qty (int regno, enum machine_mode mode, int size, int birth)
   qty[qtyno].mode = mode;
   qty[qtyno].birth = birth;
   qty[qtyno].n_calls_crossed = REG_N_CALLS_CROSSED (regno);
+  qty[qtyno].freq_calls_crossed = REG_FREQ_CALLS_CROSSED (regno);
   qty[qtyno].n_throwing_calls_crossed = REG_N_THROWING_CALLS_CROSSED (regno);
   qty[qtyno].min_class = reg_preferred_class (regno);
   qty[qtyno].alternate_class = reg_alternate_class (regno);
@@ -1193,6 +1198,7 @@ update_equiv_regs (void)
 
                      REG_BASIC_BLOCK (regno) = bb->index;
                      REG_N_CALLS_CROSSED (regno) = 0;
+                     REG_FREQ_CALLS_CROSSED (regno) = 0;
                      REG_N_THROWING_CALLS_CROSSED (regno) = 0;
                      REG_LIVE_LENGTH (regno) = 2;
 
@@ -2026,6 +2032,7 @@ combine_regs (rtx usedreg, rtx setreg, int may_save_copy, int insn_number,
 
       /* Update info about quantity SQTY.  */
       qty[sqty].n_calls_crossed += REG_N_CALLS_CROSSED (sreg);
+      qty[sqty].freq_calls_crossed += REG_FREQ_CALLS_CROSSED (sreg);
       qty[sqty].n_throwing_calls_crossed
        += REG_N_THROWING_CALLS_CROSSED (sreg);
       qty[sqty].n_refs += REG_N_REFS (sreg);
@@ -2338,8 +2345,9 @@ find_free_reg (enum reg_class class, enum machine_mode mode, int qtyno,
       && ! just_try_suggested
       && qty[qtyno].n_calls_crossed != 0
       && qty[qtyno].n_throwing_calls_crossed == 0
-      && CALLER_SAVE_PROFITABLE (qty[qtyno].n_refs,
-                                qty[qtyno].n_calls_crossed))
+      && CALLER_SAVE_PROFITABLE (optimize_size ? qty[qtyno].n_refs : qty[qtyno].freq,
+                                optimize_size ? qty[qtyno].n_calls_crossed
+                                : qty[qtyno].freq_calls_crossed))
     {
       i = find_free_reg (class, mode, qtyno, 1, 0, born_index, dead_index);
       if (i >= 0)
index d35d201..4081df3 100644 (file)
--- a/gcc/ra.h
+++ b/gcc/ra.h
@@ -32,6 +32,9 @@ struct allocno
   /* Number of calls crossed by each allocno.  */
   int calls_crossed;
 
+  /* Estimated frequency of crossing call by each allocno.  */
+  int freq_calls_crossed;
+
   /* Number of calls that might throw crossed by each allocno.  */
   int throwing_calls_crossed;
 
index 4cb083c..9a07187 100644 (file)
@@ -506,6 +506,8 @@ optimize_reg_copy_1 (rtx insn, rtx dest, rtx src)
          int s_length = 0;
          int d_n_calls = 0;
          int s_n_calls = 0;
+         int s_freq_calls = 0;
+         int d_freq_calls = 0;
 
          /* We can do the optimization.  Scan forward from INSN again,
             replacing regs as we go.  Set FAILED if a replacement can't
@@ -556,8 +558,12 @@ optimize_reg_copy_1 (rtx insn, rtx dest, rtx src)
                  /* Similarly, total calls for SREGNO, total calls beyond
                     the death note for DREGNO.  */
                  s_n_calls++;
+                 s_freq_calls += REG_FREQ_FROM_BB  (BLOCK_FOR_INSN (q));
                  if (dest_death)
-                   d_n_calls++;
+                   {
+                     d_n_calls++;
+                     d_freq_calls += REG_FREQ_FROM_BB  (BLOCK_FOR_INSN (q));
+                   }
                }
 
              /* If DEST dies here, remove the death note and save it for
@@ -590,6 +596,7 @@ optimize_reg_copy_1 (rtx insn, rtx dest, rtx src)
                    }
 
                  REG_N_CALLS_CROSSED (sregno) -= s_n_calls;
+                 REG_FREQ_CALLS_CROSSED (sregno) -= s_freq_calls;
                }
 
              /* Move death note of SRC from P to INSN.  */
@@ -619,6 +626,7 @@ optimize_reg_copy_1 (rtx insn, rtx dest, rtx src)
                  if (REG_LIVE_LENGTH (dregno) >= 0)
                    REG_LIVE_LENGTH (dregno) += d_length;
                  REG_N_CALLS_CROSSED (dregno) += d_n_calls;
+                 REG_FREQ_CALLS_CROSSED (dregno) += d_freq_calls;
                }
            }
 
@@ -684,8 +692,11 @@ optimize_reg_copy_2 (rtx insn, rtx dest, rtx src)
 
                if (CALL_P (q))
                  {
+                   int freq = REG_FREQ_FROM_BB  (BLOCK_FOR_INSN (q));
                    REG_N_CALLS_CROSSED (dregno)--;
                    REG_N_CALLS_CROSSED (sregno)++;
+                   REG_FREQ_CALLS_CROSSED (dregno) -= freq;
+                   REG_FREQ_CALLS_CROSSED (sregno) += freq;
                  }
              }
 
@@ -953,7 +964,7 @@ static int
 fixup_match_2 (rtx insn, rtx dst, rtx src, rtx offset)
 {
   rtx p, dst_death = 0;
-  int length, num_calls = 0;
+  int length, num_calls = 0, freq_calls = 0;
 
   /* If SRC dies in INSN, we'd have to move the death note.  This is
      considered to be very unlikely, so we just skip the optimization
@@ -997,6 +1008,7 @@ fixup_match_2 (rtx insn, rtx dst, rtx src, rtx offset)
                  remove_death (REGNO (dst), dst_death);
                  REG_LIVE_LENGTH (REGNO (dst)) += length;
                  REG_N_CALLS_CROSSED (REGNO (dst)) += num_calls;
+                 REG_FREQ_CALLS_CROSSED (REGNO (dst)) += freq_calls;
                }
 
              if (dump_file)
@@ -1049,7 +1061,10 @@ fixup_match_2 (rtx insn, rtx dst, rtx src, rtx offset)
       if (CALL_P (p))
        {
          if (! dst_death)
-           num_calls++;
+           {
+             num_calls++;
+             freq_calls += REG_FREQ_FROM_BB  (BLOCK_FOR_INSN (p));
+           }
 
          if (REG_N_CALLS_CROSSED (REGNO (src)) == 0)
            break;
@@ -1276,7 +1291,7 @@ regmove_optimize (rtx f, int nregs)
            {
              rtx set, p, src, dst;
              rtx src_note, dst_note;
-             int num_calls = 0;
+             int num_calls = 0, freq_calls = 0;
              enum reg_class src_class, dst_class;
              int length;
 
@@ -1465,6 +1480,7 @@ regmove_optimize (rtx f, int nregs)
                  if (CALL_P (p))
                    {
                      num_calls++;
+                     freq_calls += REG_FREQ_FROM_BB  (BLOCK_FOR_INSN (p));
 
                      if (REG_N_CALLS_CROSSED (REGNO (dst)) == 0)
                        break;
@@ -1497,6 +1513,8 @@ regmove_optimize (rtx f, int nregs)
 
                  REG_N_CALLS_CROSSED (dstno) += num_calls;
                  REG_N_CALLS_CROSSED (srcno) -= num_calls;
+                 REG_FREQ_CALLS_CROSSED (dstno) += freq_calls;
+                 REG_FREQ_CALLS_CROSSED (srcno) -= freq_calls;
 
                  REG_LIVE_LENGTH (dstno) += length;
                  if (REG_LIVE_LENGTH (srcno) >= 0)
index 192883b..f0679f7 100644 (file)
@@ -115,6 +115,7 @@ struct reg_info_t
   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 */
   int basic_block;             /* # of basic blocks (REG n) is used in */
 };
@@ -172,6 +173,7 @@ extern size_t reg_info_p_size;
 /* Indexed by N, gives number of CALL_INSNS across which (REG n) is live.  */
 
 #define REG_N_CALLS_CROSSED(N)  (reg_info_p[N].calls_crossed)
+#define REG_FREQ_CALLS_CROSSED(N)  (reg_info_p[N].freq_calls_crossed)
 
 /* Indexed by N, gives number of CALL_INSNS that may throw, across which
    (REG n) is live.  */
index 9f8e41f..26f9607 100644 (file)
@@ -180,6 +180,7 @@ regstat_bb_compute_ri (unsigned int bb_index,
          EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi)
            {
              REG_N_CALLS_CROSSED (regno)++;
+             REG_FREQ_CALLS_CROSSED (regno) += REG_FREQ_FROM_BB (bb);
              if (can_throw)
                REG_N_THROWING_CALLS_CROSSED (regno)++;
              
@@ -445,7 +446,10 @@ regstat_bb_compute_calls_crossed (unsigned int bb_index, bitmap live)
        {
          bitmap_iterator bi;
          EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi)
-           REG_N_CALLS_CROSSED (regno)++;
+           {
+             REG_N_CALLS_CROSSED (regno)++;
+             REG_FREQ_CALLS_CROSSED (regno) += REG_FREQ_FROM_BB (bb);
+           }
        }
          
       /* All of the defs except the return value are some sort of