OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / regstat.c
index d6e3989..bfd743b 100644 (file)
@@ -1,5 +1,5 @@
 /* Scanning of rtl for dataflow analysis.
-   Copyright (C) 2007
+   Copyright (C) 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
    Contributed by Kenneth Zadeck (zadeck@naturalbridge.com).
 
@@ -37,13 +37,12 @@ along with GCC; see the file COPYING3.  If not see
 
 
 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
+/* If a pass need to change these values in some magical way or the
    pass needs to have accurate values for these and is not using
    incremental df scanning, then it should use REG_N_SETS and
    REG_N_USES.  If the pass is doing incremental scanning then it
@@ -62,11 +61,27 @@ regstat_init_n_sets_and_refs (void)
 
   regstat_n_sets_and_refs = XNEWVEC (struct regstat_n_sets_and_refs_t, max_regno);
 
-  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));
-    }
+  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);
 
 }
@@ -102,7 +117,7 @@ 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)
 {
@@ -141,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);
@@ -149,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
@@ -161,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);
@@ -175,7 +190,7 @@ 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)
            {
@@ -183,7 +198,7 @@ regstat_bb_compute_ri (unsigned int bb_index,
              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
@@ -199,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 (DF_MWS_REG_DEF_P (mws)) 
+         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))
@@ -217,7 +232,7 @@ regstat_bb_compute_ri (unsigned int bb_index,
                    all_dead = false;
                    break;
                  }
-             
+
              if (all_dead)
                {
                  unsigned int regno = mws->start_regno;
@@ -227,7 +242,7 @@ 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++)
@@ -237,7 +252,7 @@ regstat_bb_compute_ri (unsigned int bb_index,
              || (!(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
@@ -260,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);
@@ -269,16 +284,16 @@ 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++)
        {
          df_ref use = *use_rec;
@@ -292,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
@@ -311,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);
@@ -361,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);
@@ -376,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
@@ -393,7 +407,7 @@ 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 through
@@ -432,12 +446,12 @@ regstat_bb_compute_calls_crossed (unsigned int bb_index, bitmap live)
       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;
 
@@ -451,7 +465,7 @@ regstat_bb_compute_calls_crossed (unsigned int bb_index, bitmap live)
              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++)
@@ -465,7 +479,7 @@ 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++)
        {
          df_ref use = *use_rec;
@@ -507,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;
 }