Hi, does this look better? Moving to cfg.c would importing tree-pass.h and rtl.h that is not cool either. predict.c does all of these. Obviously can also go to a separate file, if preferred.
If it looks fine to you, I will commit it after testing. Honza Index: tree-pass.h =================================================================== *** tree-pass.h (revision 192158) --- tree-pass.h (working copy) *************** extern void do_per_function_toporder (vo *** 547,551 **** --- 547,553 ---- extern void disable_pass (const char *); extern void enable_pass (const char *); extern void dump_passes (void); + extern struct opt_pass **passes_by_id; + extern int passes_by_id_size; #endif /* GCC_TREE_PASS_H */ Index: predict.c =================================================================== *** predict.c (revision 192158) --- predict.c (working copy) *************** rebuild_frequencies (void) *** 2799,2801 **** --- 2799,3005 ---- gcc_unreachable (); timevar_pop (TV_REBUILD_FREQUENCIES); } + + /* Make statistic about profile consistency. */ + + struct profile_record + { + int num_mismatched_freq_in[2]; + int num_mismatched_freq_out[2]; + int num_mismatched_count_in[2]; + int num_mismatched_count_out[2]; + bool run; + gcov_type time[2]; + int size[2]; + }; + + static struct profile_record *profile_record; + + static void + check_profile_consistency (int index, int subpass, bool run) + { + basic_block bb; + edge_iterator ei; + edge e; + int sum; + gcov_type lsum; + + if (index == -1) + return; + if (!profile_record) + profile_record = XCNEWVEC (struct profile_record, + passes_by_id_size); + gcc_assert (index < passes_by_id_size && index >= 0); + gcc_assert (subpass < 2); + profile_record[index].run |= run; + + FOR_ALL_BB (bb) + { + if (bb != EXIT_BLOCK_PTR_FOR_FUNCTION (cfun) + && profile_status != PROFILE_ABSENT) + { + sum = 0; + FOR_EACH_EDGE (e, ei, bb->succs) + sum += e->probability; + if (EDGE_COUNT (bb->succs) && abs (sum - REG_BR_PROB_BASE) > 100) + profile_record[index].num_mismatched_freq_out[subpass]++; + lsum = 0; + FOR_EACH_EDGE (e, ei, bb->succs) + lsum += e->count; + if (EDGE_COUNT (bb->succs) + && (lsum - bb->count > 100 || lsum - bb->count < -100)) + profile_record[index].num_mismatched_count_out[subpass]++; + } + if (bb != ENTRY_BLOCK_PTR_FOR_FUNCTION (cfun) + && profile_status != PROFILE_ABSENT) + { + sum = 0; + FOR_EACH_EDGE (e, ei, bb->preds) + sum += EDGE_FREQUENCY (e); + if (abs (sum - bb->frequency) > 100 + || (MAX (sum, bb->frequency) > 10 + && abs ((sum - bb->frequency) * 100 / (MAX (sum, bb->frequency) + 1)) > 10)) + profile_record[index].num_mismatched_freq_in[subpass]++; + lsum = 0; + FOR_EACH_EDGE (e, ei, bb->preds) + lsum += e->count; + if (lsum - bb->count > 100 || lsum - bb->count < -100) + profile_record[index].num_mismatched_count_in[subpass]++; + } + if (bb == ENTRY_BLOCK_PTR_FOR_FUNCTION (cfun) + || bb == EXIT_BLOCK_PTR_FOR_FUNCTION (cfun)) + continue; + if ((cfun && (cfun->curr_properties & PROP_trees))) + { + gimple_stmt_iterator i; + + for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i)) + { + profile_record[index].size[subpass] + += estimate_num_insns (gsi_stmt (i), &eni_size_weights); + if (profile_status == PROFILE_READ) + profile_record[index].time[subpass] + += estimate_num_insns (gsi_stmt (i), + &eni_time_weights) * bb->count; + else if (profile_status == PROFILE_GUESSED) + profile_record[index].time[subpass] + += estimate_num_insns (gsi_stmt (i), + &eni_time_weights) * bb->frequency; + } + } + else if (cfun && (cfun->curr_properties & PROP_rtl)) + { + rtx insn; + for (insn = NEXT_INSN (BB_HEAD (bb)); insn && insn != NEXT_INSN (BB_END (bb)); + insn = NEXT_INSN (insn)) + if (INSN_P (insn)) + { + profile_record[index].size[subpass] + += insn_rtx_cost (PATTERN (insn), false); + if (profile_status == PROFILE_READ) + profile_record[index].time[subpass] + += insn_rtx_cost (PATTERN (insn), true) * bb->count; + else if (profile_status == PROFILE_GUESSED) + profile_record[index].time[subpass] + += insn_rtx_cost (PATTERN (insn), true) * bb->frequency; + } + } + } + } + + /* Output profile consistency. */ + + void + dump_profile_report (void) + { + int i, j; + int last_freq_in = 0, last_count_in = 0, last_freq_out = 0, last_count_out = 0; + gcov_type last_time = 0, last_size = 0; + double rel_time_change, rel_size_change; + int last_reported = 0; + + if (!profile_record) + return; + fprintf (stderr, "\nProfile consistency report:\n\n"); + fprintf (stderr, "Pass name |mismatch in |mismated out|Overall\n"); + fprintf (stderr, " |freq count |freq count |size time\n"); + + for (i = 0; i < passes_by_id_size; i++) + for (j = 0 ; j < 2; j++) + if (profile_record[i].run) + { + if (last_time) + rel_time_change = (profile_record[i].time[j] + - (double)last_time) * 100 / (double)last_time; + else + rel_time_change = 0; + if (last_size) + rel_size_change = (profile_record[i].size[j] + - (double)last_size) * 100 / (double)last_size; + else + rel_size_change = 0; + + if (profile_record[i].num_mismatched_freq_in[j] != last_freq_in + || profile_record[i].num_mismatched_freq_out[j] != last_freq_out + || profile_record[i].num_mismatched_count_in[j] != last_count_in + || profile_record[i].num_mismatched_count_out[j] != last_count_out + || rel_time_change || rel_size_change) + { + last_reported = i; + fprintf (stderr, "%-20s %s", + passes_by_id [i]->name, + j ? "(after TODO)" : " "); + if (profile_record[i].num_mismatched_freq_in[j] != last_freq_in) + fprintf (stderr, "| %+5i", + profile_record[i].num_mismatched_freq_in[j] + - last_freq_in); + else + fprintf (stderr, "| "); + if (profile_record[i].num_mismatched_count_in[j] != last_count_in) + fprintf (stderr, " %+5i", + profile_record[i].num_mismatched_count_in[j] + - last_count_in); + else + fprintf (stderr, " "); + if (profile_record[i].num_mismatched_freq_out[j] != last_freq_out) + fprintf (stderr, "| %+5i", + profile_record[i].num_mismatched_freq_out[j] + - last_freq_out); + else + fprintf (stderr, "| "); + if (profile_record[i].num_mismatched_count_out[j] != last_count_out) + fprintf (stderr, " %+5i", + profile_record[i].num_mismatched_count_out[j] + - last_count_out); + else + fprintf (stderr, " "); + + /* Size/time units change across gimple and RTL. */ + if (i == pass_expand.pass.static_pass_number) + fprintf (stderr, "|----------"); + else + { + if (rel_size_change) + fprintf (stderr, "| %+8.4f%%", rel_size_change); + else + fprintf (stderr, "| "); + if (rel_time_change) + fprintf (stderr, " %+8.4f%%", rel_time_change); + } + fprintf (stderr, "\n"); + last_freq_in = profile_record[i].num_mismatched_freq_in[j]; + last_freq_out = profile_record[i].num_mismatched_freq_out[j]; + last_count_in = profile_record[i].num_mismatched_count_in[j]; + last_count_out = profile_record[i].num_mismatched_count_out[j]; + } + else if (j && last_reported != i) + { + last_reported = i; + fprintf (stderr, "%-20s ------------| | |\n", + passes_by_id [i]->name); + } + last_time = profile_record[i].time[j]; + last_size = profile_record[i].size[j]; + } + } + Index: basic-block.h =================================================================== *** basic-block.h (revision 192158) --- basic-block.h (working copy) *************** extern void alloc_aux_for_edge (edge, in *** 741,746 **** --- 741,747 ---- extern void alloc_aux_for_edges (int); extern void clear_aux_for_edges (void); extern void free_aux_for_edges (void); + extern void check_profile_consistency (int, int, bool); /* In cfganal.c */ extern void find_unreachable_blocks (void); Index: passes.c =================================================================== *** passes.c (revision 192164) --- passes.c (working copy) *************** execute_function_dump (void *data ATTRIB *** 1778,1986 **** } } - /* Make statistic about profile consistency. */ - - struct profile_record - { - int num_mismatched_freq_in[2]; - int num_mismatched_freq_out[2]; - int num_mismatched_count_in[2]; - int num_mismatched_count_out[2]; - bool run; - gcov_type time[2]; - int size[2]; - }; - - static struct profile_record *profile_record; - - static void - check_profile_consistency (int index, int subpass, bool run) - { - basic_block bb; - edge_iterator ei; - edge e; - int sum; - gcov_type lsum; - - if (index == -1) - return; - if (!profile_record) - profile_record = XCNEWVEC (struct profile_record, - passes_by_id_size); - gcc_assert (index < passes_by_id_size && index >= 0); - gcc_assert (subpass < 2); - profile_record[index].run |= run; - - FOR_ALL_BB (bb) - { - if (bb != EXIT_BLOCK_PTR_FOR_FUNCTION (cfun) - && profile_status != PROFILE_ABSENT) - { - sum = 0; - FOR_EACH_EDGE (e, ei, bb->succs) - sum += e->probability; - if (EDGE_COUNT (bb->succs) && abs (sum - REG_BR_PROB_BASE) > 100) - profile_record[index].num_mismatched_freq_out[subpass]++; - lsum = 0; - FOR_EACH_EDGE (e, ei, bb->succs) - lsum += e->count; - if (EDGE_COUNT (bb->succs) - && (lsum - bb->count > 100 || lsum - bb->count < -100)) - profile_record[index].num_mismatched_count_out[subpass]++; - } - if (bb != ENTRY_BLOCK_PTR_FOR_FUNCTION (cfun) - && profile_status != PROFILE_ABSENT) - { - sum = 0; - FOR_EACH_EDGE (e, ei, bb->preds) - sum += EDGE_FREQUENCY (e); - if (abs (sum - bb->frequency) > 100 - || (MAX (sum, bb->frequency) > 10 - && abs ((sum - bb->frequency) * 100 / (MAX (sum, bb->frequency) + 1)) > 10)) - profile_record[index].num_mismatched_freq_in[subpass]++; - lsum = 0; - FOR_EACH_EDGE (e, ei, bb->preds) - lsum += e->count; - if (lsum - bb->count > 100 || lsum - bb->count < -100) - profile_record[index].num_mismatched_count_in[subpass]++; - } - if (bb == ENTRY_BLOCK_PTR_FOR_FUNCTION (cfun) - || bb == EXIT_BLOCK_PTR_FOR_FUNCTION (cfun)) - continue; - if ((cfun && (cfun->curr_properties & PROP_trees))) - { - gimple_stmt_iterator i; - - for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i)) - { - profile_record[index].size[subpass] - += estimate_num_insns (gsi_stmt (i), &eni_size_weights); - if (profile_status == PROFILE_READ) - profile_record[index].time[subpass] - += estimate_num_insns (gsi_stmt (i), - &eni_time_weights) * bb->count; - else if (profile_status == PROFILE_GUESSED) - profile_record[index].time[subpass] - += estimate_num_insns (gsi_stmt (i), - &eni_time_weights) * bb->frequency; - } - } - else if (cfun && (cfun->curr_properties & PROP_rtl)) - { - rtx insn; - for (insn = NEXT_INSN (BB_HEAD (bb)); insn && insn != NEXT_INSN (BB_END (bb)); - insn = NEXT_INSN (insn)) - if (INSN_P (insn)) - { - profile_record[index].size[subpass] - += insn_rtx_cost (PATTERN (insn), false); - if (profile_status == PROFILE_READ) - profile_record[index].time[subpass] - += insn_rtx_cost (PATTERN (insn), true) * bb->count; - else if (profile_status == PROFILE_GUESSED) - profile_record[index].time[subpass] - += insn_rtx_cost (PATTERN (insn), true) * bb->frequency; - } - } - } - } - - /* Output profile consistency. */ - - void - dump_profile_report (void) - { - int i, j; - int last_freq_in = 0, last_count_in = 0, last_freq_out = 0, last_count_out = 0; - gcov_type last_time = 0, last_size = 0; - double rel_time_change, rel_size_change; - int last_reported = 0; - - if (!profile_record) - return; - fprintf (stderr, "\nProfile consistency report:\n\n"); - fprintf (stderr, "Pass name |mismatch in |mismated out|Overall\n"); - fprintf (stderr, " |freq count |freq count |size time\n"); - - for (i = 0; i < passes_by_id_size; i++) - for (j = 0 ; j < 2; j++) - if (profile_record[i].run) - { - if (last_time) - rel_time_change = (profile_record[i].time[j] - - (double)last_time) * 100 / (double)last_time; - else - rel_time_change = 0; - if (last_size) - rel_size_change = (profile_record[i].size[j] - - (double)last_size) * 100 / (double)last_size; - else - rel_size_change = 0; - - if (profile_record[i].num_mismatched_freq_in[j] != last_freq_in - || profile_record[i].num_mismatched_freq_out[j] != last_freq_out - || profile_record[i].num_mismatched_count_in[j] != last_count_in - || profile_record[i].num_mismatched_count_out[j] != last_count_out - || rel_time_change || rel_size_change) - { - last_reported = i; - fprintf (stderr, "%-20s %s", - passes_by_id [i]->name, - j ? "(after TODO)" : " "); - if (profile_record[i].num_mismatched_freq_in[j] != last_freq_in) - fprintf (stderr, "| %+5i", - profile_record[i].num_mismatched_freq_in[j] - - last_freq_in); - else - fprintf (stderr, "| "); - if (profile_record[i].num_mismatched_count_in[j] != last_count_in) - fprintf (stderr, " %+5i", - profile_record[i].num_mismatched_count_in[j] - - last_count_in); - else - fprintf (stderr, " "); - if (profile_record[i].num_mismatched_freq_out[j] != last_freq_out) - fprintf (stderr, "| %+5i", - profile_record[i].num_mismatched_freq_out[j] - - last_freq_out); - else - fprintf (stderr, "| "); - if (profile_record[i].num_mismatched_count_out[j] != last_count_out) - fprintf (stderr, " %+5i", - profile_record[i].num_mismatched_count_out[j] - - last_count_out); - else - fprintf (stderr, " "); - - /* Size/time units change across gimple and RTL. */ - if (i == pass_expand.pass.static_pass_number) - fprintf (stderr, "|----------"); - else - { - if (rel_size_change) - fprintf (stderr, "| %+8.4f%%", rel_size_change); - else - fprintf (stderr, "| "); - if (rel_time_change) - fprintf (stderr, " %+8.4f%%", rel_time_change); - } - fprintf (stderr, "\n"); - last_freq_in = profile_record[i].num_mismatched_freq_in[j]; - last_freq_out = profile_record[i].num_mismatched_freq_out[j]; - last_count_in = profile_record[i].num_mismatched_count_in[j]; - last_count_out = profile_record[i].num_mismatched_count_out[j]; - } - else if (j && last_reported != i) - { - last_reported = i; - fprintf (stderr, "%-20s ------------| | |\n", - passes_by_id [i]->name); - } - last_time = profile_record[i].time[j]; - last_size = profile_record[i].size[j]; - } - } - /* Perform all TODO actions that ought to be done on each function. */ static void --- 1778,1783 ----