OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / regstat.c
index cfd904f..abe6caf 100644 (file)
@@ -1,5 +1,5 @@
 /* Scanning of rtl for dataflow analysis.
-   Copyright (C) 2007
+   Copyright (C) 2007, 2008, 2009
    Free Software Foundation, Inc.
    Contributed by Kenneth Zadeck (zadeck@naturalbridge.com).
 
@@ -7,7 +7,7 @@ This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -16,10 +16,8 @@ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA.
-*/
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 
 #include "config.h"
@@ -39,10 +37,9 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 
 
 struct regstat_n_sets_and_refs_t *regstat_n_sets_and_refs;
-struct regstat_n_sets_and_refs_t *regstat_n_sets_and_refs;
 
 /*----------------------------------------------------------------------------
-   REG_N_SETS and REG_N_REFS.  
+   REG_N_SETS and REG_N_REFS.
    ----------------------------------------------------------------------------*/
 
 /* If a pass need to change these values in some magical way or or the
@@ -62,13 +59,29 @@ regstat_init_n_sets_and_refs (void)
   df_grow_reg_info ();
   gcc_assert (!regstat_n_sets_and_refs);
 
-  regstat_n_sets_and_refs = xmalloc (max_regno * sizeof (struct regstat_n_sets_and_refs_t));
-
-  for (i = 0; i < max_regno; i++)
-    {
-      SET_REG_N_SETS (i, DF_REG_DEF_COUNT (i));
-      SET_REG_N_REFS (i, DF_REG_USE_COUNT (i) + REG_N_SETS (i));
-    }
+  regstat_n_sets_and_refs = XNEWVEC (struct regstat_n_sets_and_refs_t, max_regno);
+
+  if (MAY_HAVE_DEBUG_INSNS)
+    for (i = 0; i < max_regno; i++)
+      {
+       int use_count;
+       df_ref use;
+
+       use_count = DF_REG_USE_COUNT (i);
+       for (use = DF_REG_USE_CHAIN (i); use; use = DF_REF_NEXT_REG (use))
+         if (DF_REF_INSN_INFO (use) && DEBUG_INSN_P (DF_REF_INSN (use)))
+           use_count--;
+
+
+       SET_REG_N_SETS (i, DF_REG_DEF_COUNT (i));
+       SET_REG_N_REFS (i, use_count + REG_N_SETS (i));
+      }
+  else
+    for (i = 0; i < max_regno; i++)
+      {
+       SET_REG_N_SETS (i, DF_REG_DEF_COUNT (i));
+       SET_REG_N_REFS (i, DF_REG_USE_COUNT (i) + REG_N_SETS (i));
+      }
   timevar_pop (TV_REG_STATS);
 
 }
@@ -104,14 +117,14 @@ size_t reg_info_p_size;
    here.  */
 
 static void
-regstat_bb_compute_ri (unsigned int bb_index, 
+regstat_bb_compute_ri (unsigned int bb_index,
                       bitmap live, bitmap do_not_gen, bitmap artificial_uses,
                       bitmap local_live, bitmap local_processed)
 {
   basic_block bb = BASIC_BLOCK (bb_index);
   rtx insn;
-  struct df_ref **def_rec;
-  struct df_ref **use_rec;
+  df_ref *def_rec;
+  df_ref *use_rec;
   int luid = 0;
   bitmap_iterator bi;
   unsigned int regno;
@@ -128,14 +141,14 @@ regstat_bb_compute_ri (unsigned int bb_index,
      to begin processing.  */
   for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++)
     {
-      struct df_ref *def = *def_rec;
+      df_ref def = *def_rec;
       if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
        bitmap_clear_bit (live, DF_REF_REGNO (def));
     }
 
   for (use_rec = df_get_artificial_uses (bb_index); *use_rec; use_rec++)
     {
-      struct df_ref *use = *use_rec;
+      df_ref use = *use_rec;
       if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0)
        {
          regno = DF_REF_REGNO (use);
@@ -143,7 +156,7 @@ regstat_bb_compute_ri (unsigned int bb_index,
          bitmap_set_bit (artificial_uses, regno);
        }
     }
-  
+
   FOR_BB_INSNS_REVERSE (bb, insn)
     {
       unsigned int uid = INSN_UID (insn);
@@ -151,8 +164,8 @@ regstat_bb_compute_ri (unsigned int bb_index,
       bitmap_iterator bi;
       struct df_mw_hardreg **mws_rec;
       rtx link;
-      if (!INSN_P (insn))
+
+      if (!NONDEBUG_INSN_P (insn))
        continue;
 
       /* Increment the live_length for all of the registers that
@@ -163,7 +176,7 @@ regstat_bb_compute_ri (unsigned int bb_index,
          REG_LIVE_LENGTH (regno)++;
        }
       luid++;
-  
+
       bitmap_clear (do_not_gen);
 
       link = REG_NOTES (insn);
@@ -177,14 +190,15 @@ regstat_bb_compute_ri (unsigned int bb_index,
       /* Process the defs.  */
       if (CALL_P (insn))
        {
-         bool can_throw = can_throw_internal (insn); 
+         bool can_throw = can_throw_internal (insn);
          bool set_jump = (find_reg_note (insn, REG_SETJMP, NULL) != NULL);
          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)++;
-             
+
              /* We have a problem with any pseudoreg that lives
                 across the setjmp.  ANSI says that if a user variable
                 does not change in value between the setjmp and the
@@ -200,17 +214,17 @@ regstat_bb_compute_ri (unsigned int bb_index,
                bitmap_set_bit (setjmp_crosses, regno);
            }
        }
-         
+
       /* We only care about real sets for calls.  Clobbers only
         may clobbers cannot be depended on.  */
       for (mws_rec = DF_INSN_UID_MWS (uid); *mws_rec; mws_rec++)
        {
-         struct df_mw_hardreg *mws = *mws_rec; 
-         if (mws->type == DF_REF_REG_DEF) 
+         struct df_mw_hardreg *mws = *mws_rec;
+         if (DF_MWS_REG_DEF_P (mws))
            {
              bool all_dead = true;
              unsigned int r;
-             
+
              for (r=mws->start_regno; r <= mws->end_regno; r++)
                if ((bitmap_bit_p (live, r))
                    || bitmap_bit_p (artificial_uses, r))
@@ -218,7 +232,7 @@ regstat_bb_compute_ri (unsigned int bb_index,
                    all_dead = false;
                    break;
                  }
-             
+
              if (all_dead)
                {
                  unsigned int regno = mws->start_regno;
@@ -228,17 +242,17 @@ regstat_bb_compute_ri (unsigned int bb_index,
                }
            }
        }
-      
+
       /* All of the defs except the return value are some sort of
         clobber.  This code is for the return.  */
       for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
        {
-         struct df_ref *def = *def_rec;
+         df_ref def = *def_rec;
          if ((!CALL_P (insn))
              || (!(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 this regno, then it has already been
@@ -261,7 +275,7 @@ regstat_bb_compute_ri (unsigned int bb_index,
                {
                  REG_LIVE_LENGTH (dregno)++;
                }
-             
+
              if (dregno >= FIRST_PSEUDO_REGISTER)
                {
                  REG_FREQ (dregno) += REG_FREQ_FROM_BB (bb);
@@ -270,19 +284,19 @@ regstat_bb_compute_ri (unsigned int bb_index,
                  else if (REG_BASIC_BLOCK (dregno) != bb->index)
                    REG_BASIC_BLOCK (dregno) = REG_BLOCK_GLOBAL;
                }
-             
+
              if (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER + DF_REF_MAY_CLOBBER)))
                bitmap_set_bit (do_not_gen, dregno);
-             
+
              /* Kill this register if it is not a subreg store or conditional store.  */
              if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)))
                bitmap_clear_bit (live, dregno);
            }
        }
-      
+
       for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++)
        {
-         struct df_ref *use = *use_rec;
+         df_ref use = *use_rec;
          unsigned int uregno = DF_REF_REGNO (use);
 
          if (uregno >= FIRST_PSEUDO_REGISTER)
@@ -293,11 +307,10 @@ 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_bit_p (live, uregno))
+
+         if (bitmap_set_bit (live, uregno))
            {
              /* This register is now live.  */
-             bitmap_set_bit (live, uregno);
 
              /* If we have seen this regno, then it has already been
                 processed correctly with the per insn increment.  If
@@ -312,7 +325,7 @@ regstat_bb_compute_ri (unsigned int bb_index,
            }
        }
     }
-  
+
   /* 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);
@@ -345,7 +358,7 @@ regstat_compute_ri (void)
   setjmp_crosses = BITMAP_ALLOC (&df_bitmap_obstack);
   max_regno = max_reg_num ();
   reg_info_p_size = max_regno;
-  reg_info_p = xcalloc (max_regno, sizeof (struct reg_info_t));
+  reg_info_p = XCNEWVEC (struct reg_info_t, max_regno);
 
   FOR_EACH_BB (bb)
     {
@@ -362,8 +375,8 @@ regstat_compute_ri (void)
     {
       REG_BASIC_BLOCK (regno) = REG_BLOCK_UNKNOWN;
       REG_LIVE_LENGTH (regno) = -1;
-    }    
-  
+    }
+
   BITMAP_FREE (local_live);
   BITMAP_FREE (local_processed);
   timevar_pop (TV_REG_STATS);
@@ -377,14 +390,14 @@ regstat_free_ri (void)
 {
   gcc_assert (reg_info_p);
   reg_info_p_size = 0;
-  free (reg_info_p); 
+  free (reg_info_p);
   reg_info_p = NULL;
 
   BITMAP_FREE (setjmp_crosses);
 }
 
 
-/* Return a bitmap containing the set of registers that cross a setjmp.  
+/* Return a bitmap containing the set of registers that cross a setjmp.
    The client should not change or delete this bitmap.  */
 
 bitmap
@@ -394,10 +407,10 @@ regstat_get_setjmp_crosses (void)
 }
 
 /*----------------------------------------------------------------------------
-   Process REG_N_CALLS_CROSSED.  
+   Process REG_N_CALLS_CROSSED.
 
    This is used by sched_deps.  A good implementation of sched-deps
-   would really process the blocks directly rather than going thur
+   would really process the blocks directly rather than going through
    lists of insns.  If it did this, it could use the exact regs that
    cross an individual call rather than using this info that merges
    the info for all calls.
@@ -406,15 +419,15 @@ regstat_get_setjmp_crosses (void)
 
 
 
-/* Compute callse crossed for BB. Live is a scratch bitvector.  */
+/* Compute calls crossed for BB. Live is a scratch bitvector.  */
 
 static void
 regstat_bb_compute_calls_crossed (unsigned int bb_index, bitmap live)
 {
   basic_block bb = BASIC_BLOCK (bb_index);
   rtx insn;
-  struct df_ref **def_rec;
-  struct df_ref **use_rec;
+  df_ref *def_rec;
+  df_ref *use_rec;
 
   bitmap_copy (live, df_get_live_out (bb));
 
@@ -422,23 +435,23 @@ regstat_bb_compute_calls_crossed (unsigned int bb_index, bitmap live)
      to begin processing.  */
   for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++)
     {
-      struct df_ref *def = *def_rec;
+      df_ref def = *def_rec;
       if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
        bitmap_clear_bit (live, DF_REF_REGNO (def));
     }
 
   for (use_rec = df_get_artificial_uses (bb_index); *use_rec; use_rec++)
     {
-      struct df_ref *use = *use_rec;
+      df_ref use = *use_rec;
       if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0)
        bitmap_set_bit (live, DF_REF_REGNO (use));
     }
-  
+
   FOR_BB_INSNS_REVERSE (bb, insn)
     {
       unsigned int uid = INSN_UID (insn);
       unsigned int regno;
+
       if (!INSN_P (insn))
        continue;
 
@@ -447,14 +460,17 @@ 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
         clobber.  This code is for the return.  */
       for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
        {
-         struct df_ref *def = *def_rec;
+         df_ref def = *def_rec;
          if ((!CALL_P (insn))
              || (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER))))
            {
@@ -463,10 +479,10 @@ regstat_bb_compute_calls_crossed (unsigned int bb_index, bitmap live)
                bitmap_clear_bit (live, DF_REF_REGNO (def));
            }
        }
-      
+
       for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++)
        {
-         struct df_ref *use = *use_rec;
+         df_ref use = *use_rec;
          bitmap_set_bit (live, DF_REF_REGNO (use));
        }
     }
@@ -486,7 +502,7 @@ regstat_compute_calls_crossed (void)
   timevar_push (TV_REG_STATS);
   max_regno = max_reg_num ();
   reg_info_p_size = max_regno;
-  reg_info_p = xcalloc (max_regno, sizeof (struct reg_info_t));
+  reg_info_p = XCNEWVEC (struct reg_info_t, max_regno);
 
   FOR_EACH_BB (bb)
     {
@@ -505,7 +521,7 @@ regstat_free_calls_crossed (void)
 {
   gcc_assert (reg_info_p);
   reg_info_p_size = 0;
-  free (reg_info_p); 
+  free (reg_info_p);
   reg_info_p = NULL;
 }