OSDN Git Service

Add forgotten ChangeLog entries.
[pf3gnuchains/gcc-fork.git] / gcc / profile.c
index 6aca917..ac46046 100644 (file)
@@ -1,6 +1,6 @@
 /* Calculate branch probabilities, and basic block execution counts.
    Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
+   2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
    Free Software Foundation, Inc.
    Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
    based on some ideas from Dain Samples of UC Berkeley.
@@ -100,7 +100,6 @@ static int total_num_blocks_created;
 static int total_num_passes;
 static int total_num_times_called;
 static int total_hist_br_prob[20];
-static int total_num_never_executed;
 static int total_num_branches;
 
 /* Forward declarations.  */
@@ -277,8 +276,20 @@ is_edge_inconsistent (VEC(edge,gc) *edges)
     {
       if (!EDGE_INFO (e)->ignore)
         {
-          if (e->count < 0)
-            return true;
+          if (e->count < 0
+             && (!(e->flags & EDGE_FAKE)
+                 || !block_ends_with_call_p (e->src)))
+           {
+             if (dump_file)
+               {
+                 fprintf (dump_file,
+                          "Edge %i->%i is inconsistent, count"HOST_WIDEST_INT_PRINT_DEC,
+                          e->src->index, e->dest->index, e->count);
+                 dump_bb (e->src, dump_file, 0);
+                 dump_bb (e->dest, dump_file, 0);
+               }
+              return true;
+           }
         }
     }
   return false;
@@ -307,20 +318,59 @@ static bool
 is_inconsistent (void)
 {
   basic_block bb;
+  bool inconsistent = false;
   FOR_EACH_BB (bb)
     {
-      if (is_edge_inconsistent (bb->preds))
-        return true;
-      if (is_edge_inconsistent (bb->succs))
-        return true;
-      if ( bb->count != sum_edge_counts (bb->preds)
-         || (bb->count != sum_edge_counts (bb->succs) &&
-             !(find_edge (bb, EXIT_BLOCK_PTR) != NULL &&
-               block_ends_with_call_p (bb))))
-        return true;
+      inconsistent |= is_edge_inconsistent (bb->preds);
+      if (!dump_file && inconsistent)
+       return true;
+      inconsistent |= is_edge_inconsistent (bb->succs);
+      if (!dump_file && inconsistent)
+       return true;
+      if (bb->count < 0)
+        {
+         if (dump_file)
+           {
+             fprintf (dump_file, "BB %i count is negative "
+                      HOST_WIDEST_INT_PRINT_DEC,
+                      bb->index,
+                      bb->count);
+             dump_bb (bb, dump_file, 0);
+           }
+         inconsistent = true;
+       }
+      if (bb->count != sum_edge_counts (bb->preds))
+        {
+         if (dump_file)
+           {
+             fprintf (dump_file, "BB %i count does not match sum of incoming edges "
+                      HOST_WIDEST_INT_PRINT_DEC" should be " HOST_WIDEST_INT_PRINT_DEC,
+                      bb->index,
+                      bb->count,
+                      sum_edge_counts (bb->preds));
+             dump_bb (bb, dump_file, 0);
+           }
+         inconsistent = true;
+       }
+      if (bb->count != sum_edge_counts (bb->succs) &&
+          ! (find_edge (bb, EXIT_BLOCK_PTR) != NULL && block_ends_with_call_p (bb)))
+       {
+         if (dump_file)
+           {
+             fprintf (dump_file, "BB %i count does not match sum of outgoing edges "
+                      HOST_WIDEST_INT_PRINT_DEC" should be " HOST_WIDEST_INT_PRINT_DEC,
+                      bb->index,
+                      bb->count,
+                      sum_edge_counts (bb->succs));
+             dump_bb (bb, dump_file, 0);
+           }
+         inconsistent = true;
+       }
+      if (!dump_file && inconsistent)
+       return true;
     }
 
-  return false;
+  return inconsistent;
 }
 
 /* Set each basic block count to the sum of its outgoing edge counts */
@@ -396,25 +446,23 @@ compute_branch_probabilities (void)
   int changes;
   int passes;
   int hist_br_prob[20];
-  int num_never_executed;
   int num_branches;
   gcov_type *exec_counts = get_exec_counts ();
   int inconsistent = 0;
 
   /* Very simple sanity checks so we catch bugs in our profiling code.  */
-  if (profile_info)
+  if (!profile_info)
+    return;
+  if (profile_info->run_max * profile_info->runs < profile_info->sum_max)
     {
-      if (profile_info->run_max * profile_info->runs < profile_info->sum_max)
-        {
-          error ("corrupted profile info: run_max * runs < sum_max");
-          exec_counts = NULL;
-        }
+      error ("corrupted profile info: run_max * runs < sum_max");
+      exec_counts = NULL;
+    }
 
-      if (profile_info->sum_all < profile_info->sum_max)
-        {
-          error ("corrupted profile info: sum_all is smaller than sum_max");
-          exec_counts = NULL;
-        }
+  if (profile_info->sum_all < profile_info->sum_max)
+    {
+      error ("corrupted profile info: sum_all is smaller than sum_max");
+      exec_counts = NULL;
     }
 
   /* Attach extra info block to each bb.  */
@@ -597,7 +645,6 @@ compute_branch_probabilities (void)
 
   for (i = 0; i < 20; i++)
     hist_br_prob[i] = 0;
-  num_never_executed = 0;
   num_branches = 0;
 
   FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, NULL, next_bb)
@@ -691,16 +738,15 @@ compute_branch_probabilities (void)
          if (bb->index >= NUM_FIXED_BLOCKS
              && block_ends_with_condjump_p (bb)
              && EDGE_COUNT (bb->succs) >= 2)
-           num_branches++, num_never_executed;
+           num_branches++;
        }
     }
   counts_to_freqs ();
+  profile_status = PROFILE_READ;
 
   if (dump_file)
     {
       fprintf (dump_file, "%d branches\n", num_branches);
-      fprintf (dump_file, "%d branches never executed\n",
-              num_never_executed);
       if (num_branches)
        for (i = 0; i < 10; i++)
          fprintf (dump_file, "%d%% branches in range %d-%d%%\n",
@@ -708,7 +754,6 @@ compute_branch_probabilities (void)
                   5 * i, 5 * i + 5);
 
       total_num_branches += num_branches;
-      total_num_never_executed += num_never_executed;
       for (i = 0; i < 20; i++)
        total_hist_br_prob[i] += hist_br_prob[i];
 
@@ -730,7 +775,7 @@ compute_value_histograms (histogram_values values)
   gcov_type *histogram_counts[GCOV_N_VALUE_COUNTERS];
   gcov_type *act_count[GCOV_N_VALUE_COUNTERS];
   gcov_type *aact_count;
+
   for (t = 0; t < GCOV_N_VALUE_COUNTERS; t++)
     n_histogram_counters[t] = 0;
 
@@ -898,8 +943,8 @@ branch_prob (void)
            }
 
          /* Edge with goto locus might get wrong coverage info unless
-            it is the only edge out of BB.   
-            Don't do that when the locuses match, so 
+            it is the only edge out of BB.
+            Don't do that when the locuses match, so
             if (blah) goto something;
             is not computed twice.  */
          if (last
@@ -909,10 +954,12 @@ branch_prob (void)
              && (LOCATION_FILE (e->goto_locus)
                  != LOCATION_FILE (gimple_location (last))
                  || (LOCATION_LINE (e->goto_locus)
-                     != LOCATION_LINE (gimple_location  (last)))))
+                     != LOCATION_LINE (gimple_location (last)))))
            {
              basic_block new_bb = split_edge (e);
-             single_succ_edge (new_bb)->goto_locus = e->goto_locus;
+             edge ne = single_succ_edge (new_bb);
+             ne->goto_locus = e->goto_locus;
+             ne->goto_block = e->goto_block;
            }
          if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
               && e->dest != EXIT_BLOCK_PTR)
@@ -1080,7 +1127,7 @@ branch_prob (void)
 
          if (bb == ENTRY_BLOCK_PTR->next_bb)
            {
-             expanded_location curr_location = 
+             expanded_location curr_location =
                expand_location (DECL_SOURCE_LOCATION (current_function_decl));
              output_location (curr_location.file, curr_location.line,
                               &offset, bb);
@@ -1154,8 +1201,6 @@ branch_prob (void)
 
   VEC_free (histogram_value, heap, values);
   free_edge_list (el);
-  if (flag_branch_probabilities)
-    profile_status = PROFILE_READ;
   coverage_end_function ();
 }
 \f
@@ -1282,7 +1327,6 @@ init_branch_prob (void)
   total_num_passes = 0;
   total_num_times_called = 0;
   total_num_branches = 0;
-  total_num_never_executed = 0;
   for (i = 0; i < 20; i++)
     total_hist_br_prob[i] = 0;
 }
@@ -1313,8 +1357,6 @@ end_branch_prob (void)
                 / total_num_times_called);
       fprintf (dump_file, "Total number of branches: %d\n",
               total_num_branches);
-      fprintf (dump_file, "Total number of branches never executed: %d\n",
-              total_num_never_executed);
       if (total_num_branches)
        {
          int i;