X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fprofile.c;h=c4c7276ffe0a09d6a59b0becdaaf3852fe1e2249;hb=d94e5be7eab96e22ec7d05f44756a594443e3192;hp=761c8ad4b07a3429e14c055f53d1bd0bedf7169c;hpb=e0dc6f2bee436056af7d1c49ed2714fa53ee430d;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/profile.c b/gcc/profile.c index 761c8ad4b07..c4c7276ffe0 100644 --- a/gcc/profile.c +++ b/gcc/profile.c @@ -277,8 +277,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 +319,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 incomming 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 */ @@ -402,19 +453,18 @@ compute_branch_probabilities (void) 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. */ @@ -579,7 +629,7 @@ compute_branch_probabilities (void) if (informed == 0) { informed = 1; - inform ("correcting inconsistent profile data"); + inform (input_location, "correcting inconsistent profile data"); } correct_negative_edge_counts (); /* Set bb counts to the sum of the outgoing edge counts */ @@ -695,6 +745,7 @@ compute_branch_probabilities (void) } } counts_to_freqs (); + profile_status = PROFILE_READ; if (dump_file) { @@ -909,10 +960,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) @@ -1154,8 +1207,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 (); }