diff options
author | Martin Liska <mliska@suse.cz> | 2018-09-21 10:41:17 +0200 |
---|---|---|
committer | Martin Liska <marxin@gcc.gnu.org> | 2018-09-21 08:41:17 +0000 |
commit | 512cc0151207de4c7ff3a84f040f730fe0d52458 (patch) | |
tree | d3237cdec0d5acc77939322658f0dc8de1d5a5be /gcc | |
parent | 36ff254bf63f21dd8fc7a353c8b8f3aa08018654 (diff) | |
download | gcc-512cc0151207de4c7ff3a84f040f730fe0d52458.zip gcc-512cc0151207de4c7ff3a84f040f730fe0d52458.tar.gz gcc-512cc0151207de4c7ff3a84f040f730fe0d52458.tar.bz2 |
Remove arc profile histogram in non-LTO mode.
2018-09-21 Martin Liska <mliska@suse.cz>
* auto-profile.c (autofdo_source_profile::read): Do not
set sum_all.
(read_profile): Do not add working sets.
(read_autofdo_file): Remove sum_all.
(afdo_callsite_hot_enough_for_early_inline): Remove const
qualifier.
* coverage.c (struct counts_entry): Remove gcov_summary.
(read_counts_file): Read new GCOV_TAG_OBJECT_SUMMARY,
do not support GCOV_TAG_PROGRAM_SUMMARY.
(get_coverage_counts): Remove summary and expected
arguments.
* coverage.h (get_coverage_counts): Likewise.
* doc/gcov-dump.texi: Remove -w option.
* gcov-dump.c (dump_working_sets): Remove.
(main): Do not support '-w' option.
(print_usage): Likewise.
(tag_summary): Likewise.
* gcov-io.c (gcov_write_summary): Do not dump
histogram.
(gcov_read_summary): Likewise.
(gcov_histo_index): Remove.
(gcov_histogram_merge): Likewise.
(compute_working_sets): Likewise.
* gcov-io.h (GCOV_TAG_OBJECT_SUMMARY): Mark
it not obsolete.
(GCOV_TAG_PROGRAM_SUMMARY): Mark it obsolete.
(GCOV_TAG_SUMMARY_LENGTH): Adjust.
(GCOV_HISTOGRAM_SIZE): Remove.
(GCOV_HISTOGRAM_BITVECTOR_SIZE): Likewise.
(struct gcov_summary): Simplify rapidly just
to runs and sum_max fields.
(gcov_histo_index): Remove.
(NUM_GCOV_WORKING_SETS): Likewise.
(compute_working_sets): Likewise.
* gcov-tool.c (print_overlap_usage_message): Remove
trailing empty line.
* gcov.c (read_count_file): Read GCOV_TAG_OBJECT_SUMMARY.
(output_lines): Remove program related line.
* ipa-profile.c (ipa_profile): Do not consider GCOV histogram.
* lto-cgraph.c (output_profile_summary): Do not stream GCOV
histogram.
(input_profile_summary): Do not read it.
(merge_profile_summaries): And do not merge it.
(input_symtab): Do not call removed function.
* modulo-sched.c (sms_schedule): Do not print sum_max.
* params.def (HOT_BB_COUNT_FRACTION): Reincarnate param that was
removed when histogram method was invented.
(HOT_BB_COUNT_WS_PERMILLE): Mention that it's used only in LTO
mode.
* postreload-gcse.c (eliminate_partially_redundant_load): Fix
GCOV coding style.
* predict.c (get_hot_bb_threshold): Use HOT_BB_COUNT_FRACTION
and dump selected value.
* profile.c (add_working_set): Remove.
(get_working_sets): Likewise.
(find_working_set): Likewise.
(get_exec_counts): Do not work with working sets.
(read_profile_edge_counts): Do not inform as sum_max is removed.
(compute_branch_probabilities): Likewise.
(compute_value_histograms): Remove argument for call of
get_coverage_counts.
* profile.h: Do not make gcov_summary const.
2018-09-21 Martin Liska <mliska@suse.cz>
* libgcov-driver.c (crc32_unsigned): Remove.
(gcov_histogram_insert): Likewise.
(gcov_compute_histogram): Likewise.
(compute_summary): Simplify rapidly.
(merge_one_data): Do not handle PROGRAM_SUMMARY tag.
(merge_summary): Rapidly simplify.
(dump_one_gcov): Ignore gcov_summary.
(gcov_do_dump): Do not handle program summary, it's not
used.
* libgcov-util.c (tag_summary): Remove.
(read_gcda_finalize): Fix coding style.
(read_gcda_file): Initialize curr_object_summary.
(compute_summary): Remove.
(calculate_overlap): Remove settings of run_max.
From-SVN: r264462
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 65 | ||||
-rw-r--r-- | gcc/auto-profile.c | 21 | ||||
-rw-r--r-- | gcc/coverage.c | 59 | ||||
-rw-r--r-- | gcc/coverage.h | 4 | ||||
-rw-r--r-- | gcc/doc/gcov-dump.texi | 6 | ||||
-rw-r--r-- | gcc/gcov-dump.c | 81 | ||||
-rw-r--r-- | gcc/gcov-io.c | 398 | ||||
-rw-r--r-- | gcc/gcov-io.h | 71 | ||||
-rw-r--r-- | gcc/gcov-tool.c | 1 | ||||
-rw-r--r-- | gcc/gcov.c | 7 | ||||
-rw-r--r-- | gcc/ipa-profile.c | 26 | ||||
-rw-r--r-- | gcc/lto-cgraph.c | 136 | ||||
-rw-r--r-- | gcc/modulo-sched.c | 8 | ||||
-rw-r--r-- | gcc/params.def | 7 | ||||
-rw-r--r-- | gcc/postreload-gcse.c | 2 | ||||
-rw-r--r-- | gcc/predict.c | 9 | ||||
-rw-r--r-- | gcc/profile.c | 116 | ||||
-rw-r--r-- | gcc/profile.h | 2 |
18 files changed, 120 insertions, 899 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2070b59..97e75ec 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,68 @@ +2018-09-21 Martin Liska <mliska@suse.cz> + + * auto-profile.c (autofdo_source_profile::read): Do not + set sum_all. + (read_profile): Do not add working sets. + (read_autofdo_file): Remove sum_all. + (afdo_callsite_hot_enough_for_early_inline): Remove const + qualifier. + * coverage.c (struct counts_entry): Remove gcov_summary. + (read_counts_file): Read new GCOV_TAG_OBJECT_SUMMARY, + do not support GCOV_TAG_PROGRAM_SUMMARY. + (get_coverage_counts): Remove summary and expected + arguments. + * coverage.h (get_coverage_counts): Likewise. + * doc/gcov-dump.texi: Remove -w option. + * gcov-dump.c (dump_working_sets): Remove. + (main): Do not support '-w' option. + (print_usage): Likewise. + (tag_summary): Likewise. + * gcov-io.c (gcov_write_summary): Do not dump + histogram. + (gcov_read_summary): Likewise. + (gcov_histo_index): Remove. + (gcov_histogram_merge): Likewise. + (compute_working_sets): Likewise. + * gcov-io.h (GCOV_TAG_OBJECT_SUMMARY): Mark + it not obsolete. + (GCOV_TAG_PROGRAM_SUMMARY): Mark it obsolete. + (GCOV_TAG_SUMMARY_LENGTH): Adjust. + (GCOV_HISTOGRAM_SIZE): Remove. + (GCOV_HISTOGRAM_BITVECTOR_SIZE): Likewise. + (struct gcov_summary): Simplify rapidly just + to runs and sum_max fields. + (gcov_histo_index): Remove. + (NUM_GCOV_WORKING_SETS): Likewise. + (compute_working_sets): Likewise. + * gcov-tool.c (print_overlap_usage_message): Remove + trailing empty line. + * gcov.c (read_count_file): Read GCOV_TAG_OBJECT_SUMMARY. + (output_lines): Remove program related line. + * ipa-profile.c (ipa_profile): Do not consider GCOV histogram. + * lto-cgraph.c (output_profile_summary): Do not stream GCOV + histogram. + (input_profile_summary): Do not read it. + (merge_profile_summaries): And do not merge it. + (input_symtab): Do not call removed function. + * modulo-sched.c (sms_schedule): Do not print sum_max. + * params.def (HOT_BB_COUNT_FRACTION): Reincarnate param that was + removed when histogram method was invented. + (HOT_BB_COUNT_WS_PERMILLE): Mention that it's used only in LTO + mode. + * postreload-gcse.c (eliminate_partially_redundant_load): Fix + GCOV coding style. + * predict.c (get_hot_bb_threshold): Use HOT_BB_COUNT_FRACTION + and dump selected value. + * profile.c (add_working_set): Remove. + (get_working_sets): Likewise. + (find_working_set): Likewise. + (get_exec_counts): Do not work with working sets. + (read_profile_edge_counts): Do not inform as sum_max is removed. + (compute_branch_probabilities): Likewise. + (compute_value_histograms): Remove argument for call of + get_coverage_counts. + * profile.h: Do not make gcov_summary const. + 2018-09-21 Monk Chiang <sh.chiang04@gmail.com> * config.gcc (nds32*-*-*): Set TARGET_DEFAULT_TLSDESC_TRAMPOLINE=0. diff --git a/gcc/auto-profile.c b/gcc/auto-profile.c index 197fa10..68abe32 100644 --- a/gcc/auto-profile.c +++ b/gcc/auto-profile.c @@ -867,7 +867,6 @@ autofdo_source_profile::read () function_instance::function_instance_stack stack; function_instance *s = function_instance::read_function_instance ( &stack, gcov_read_counter ()); - afdo_profile_info->sum_all += s->total_count (); map_[s->name ()] = s; } return true; @@ -958,23 +957,6 @@ read_profile (void) /* autofdo_module_profile. */ fake_read_autofdo_module_profile (); - - /* Read in the working set. */ - if (gcov_read_unsigned () != GCOV_TAG_AFDO_WORKING_SET) - { - error ("cannot read working set from %s", auto_profile_file); - return; - } - - /* Skip the length of the section. */ - gcov_read_unsigned (); - gcov_working_set_t set[128]; - for (unsigned i = 0; i < 128; i++) - { - set[i].num_counters = gcov_read_unsigned (); - set[i].min_counter = gcov_read_counter (); - } - add_working_set (set); } /* From AutoFDO profiles, find values inside STMT for that we want to measure @@ -1685,7 +1667,6 @@ read_autofdo_file (void) autofdo::afdo_profile_info = XNEW (gcov_summary); autofdo::afdo_profile_info->runs = 1; autofdo::afdo_profile_info->sum_max = 0; - autofdo::afdo_profile_info->sum_all = 0; /* Read the profile from the profile file. */ autofdo::read_profile (); @@ -1712,7 +1693,7 @@ afdo_callsite_hot_enough_for_early_inline (struct cgraph_edge *edge) if (count > 0) { bool is_hot; - const gcov_summary *saved_profile_info = profile_info; + gcov_summary *saved_profile_info = profile_info; /* At early inline stage, profile_info is not set yet. We need to temporarily set it to afdo_profile_info to calculate hotness. */ profile_info = autofdo::afdo_profile_info; diff --git a/gcc/coverage.c b/gcc/coverage.c index bae6f5c..26cce2b 100644 --- a/gcc/coverage.c +++ b/gcc/coverage.c @@ -49,6 +49,7 @@ along with GCC; see the file COPYING3. If not see #include "intl.h" #include "params.h" #include "auto-profile.h" +#include "profile.h" #include "gcov-io.c" @@ -73,7 +74,6 @@ struct counts_entry : pointer_hash <counts_entry> unsigned lineno_checksum; unsigned cfg_checksum; gcov_type *counts; - gcov_summary summary; /* hash_table support. */ static inline hashval_t hash (const counts_entry *); @@ -185,8 +185,6 @@ static void read_counts_file (void) { gcov_unsigned_t fn_ident = 0; - gcov_summary summary; - unsigned new_summary = 1; gcov_unsigned_t tag; int is_error = 0; unsigned lineno_checksum = 0; @@ -236,27 +234,12 @@ read_counts_file (void) } else fn_ident = lineno_checksum = cfg_checksum = 0; - new_summary = 1; } - else if (tag == GCOV_TAG_PROGRAM_SUMMARY) + else if (tag == GCOV_TAG_OBJECT_SUMMARY) { - struct gcov_summary sum; - - if (new_summary) - memset (&summary, 0, sizeof (summary)); - - gcov_read_summary (&sum); - summary.runs += sum.runs; - summary.sum_all += sum.sum_all; - if (summary.run_max < sum.run_max) - summary.run_max = sum.run_max; - summary.sum_max += sum.sum_max; - if (new_summary) - memcpy (summary.histogram, sum.histogram, - sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE); - else - gcov_histogram_merge (summary.histogram, sum.histogram); - new_summary = 0; + profile_info = XCNEW (gcov_summary); + profile_info->runs = gcov_read_unsigned (); + profile_info->sum_max = gcov_read_unsigned (); } else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident) { @@ -276,9 +259,6 @@ read_counts_file (void) entry->ctr = elt.ctr; entry->lineno_checksum = lineno_checksum; entry->cfg_checksum = cfg_checksum; - if (elt.ctr == GCOV_COUNTER_ARCS) - entry->summary = summary; - entry->summary.num = n_counts; entry->counts = XCNEWVEC (gcov_type, n_counts); } else if (entry->lineno_checksum != lineno_checksum @@ -292,22 +272,6 @@ read_counts_file (void) counts_hash = NULL; break; } - else if (entry->summary.num != n_counts) - { - error ("Profile data for function %u is corrupted", fn_ident); - error ("number of counters is %d instead of %d", entry->summary.num, n_counts); - delete counts_hash; - counts_hash = NULL; - break; - } - else - { - entry->summary.runs += summary.runs; - entry->summary.sum_all += summary.sum_all; - if (entry->summary.run_max < summary.run_max) - entry->summary.run_max = summary.run_max; - entry->summary.sum_max += summary.sum_max; - } for (ix = 0; ix != n_counts; ix++) entry->counts[ix] += gcov_read_counter (); } @@ -330,9 +294,8 @@ read_counts_file (void) /* Returns the counters for a particular tag. */ gcov_type * -get_coverage_counts (unsigned counter, unsigned expected, - unsigned cfg_checksum, unsigned lineno_checksum, - const gcov_summary **summary) +get_coverage_counts (unsigned counter, unsigned cfg_checksum, + unsigned lineno_checksum) { counts_entry *entry, elt; @@ -363,14 +326,13 @@ get_coverage_counts (unsigned counter, unsigned expected, } elt.ctr = counter; entry = counts_hash->find (&elt); - if (!entry || !entry->summary.num) + if (!entry) /* The function was not emitted, or is weak and not chosen in the final executable. Silently fail, because there's nothing we can do about it. */ return NULL; - if (entry->cfg_checksum != cfg_checksum - || entry->summary.num != expected) + if (entry->cfg_checksum != cfg_checksum) { static int warned = 0; bool warning_printed = false; @@ -414,9 +376,6 @@ get_coverage_counts (unsigned counter, unsigned expected, DECL_ASSEMBLER_NAME (current_function_decl)); } - if (summary) - *summary = &entry->summary; - return entry->counts; } diff --git a/gcc/coverage.h b/gcc/coverage.h index 842d695..d612c38 100644 --- a/gcc/coverage.h +++ b/gcc/coverage.h @@ -51,10 +51,8 @@ extern tree tree_coverage_counter_addr (unsigned /*counter*/, unsigned/*num*/); /* Get all the counters for the current function. */ extern gcov_type *get_coverage_counts (unsigned /*counter*/, - unsigned /*expected*/, unsigned /*cfg_checksum*/, - unsigned /*lineno_checksum*/, - const gcov_summary **); + unsigned /*lineno_checksum*/); extern tree get_gcov_type (void); extern bool coverage_node_map_initialized_p (void); diff --git a/gcc/doc/gcov-dump.texi b/gcc/doc/gcov-dump.texi index e526bde..0313358 100644 --- a/gcc/doc/gcov-dump.texi +++ b/gcc/doc/gcov-dump.texi @@ -61,7 +61,7 @@ gcov-dump [@option{-v}|@option{--version}] [@option{-h}|@option{--help}] [@option{-l}|@option{--long}] [@option{-p}|@option{--positions}] - [@option{-w}|@option{--working-sets}] @var{gcovfiles} + @var{gcovfiles} @c man end @end ignore @@ -84,10 +84,6 @@ Dump positions of records. @itemx --version Display the @command{gcov-dump} version number (on the standard output), and exit without doing any further processing. - -@item -w -@itemx --working-sets -Dump working set computed from summary. @end table @c man end diff --git a/gcc/gcov-dump.c b/gcc/gcov-dump.c index 3ff11a6..7762e4e 100644 --- a/gcc/gcov-dump.c +++ b/gcc/gcov-dump.c @@ -38,9 +38,6 @@ static void tag_arcs (const char *, unsigned, unsigned, unsigned); static void tag_lines (const char *, unsigned, unsigned, unsigned); static void tag_counters (const char *, unsigned, unsigned, unsigned); static void tag_summary (const char *, unsigned, unsigned, unsigned); -static void dump_working_sets (const char *filename ATTRIBUTE_UNUSED, - const gcov_summary *summary, - unsigned depth); extern int main (int, char **); typedef struct tag_format @@ -52,7 +49,6 @@ typedef struct tag_format static int flag_dump_contents = 0; static int flag_dump_positions = 0; -static int flag_dump_working_sets = 0; static const struct option options[] = { @@ -60,7 +56,6 @@ static const struct option options[] = { "version", no_argument, NULL, 'v' }, { "long", no_argument, NULL, 'l' }, { "positions", no_argument, NULL, 'o' }, - { "working-sets", no_argument, NULL, 'w' }, { 0, 0, 0, 0 } }; @@ -77,7 +72,6 @@ static const tag_format_t tag_table[] = {GCOV_TAG_ARCS, "ARCS", tag_arcs}, {GCOV_TAG_LINES, "LINES", tag_lines}, {GCOV_TAG_OBJECT_SUMMARY, "OBJECT_SUMMARY", tag_summary}, - {GCOV_TAG_PROGRAM_SUMMARY, "PROGRAM_SUMMARY", tag_summary}, {0, NULL, NULL} }; @@ -117,9 +111,6 @@ main (int argc ATTRIBUTE_UNUSED, char **argv) case 'p': flag_dump_positions = 1; break; - case 'w': - flag_dump_working_sets = 1; - break; default: fprintf (stderr, "unknown flag `%c'\n", opt); } @@ -139,7 +130,6 @@ print_usage (void) printf (" -l, --long Dump record contents too\n"); printf (" -p, --positions Dump record positions\n"); printf (" -v, --version Print version number\n"); - printf (" -w, --working-sets Dump working set computed from summary\n"); printf ("\nFor bug reporting instructions, please see:\n%s.\n", bug_report_url); } @@ -465,75 +455,10 @@ tag_counters (const char *filename ATTRIBUTE_UNUSED, static void tag_summary (const char *filename ATTRIBUTE_UNUSED, unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED, - unsigned depth) + unsigned depth ATTRIBUTE_UNUSED) { gcov_summary summary; - unsigned h_ix; - gcov_bucket_type *histo_bucket; - gcov_read_summary (&summary); - printf (" checksum=0x%08x", summary.checksum); - - printf ("\n"); - print_prefix (filename, depth, 0); - printf (VALUE_PADDING_PREFIX "counts=%u, runs=%u", - summary.num, summary.runs); - - printf (", sum_all=%" PRId64, - (int64_t)summary.sum_all); - printf (", run_max=%" PRId64, - (int64_t)summary.run_max); - printf (", sum_max=%" PRId64, - (int64_t)summary.sum_max); - printf ("\n"); - print_prefix (filename, depth, 0); - printf (VALUE_PADDING_PREFIX "counter histogram:"); - for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++) - { - histo_bucket = &summary.histogram[h_ix]; - if (!histo_bucket->num_counters) - continue; - printf ("\n"); - print_prefix (filename, depth, 0); - printf (VALUE_PADDING_PREFIX VALUE_PREFIX "num counts=%u, " - "min counter=%" PRId64 ", cum_counter=%" PRId64, - h_ix, histo_bucket->num_counters, - (int64_t)histo_bucket->min_value, - (int64_t)histo_bucket->cum_value); - } - if (flag_dump_working_sets) - dump_working_sets (filename, &summary, depth); -} - -static void -dump_working_sets (const char *filename ATTRIBUTE_UNUSED, - const gcov_summary *summary, - unsigned depth) -{ - gcov_working_set_t gcov_working_sets[NUM_GCOV_WORKING_SETS]; - unsigned ws_ix, pctinc, pct; - gcov_working_set_t *ws_info; - - compute_working_sets (summary, gcov_working_sets); - - printf ("\n"); - print_prefix (filename, depth, 0); - printf (VALUE_PADDING_PREFIX "counter working sets:"); - /* Multiply the percentage by 100 to avoid float. */ - pctinc = 100 * 100 / NUM_GCOV_WORKING_SETS; - for (ws_ix = 0, pct = pctinc; ws_ix < NUM_GCOV_WORKING_SETS; - ws_ix++, pct += pctinc) - { - if (ws_ix == NUM_GCOV_WORKING_SETS - 1) - pct = 9990; - ws_info = &gcov_working_sets[ws_ix]; - /* Print out the percentage using int arithmatic to avoid float. */ - printf ("\n"); - print_prefix (filename, depth + 1, 0); - printf (VALUE_PADDING_PREFIX "%u.%02u%%: num counts=%u, min counter=" - "%" PRId64, - pct / 100, pct - (pct / 100 * 100), - ws_info->num_counters, - (int64_t)ws_info->min_counter); - } + printf (" runs=%d, sum_max=%" PRId64, + summary.runs, summary.sum_max); } diff --git a/gcc/gcov-io.c b/gcc/gcov-io.c index 311e4d0..63cc7fc 100644 --- a/gcc/gcov-io.c +++ b/gcc/gcov-io.c @@ -446,39 +446,11 @@ gcov_write_tag_length (gcov_unsigned_t tag, gcov_unsigned_t length) GCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t tag, const struct gcov_summary *summary) { - unsigned h_ix, bv_ix, h_cnt = 0; - unsigned histo_bitvector[GCOV_HISTOGRAM_BITVECTOR_SIZE]; - - /* Count number of non-zero histogram entries, and fill in a bit vector - of non-zero indices. The histogram is only currently computed for arc - counters. */ - for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++) - histo_bitvector[bv_ix] = 0; - for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++) - if (summary->histogram[h_ix].num_counters) - { - histo_bitvector[h_ix / 32] |= 1 << (h_ix % 32); - h_cnt++; - } - gcov_write_tag_length (tag, GCOV_TAG_SUMMARY_LENGTH (h_cnt)); - gcov_write_unsigned (summary->checksum); - - gcov_write_unsigned (summary->num); + gcov_write_tag_length (tag, GCOV_TAG_SUMMARY_LENGTH); gcov_write_unsigned (summary->runs); - gcov_write_counter (summary->sum_all); - gcov_write_counter (summary->run_max); - gcov_write_counter (summary->sum_max); - for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++) - gcov_write_unsigned (histo_bitvector[bv_ix]); - for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++) - { - if (!summary->histogram[h_ix].num_counters) - continue; - gcov_write_unsigned (summary->histogram[h_ix].num_counters); - gcov_write_counter (summary->histogram[h_ix].min_value); - gcov_write_counter (summary->histogram[h_ix].cum_value); - } + gcov_write_unsigned (summary->sum_max); } + #endif /* IN_LIBGCOV */ #endif /*!IN_GCOV */ @@ -637,65 +609,8 @@ gcov_read_string (void) GCOV_LINKAGE void gcov_read_summary (struct gcov_summary *summary) { - unsigned h_ix, bv_ix, h_cnt = 0; - unsigned histo_bitvector[GCOV_HISTOGRAM_BITVECTOR_SIZE]; - unsigned cur_bitvector; - - summary->checksum = gcov_read_unsigned (); - summary->num = gcov_read_unsigned (); summary->runs = gcov_read_unsigned (); - summary->sum_all = gcov_read_counter (); - summary->run_max = gcov_read_counter (); - summary->sum_max = gcov_read_counter (); - memset (summary->histogram, 0, - sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE); - for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++) - { - histo_bitvector[bv_ix] = gcov_read_unsigned (); -#if IN_LIBGCOV - /* When building libgcov we don't include system.h, which includes - hwint.h (where popcount_hwi is declared). However, libgcov.a - is built by the bootstrapped compiler and therefore the builtins - are always available. */ - h_cnt += __builtin_popcount (histo_bitvector[bv_ix]); -#else - h_cnt += popcount_hwi (histo_bitvector[bv_ix]); -#endif - } - bv_ix = 0; - h_ix = 0; - cur_bitvector = 0; - while (h_cnt--) - { - /* Find the index corresponding to the next entry we will read in. - First find the next non-zero bitvector and re-initialize - the histogram index accordingly, then right shift and increment - the index until we find a set bit. */ - while (!cur_bitvector) - { - h_ix = bv_ix * 32; - if (bv_ix >= GCOV_HISTOGRAM_BITVECTOR_SIZE) - gcov_error ("corrupted profile info: summary histogram " - "bitvector is corrupt"); - cur_bitvector = histo_bitvector[bv_ix++]; - } - while (!(cur_bitvector & 0x1)) - { - h_ix++; - cur_bitvector >>= 1; - } - if (h_ix >= GCOV_HISTOGRAM_SIZE) - gcov_error ("corrupted profile info: summary histogram " - "index is corrupt"); - - summary->histogram[h_ix].num_counters = gcov_read_unsigned (); - summary->histogram[h_ix].min_value = gcov_read_counter (); - summary->histogram[h_ix].cum_value = gcov_read_counter (); - /* Shift off the index we are done with and increment to the - corresponding next histogram entry. */ - cur_bitvector >>= 1; - h_ix++; - } + summary->sum_max = gcov_read_unsigned (); } /* We need to expose the below function when compiling for gcov-tool. */ @@ -747,308 +662,3 @@ gcov_time (void) return status.st_mtime; } #endif /* IN_GCOV */ - -#if !IN_GCOV -/* Determine the index into histogram for VALUE. */ - -#if IN_LIBGCOV -static unsigned -#else -GCOV_LINKAGE unsigned -#endif -gcov_histo_index (gcov_type value) -{ - gcov_type_unsigned v = (gcov_type_unsigned)value; - unsigned r = 0; - unsigned prev2bits = 0; - - /* Find index into log2 scale histogram, where each of the log2 - sized buckets is divided into 4 linear sub-buckets for better - focus in the higher buckets. */ - - /* Find the place of the most-significant bit set. */ - if (v > 0) - { -#if IN_LIBGCOV - /* When building libgcov we don't include system.h, which includes - hwint.h (where floor_log2 is declared). However, libgcov.a - is built by the bootstrapped compiler and therefore the builtins - are always available. */ - r = sizeof (long long) * __CHAR_BIT__ - 1 - __builtin_clzll (v); -#else - /* We use floor_log2 from hwint.c, which takes a HOST_WIDE_INT - that is 64 bits and gcov_type_unsigned is 64 bits. */ - r = floor_log2 (v); -#endif - } - - /* If at most the 2 least significant bits are set (value is - 0 - 3) then that value is our index into the lowest set of - four buckets. */ - if (r < 2) - return (unsigned)value; - - gcov_nonruntime_assert (r < 64); - - /* Find the two next most significant bits to determine which - of the four linear sub-buckets to select. */ - prev2bits = (v >> (r - 2)) & 0x3; - /* Finally, compose the final bucket index from the log2 index and - the next 2 bits. The minimum r value at this point is 2 since we - returned above if r was 2 or more, so the minimum bucket at this - point is 4. */ - return (r - 1) * 4 + prev2bits; -} - -/* Merge SRC_HISTO into TGT_HISTO. The counters are assumed to be in - the same relative order in both histograms, and are matched up - and merged in reverse order. Each counter is assigned an equal portion of - its entry's original cumulative counter value when computing the - new merged cum_value. */ - -static void gcov_histogram_merge (gcov_bucket_type *tgt_histo, - gcov_bucket_type *src_histo) -{ - int src_i, tgt_i, tmp_i = 0; - unsigned src_num, tgt_num, merge_num; - gcov_type src_cum, tgt_cum, merge_src_cum, merge_tgt_cum, merge_cum; - gcov_type merge_min; - gcov_bucket_type tmp_histo[GCOV_HISTOGRAM_SIZE]; - int src_done = 0; - - memset (tmp_histo, 0, sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE); - - /* Assume that the counters are in the same relative order in both - histograms. Walk the histograms from largest to smallest entry, - matching up and combining counters in order. */ - src_num = 0; - src_cum = 0; - src_i = GCOV_HISTOGRAM_SIZE - 1; - for (tgt_i = GCOV_HISTOGRAM_SIZE - 1; tgt_i >= 0 && !src_done; tgt_i--) - { - tgt_num = tgt_histo[tgt_i].num_counters; - tgt_cum = tgt_histo[tgt_i].cum_value; - /* Keep going until all of the target histogram's counters at this - position have been matched and merged with counters from the - source histogram. */ - while (tgt_num > 0 && !src_done) - { - /* If this is either the first time through this loop or we just - exhausted the previous non-zero source histogram entry, look - for the next non-zero source histogram entry. */ - if (!src_num) - { - /* Locate the next non-zero entry. */ - while (src_i >= 0 && !src_histo[src_i].num_counters) - src_i--; - /* If source histogram has fewer counters, then just copy over the - remaining target counters and quit. */ - if (src_i < 0) - { - tmp_histo[tgt_i].num_counters += tgt_num; - tmp_histo[tgt_i].cum_value += tgt_cum; - if (!tmp_histo[tgt_i].min_value || - tgt_histo[tgt_i].min_value < tmp_histo[tgt_i].min_value) - tmp_histo[tgt_i].min_value = tgt_histo[tgt_i].min_value; - while (--tgt_i >= 0) - { - tmp_histo[tgt_i].num_counters - += tgt_histo[tgt_i].num_counters; - tmp_histo[tgt_i].cum_value += tgt_histo[tgt_i].cum_value; - if (!tmp_histo[tgt_i].min_value || - tgt_histo[tgt_i].min_value - < tmp_histo[tgt_i].min_value) - tmp_histo[tgt_i].min_value = tgt_histo[tgt_i].min_value; - } - - src_done = 1; - break; - } - - src_num = src_histo[src_i].num_counters; - src_cum = src_histo[src_i].cum_value; - } - - /* The number of counters to merge on this pass is the minimum - of the remaining counters from the current target and source - histogram entries. */ - merge_num = tgt_num; - if (src_num < merge_num) - merge_num = src_num; - - /* The merged min_value is the sum of the min_values from target - and source. */ - merge_min = tgt_histo[tgt_i].min_value + src_histo[src_i].min_value; - - /* Compute the portion of source and target entries' cum_value - that will be apportioned to the counters being merged. - The total remaining cum_value from each entry is divided - equally among the counters from that histogram entry if we - are not merging all of them. */ - merge_src_cum = src_cum; - if (merge_num < src_num) - merge_src_cum = merge_num * src_cum / src_num; - merge_tgt_cum = tgt_cum; - if (merge_num < tgt_num) - merge_tgt_cum = merge_num * tgt_cum / tgt_num; - /* The merged cum_value is the sum of the source and target - components. */ - merge_cum = merge_src_cum + merge_tgt_cum; - - /* Update the remaining number of counters and cum_value left - to be merged from this source and target entry. */ - src_cum -= merge_src_cum; - tgt_cum -= merge_tgt_cum; - src_num -= merge_num; - tgt_num -= merge_num; - - /* The merged counters get placed in the new merged histogram - at the entry for the merged min_value. */ - tmp_i = gcov_histo_index (merge_min); - gcov_nonruntime_assert (tmp_i < GCOV_HISTOGRAM_SIZE); - tmp_histo[tmp_i].num_counters += merge_num; - tmp_histo[tmp_i].cum_value += merge_cum; - if (!tmp_histo[tmp_i].min_value || - merge_min < tmp_histo[tmp_i].min_value) - tmp_histo[tmp_i].min_value = merge_min; - - /* Ensure the search for the next non-zero src_histo entry starts - at the next smallest histogram bucket. */ - if (!src_num) - src_i--; - } - } - - gcov_nonruntime_assert (tgt_i < 0); - - /* In the case where there were more counters in the source histogram, - accumulate the remaining unmerged cumulative counter values. Add - those to the smallest non-zero target histogram entry. Otherwise, - the total cumulative counter values in the histogram will be smaller - than the sum_all stored in the summary, which will complicate - computing the working set information from the histogram later on. */ - if (src_num) - src_i--; - while (src_i >= 0) - { - src_cum += src_histo[src_i].cum_value; - src_i--; - } - /* At this point, tmp_i should be the smallest non-zero entry in the - tmp_histo. */ - gcov_nonruntime_assert (tmp_i >= 0 && tmp_i < GCOV_HISTOGRAM_SIZE - && tmp_histo[tmp_i].num_counters > 0); - tmp_histo[tmp_i].cum_value += src_cum; - - /* Finally, copy the merged histogram into tgt_histo. */ - memcpy (tgt_histo, tmp_histo, - sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE); -} -#endif /* !IN_GCOV */ - -/* This is used by gcov-dump (IN_GCOV == -1) and in the compiler - (!IN_GCOV && !IN_LIBGCOV). */ -#if IN_GCOV <= 0 && !IN_LIBGCOV -/* Compute the working set information from the counter histogram in - the profile summary. This is an array of information corresponding to a - range of percentages of the total execution count (sum_all), and includes - the number of counters required to cover that working set percentage and - the minimum counter value in that working set. */ - -GCOV_LINKAGE void -compute_working_sets (const gcov_summary *summary, - gcov_working_set_t *gcov_working_sets) -{ - gcov_type working_set_cum_values[NUM_GCOV_WORKING_SETS]; - gcov_type ws_cum_hotness_incr; - gcov_type cum, tmp_cum; - const gcov_bucket_type *histo_bucket; - unsigned ws_ix, c_num, count; - int h_ix; - - /* Compute the amount of sum_all that the cumulative hotness grows - by in each successive working set entry, which depends on the - number of working set entries. */ - ws_cum_hotness_incr = summary->sum_all / NUM_GCOV_WORKING_SETS; - - /* Next fill in an array of the cumulative hotness values corresponding - to each working set summary entry we are going to compute below. - Skip 0% statistics, which can be extrapolated from the - rest of the summary data. */ - cum = ws_cum_hotness_incr; - for (ws_ix = 0; ws_ix < NUM_GCOV_WORKING_SETS; - ws_ix++, cum += ws_cum_hotness_incr) - working_set_cum_values[ws_ix] = cum; - /* The last summary entry is reserved for (roughly) 99.9% of the - working set. Divide by 1024 so it becomes a shift, which gives - almost exactly 99.9%. */ - working_set_cum_values[NUM_GCOV_WORKING_SETS-1] - = summary->sum_all - summary->sum_all/1024; - - /* Next, walk through the histogram in decending order of hotness - and compute the statistics for the working set summary array. - As histogram entries are accumulated, we check to see which - working set entries have had their expected cum_value reached - and fill them in, walking the working set entries in increasing - size of cum_value. */ - ws_ix = 0; /* The current entry into the working set array. */ - cum = 0; /* The current accumulated counter sum. */ - count = 0; /* The current accumulated count of block counters. */ - for (h_ix = GCOV_HISTOGRAM_SIZE - 1; - h_ix >= 0 && ws_ix < NUM_GCOV_WORKING_SETS; h_ix--) - { - histo_bucket = &summary->histogram[h_ix]; - - /* If we haven't reached the required cumulative counter value for - the current working set percentage, simply accumulate this histogram - entry into the running sums and continue to the next histogram - entry. */ - if (cum + histo_bucket->cum_value < working_set_cum_values[ws_ix]) - { - cum += histo_bucket->cum_value; - count += histo_bucket->num_counters; - continue; - } - - /* If adding the current histogram entry's cumulative counter value - causes us to exceed the current working set size, then estimate - how many of this histogram entry's counter values are required to - reach the working set size, and fill in working set entries - as we reach their expected cumulative value. */ - for (c_num = 0, tmp_cum = cum; - c_num < histo_bucket->num_counters && ws_ix < NUM_GCOV_WORKING_SETS; - c_num++) - { - count++; - /* If we haven't reached the last histogram entry counter, add - in the minimum value again. This will underestimate the - cumulative sum so far, because many of the counter values in this - entry may have been larger than the minimum. We could add in the - average value every time, but that would require an expensive - divide operation. */ - if (c_num + 1 < histo_bucket->num_counters) - tmp_cum += histo_bucket->min_value; - /* If we have reached the last histogram entry counter, then add - in the entire cumulative value. */ - else - tmp_cum = cum + histo_bucket->cum_value; - - /* Next walk through successive working set entries and fill in - the statistics for any whose size we have reached by accumulating - this histogram counter. */ - while (ws_ix < NUM_GCOV_WORKING_SETS - && tmp_cum >= working_set_cum_values[ws_ix]) - { - gcov_working_sets[ws_ix].num_counters = count; - gcov_working_sets[ws_ix].min_counter - = histo_bucket->min_value; - ws_ix++; - } - } - /* Finally, update the running cumulative value since we were - using a temporary above. */ - cum += histo_bucket->cum_value; - } - gcov_nonruntime_assert (ws_ix == NUM_GCOV_WORKING_SETS); -} -#endif /* IN_GCOV <= 0 && !IN_LIBGCOV */ diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h index 7a11f0a..1fc31f5 100644 --- a/gcc/gcov-io.h +++ b/gcc/gcov-io.h @@ -133,17 +133,14 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see blocks they are for. The data file contains the following records. - data: {unit summary:object summary:program* function-data*}* + data: {unit summary:object function-data*}* unit: header int32:checksum - function-data: announce_function present counts + function-data: announce_function present counts announce_function: header int32:ident int32:lineno_checksum int32:cfg_checksum present: header int32:present counts: header int64:count* - summary: int32:checksum int32:num int32:runs int64:sum - int64:max int64:sum_max histogram - histogram: {int32:bitvector}8 histogram-buckets* - histogram-buckets: int32:num int64:min int64:sum + summary: int32:checksum int32:runs int32:sum_max The ANNOUNCE_FUNCTION record is the same as that in the note file, but without the source location. The COUNTS gives the @@ -190,7 +187,7 @@ typedef uint64_t gcov_type_unsigned; #define ATTRIBUTE_HIDDEN -#endif /* !IN_LIBGOCV */ +#endif /* !IN_LIBGCOV */ #ifndef GCOV_LINKAGE #define GCOV_LINKAGE extern @@ -240,9 +237,9 @@ typedef uint64_t gcov_type_unsigned; #define GCOV_TAG_COUNTER_BASE ((gcov_unsigned_t)0x01a10000) #define GCOV_TAG_COUNTER_LENGTH(NUM) ((NUM) * 2) #define GCOV_TAG_COUNTER_NUM(LENGTH) ((LENGTH) / 2) -#define GCOV_TAG_OBJECT_SUMMARY ((gcov_unsigned_t)0xa1000000) /* Obsolete */ -#define GCOV_TAG_PROGRAM_SUMMARY ((gcov_unsigned_t)0xa3000000) -#define GCOV_TAG_SUMMARY_LENGTH(NUM) (1 + (10 + 3 * 2) + (NUM) * 5) +#define GCOV_TAG_OBJECT_SUMMARY ((gcov_unsigned_t)0xa1000000) +#define GCOV_TAG_PROGRAM_SUMMARY ((gcov_unsigned_t)0xa3000000) /* Obsolete */ +#define GCOV_TAG_SUMMARY_LENGTH (2) #define GCOV_TAG_AFDO_FILE_NAMES ((gcov_unsigned_t)0xaa000000) #define GCOV_TAG_AFDO_FUNCTION ((gcov_unsigned_t)0xac000000) #define GCOV_TAG_AFDO_WORKING_SET ((gcov_unsigned_t)0xaf000000) @@ -307,43 +304,12 @@ GCOV_COUNTERS #define GCOV_ARC_FAKE (1 << 1) #define GCOV_ARC_FALLTHROUGH (1 << 2) -/* Structured records. */ - -/* Structure used for each bucket of the log2 histogram of counter values. */ -typedef struct -{ - /* Number of counters whose profile count falls within the bucket. */ - gcov_unsigned_t num_counters; - /* Smallest profile count included in this bucket. */ - gcov_type min_value; - /* Cumulative value of the profile counts in this bucket. */ - gcov_type cum_value; -} gcov_bucket_type; - -/* For a log2 scale histogram with each range split into 4 - linear sub-ranges, there will be at most 64 (max gcov_type bit size) - 1 log2 - ranges since the lowest 2 log2 values share the lowest 4 linear - sub-range (values 0 - 3). This is 252 total entries (63*4). */ - -#define GCOV_HISTOGRAM_SIZE 252 - -/* How many unsigned ints are required to hold a bit vector of non-zero - histogram entries when the histogram is written to the gcov file. - This is essentially a ceiling divide by 32 bits. */ -#define GCOV_HISTOGRAM_BITVECTOR_SIZE (GCOV_HISTOGRAM_SIZE + 31) / 32 - /* Object & program summary record. */ struct gcov_summary { - gcov_unsigned_t checksum; /* Checksum of program. */ - gcov_unsigned_t num; /* Number of counters. */ gcov_unsigned_t runs; /* Number of program runs. */ - gcov_type sum_all; /* Sum of all counters accumulated. */ - gcov_type run_max; /* Maximum value on a single run. */ gcov_type sum_max; /* Sum of individual run max values. */ - gcov_bucket_type histogram[GCOV_HISTOGRAM_SIZE]; /* Histogram of - counter values. */ }; #if !defined(inhibit_libc) @@ -380,35 +346,12 @@ GCOV_LINKAGE void gcov_write_unsigned (gcov_unsigned_t) ATTRIBUTE_HIDDEN; #if !IN_GCOV && !IN_LIBGCOV /* Available only in compiler */ -GCOV_LINKAGE unsigned gcov_histo_index (gcov_type value); GCOV_LINKAGE void gcov_write_string (const char *); GCOV_LINKAGE void gcov_write_filename (const char *); GCOV_LINKAGE gcov_position_t gcov_write_tag (gcov_unsigned_t); GCOV_LINKAGE void gcov_write_length (gcov_position_t /*position*/); #endif -#if IN_GCOV <= 0 && !IN_LIBGCOV -/* Available in gcov-dump and the compiler. */ - -/* Number of data points in the working set summary array. Using 128 - provides information for at least every 1% increment of the total - profile size. The last entry is hardwired to 99.9% of the total. */ -#define NUM_GCOV_WORKING_SETS 128 - -/* Working set size statistics for a given percentage of the entire - profile (sum_all from the counter summary). */ -typedef struct gcov_working_set_info -{ - /* Number of hot counters included in this working set. */ - unsigned num_counters; - /* Smallest counter included in this working set. */ - gcov_type min_counter; -} gcov_working_set_t; - -GCOV_LINKAGE void compute_working_sets (const gcov_summary *summary, - gcov_working_set_t *gcov_working_sets); -#endif - #if IN_GCOV > 0 /* Available in gcov */ GCOV_LINKAGE time_t gcov_time (void); diff --git a/gcc/gcov-tool.c b/gcc/gcov-tool.c index 15fd710..88539f9 100644 --- a/gcc/gcov-tool.c +++ b/gcc/gcov-tool.c @@ -423,7 +423,6 @@ print_overlap_usage_message (int error_p) fnotice (file, " -o, --object Print object level info\n"); fnotice (file, " -t <float>, --hot_threshold <float> Set the threshold for hotness\n"); fnotice (file, " -v, --verbose Verbose mode\n"); - } static const struct option overlap_options[] = @@ -418,7 +418,6 @@ static vector<char *> processed_files; /* This holds data summary information. */ static unsigned object_runs; -static unsigned program_count; static unsigned total_lines; static unsigned total_executed; @@ -1829,12 +1828,11 @@ read_count_file (void) unsigned length = gcov_read_unsigned (); unsigned long base = gcov_position (); - if (tag == GCOV_TAG_PROGRAM_SUMMARY) + if (tag == GCOV_TAG_OBJECT_SUMMARY) { struct gcov_summary summary; gcov_read_summary (&summary); - object_runs += summary.runs; - program_count++; + object_runs = summary.runs; } else if (tag == GCOV_TAG_FUNCTION && !length) ; /* placeholder */ @@ -2952,7 +2950,6 @@ output_lines (FILE *gcov_file, const source_info *src) no_data_file ? "-" : da_file_name); fprintf (gcov_file, DEFAULT_LINE_START "Runs:%u\n", object_runs); } - fprintf (gcov_file, DEFAULT_LINE_START "Programs:%u\n", program_count); source_file = fopen (src->name, "r"); if (!source_file) diff --git a/gcc/ipa-profile.c b/gcc/ipa-profile.c index f921d1b..c74f4a4 100644 --- a/gcc/ipa-profile.c +++ b/gcc/ipa-profile.c @@ -25,13 +25,6 @@ along with GCC; see the file COPYING3. If not see from profile feedback. This histogram is complete only with LTO, otherwise it contains information only about the current unit. - Similar histogram is also estimated by coverage runtime. This histogram - is not dependent on LTO, but it suffers from various defects; first - gcov runtime is not weighting individual basic block by estimated execution - time and second the merging of multiple runs makes assumption that the - histogram distribution did not change. Consequentely histogram constructed - here may be more precise. - The information is used to set hot/cold thresholds. - Next speculative indirect call resolution is performed: the local profile pass assigns profile-id to each function and provide us with a @@ -512,25 +505,7 @@ ipa_profile (void) gcov_type threshold; gcc_assert (overall_size); - if (dump_file) - { - gcov_type min, cumulated_time = 0, cumulated_size = 0; - fprintf (dump_file, "Overall time: %" PRId64"\n", - (int64_t)overall_time); - min = get_hot_bb_threshold (); - for (i = 0; i < (int)histogram.length () && histogram[i]->count >= min; - i++) - { - cumulated_time += histogram[i]->count * histogram[i]->time; - cumulated_size += histogram[i]->size; - } - fprintf (dump_file, "GCOV min count: %" PRId64 - " Time:%3.2f%% Size:%3.2f%%\n", - (int64_t)min, - cumulated_time * 100.0 / overall_time, - cumulated_size * 100.0 / overall_size); - } cutoff = (overall_time * PARAM_VALUE (HOT_BB_COUNT_WS_PERMILLE) + 500) / 1000; threshold = 0; for (i = 0; cumulated < cutoff; i++) @@ -557,6 +532,7 @@ ipa_profile (void) cumulated_time * 100.0 / overall_time, cumulated_size * 100.0 / overall_size); } + if (threshold > get_hot_bb_threshold () || in_lto_p) { diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c index 1e6a7ad..6d9eea1 100644 --- a/gcc/lto-cgraph.c +++ b/gcc/lto-cgraph.c @@ -693,39 +693,14 @@ lto_output_ref (struct lto_simple_output_block *ob, struct ipa_ref *ref, static void output_profile_summary (struct lto_simple_output_block *ob) { - unsigned h_ix; - struct bitpack_d bp; - if (profile_info) { /* We do not output num and run_max, they are not used by GCC profile feedback and they are difficult to merge from multiple units. */ - gcc_assert (profile_info->runs); - streamer_write_uhwi_stream (ob->main_stream, profile_info->runs); - streamer_write_gcov_count_stream (ob->main_stream, profile_info->sum_max); + unsigned runs = (profile_info->runs); + streamer_write_uhwi_stream (ob->main_stream, runs); - /* sum_all is needed for computing the working set with the - histogram. */ - streamer_write_gcov_count_stream (ob->main_stream, profile_info->sum_all); - - /* Create and output a bitpack of non-zero histogram entries indices. */ - bp = bitpack_create (ob->main_stream); - for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++) - bp_pack_value (&bp, profile_info->histogram[h_ix].num_counters > 0, 1); - streamer_write_bitpack (&bp); - /* Now stream out only those non-zero entries. */ - for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++) - { - if (!profile_info->histogram[h_ix].num_counters) - continue; - streamer_write_gcov_count_stream (ob->main_stream, - profile_info->histogram[h_ix].num_counters); - streamer_write_gcov_count_stream (ob->main_stream, - profile_info->histogram[h_ix].min_value); - streamer_write_gcov_count_stream (ob->main_stream, - profile_info->histogram[h_ix].cum_value); - } /* IPA-profile computes hot bb threshold based on cumulated whole program profile. We need to stream it down to ltrans. */ if (flag_wpa) @@ -1591,46 +1566,16 @@ input_refs (struct lto_input_block *ib, } } - -static gcov_summary lto_gcov_summary; - /* Input profile_info from IB. */ static void input_profile_summary (struct lto_input_block *ib, struct lto_file_decl_data *file_data) { - unsigned h_ix; - struct bitpack_d bp; unsigned int runs = streamer_read_uhwi (ib); if (runs) { file_data->profile_info.runs = runs; - file_data->profile_info.sum_max = streamer_read_gcov_count (ib); - file_data->profile_info.sum_all = streamer_read_gcov_count (ib); - - memset (file_data->profile_info.histogram, 0, - sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE); - /* Input the bitpack of non-zero histogram indices. */ - bp = streamer_read_bitpack (ib); - /* Read in and unpack the full bitpack, flagging non-zero - histogram entries by setting the num_counters non-zero. */ - for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++) - { - file_data->profile_info.histogram[h_ix].num_counters - = bp_unpack_value (&bp, 1); - } - for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++) - { - if (!file_data->profile_info.histogram[h_ix].num_counters) - continue; - - file_data->profile_info.histogram[h_ix].num_counters - = streamer_read_gcov_count (ib); - file_data->profile_info.histogram[h_ix].min_value - = streamer_read_gcov_count (ib); - file_data->profile_info.histogram[h_ix].cum_value - = streamer_read_gcov_count (ib); - } + /* IPA-profile computes hot bb threshold based on cumulated whole program profile. We need to stream it down to ltrans. */ if (flag_ltrans) @@ -1645,13 +1590,10 @@ static void merge_profile_summaries (struct lto_file_decl_data **file_data_vec) { struct lto_file_decl_data *file_data; - unsigned int j, h_ix; + unsigned int j; gcov_unsigned_t max_runs = 0; struct cgraph_node *node; struct cgraph_edge *edge; - gcov_type saved_sum_all = 0; - gcov_summary *saved_profile_info = 0; - int saved_scale = 0; /* Find unit with maximal number of runs. If we ever get serious about roundoff errors, we might also consider computing smallest common @@ -1672,70 +1614,8 @@ merge_profile_summaries (struct lto_file_decl_data **file_data_vec) return; } - profile_info = <o_gcov_summary; - lto_gcov_summary.runs = max_runs; - lto_gcov_summary.sum_max = 0; - memset (lto_gcov_summary.histogram, 0, - sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE); - - /* Rescale all units to the maximal number of runs. - sum_max can not be easily merged, as we have no idea what files come from - the same run. We do not use the info anyway, so leave it 0. */ - for (j = 0; (file_data = file_data_vec[j]) != NULL; j++) - if (file_data->profile_info.runs) - { - int scale = GCOV_COMPUTE_SCALE (max_runs, - file_data->profile_info.runs); - lto_gcov_summary.sum_max - = MAX (lto_gcov_summary.sum_max, - apply_scale (file_data->profile_info.sum_max, scale)); - lto_gcov_summary.sum_all - = MAX (lto_gcov_summary.sum_all, - apply_scale (file_data->profile_info.sum_all, scale)); - /* Save a pointer to the profile_info with the largest - scaled sum_all and the scale for use in merging the - histogram. */ - if (!saved_profile_info - || lto_gcov_summary.sum_all > saved_sum_all) - { - saved_profile_info = &file_data->profile_info; - saved_sum_all = lto_gcov_summary.sum_all; - saved_scale = scale; - } - } - - gcc_assert (saved_profile_info); - - /* Scale up the histogram from the profile that had the largest - scaled sum_all above. */ - for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++) - { - /* Scale up the min value as we did the corresponding sum_all - above. Use that to find the new histogram index. */ - gcov_type scaled_min - = apply_scale (saved_profile_info->histogram[h_ix].min_value, - saved_scale); - /* The new index may be shared with another scaled histogram entry, - so we need to account for a non-zero histogram entry at new_ix. */ - unsigned new_ix = gcov_histo_index (scaled_min); - lto_gcov_summary.histogram[new_ix].min_value - = (lto_gcov_summary.histogram[new_ix].num_counters - ? MIN (lto_gcov_summary.histogram[new_ix].min_value, scaled_min) - : scaled_min); - /* Some of the scaled counter values would ostensibly need to be placed - into different (larger) histogram buckets, but we keep things simple - here and place the scaled cumulative counter value in the bucket - corresponding to the scaled minimum counter value. */ - lto_gcov_summary.histogram[new_ix].cum_value - += apply_scale (saved_profile_info->histogram[h_ix].cum_value, - saved_scale); - lto_gcov_summary.histogram[new_ix].num_counters - += saved_profile_info->histogram[h_ix].num_counters; - } - - /* Watch roundoff errors. */ - if (lto_gcov_summary.sum_max < max_runs) - lto_gcov_summary.sum_max = max_runs; + profile_info = XCNEW (gcov_summary); + profile_info->runs = max_runs; /* If merging already happent at WPA time, we are done. */ if (flag_ltrans) @@ -1814,10 +1694,6 @@ input_symtab (void) merge_profile_summaries (file_data_vec); - if (!flag_auto_profile) - get_working_sets (); - - /* Clear out the aux field that was used to store enough state to tell which nodes should be overwritten. */ FOR_EACH_FUNCTION (node) diff --git a/gcc/modulo-sched.c b/gcc/modulo-sched.c index 9a27365..121e619 100644 --- a/gcc/modulo-sched.c +++ b/gcc/modulo-sched.c @@ -1449,10 +1449,6 @@ sms_schedule (void) fprintf (dump_file, "%" PRId64 "max %" PRId64, (int64_t) trip_count, (int64_t) max_trip_count); fprintf (dump_file, "\n"); - fprintf (dump_file, "SMS profile-sum-max "); - fprintf (dump_file, "%" PRId64, - (int64_t) profile_info->sum_max); - fprintf (dump_file, "\n"); } } continue; @@ -1567,10 +1563,6 @@ sms_schedule (void) fprintf (dump_file, "%" PRId64, (int64_t) bb->count.to_gcov_type ()); fprintf (dump_file, "\n"); - fprintf (dump_file, "SMS profile-sum-max "); - fprintf (dump_file, "%" PRId64, - (int64_t) profile_info->sum_max); - fprintf (dump_file, "\n"); } fprintf (dump_file, "SMS doloop\n"); fprintf (dump_file, "SMS built-ddg %d\n", g->num_nodes); diff --git a/gcc/params.def b/gcc/params.def index a0ad3ec..9f06973 100644 --- a/gcc/params.def +++ b/gcc/params.def @@ -393,10 +393,15 @@ DEFPARAM(PARAM_SMS_LOOP_AVERAGE_COUNT_THRESHOLD, "A threshold on the average loop count considered by the swing modulo scheduler.", 0, 0, 0) +DEFPARAM(HOT_BB_COUNT_FRACTION, + "hot-bb-count-fraction", + "Select fraction of the maximal count of repetitions of basic block in program given basic " + "block needs to have to be considered hot (used in non-LTO mode)", + 10000, 0, 0) DEFPARAM(HOT_BB_COUNT_WS_PERMILLE, "hot-bb-count-ws-permille", "A basic block profile count is considered hot if it contributes to " - "the given permillage of the entire profiled execution.", + "the given permillage of the entire profiled execution (used in LTO mode).", 999, 0, 1000) DEFPARAM(HOT_BB_FREQUENCY_FRACTION, "hot-bb-frequency-fraction", diff --git a/gcc/postreload-gcse.c b/gcc/postreload-gcse.c index afa61dc..b569931 100644 --- a/gcc/postreload-gcse.c +++ b/gcc/postreload-gcse.c @@ -1161,7 +1161,7 @@ eliminate_partially_redundant_load (basic_block bb, rtx_insn *insn, || (optimize_bb_for_size_p (bb) && npred_ok > 1) /* If we don't have profile information we cannot tell if splitting a critical edge is profitable or not so don't do it. */ - || ((! profile_info || profile_status_for_fn (cfun) != PROFILE_READ + || ((!profile_info || profile_status_for_fn (cfun) != PROFILE_READ || targetm.cannot_modify_jumps_p ()) && critical_edge_split)) goto cleanup; diff --git a/gcc/predict.c b/gcc/predict.c index 5114552..ab2dc8e 100644 --- a/gcc/predict.c +++ b/gcc/predict.c @@ -129,12 +129,13 @@ static gcov_type min_count = -1; gcov_type get_hot_bb_threshold () { - gcov_working_set_t *ws; if (min_count == -1) { - ws = find_working_set (PARAM_VALUE (HOT_BB_COUNT_WS_PERMILLE)); - gcc_assert (ws); - min_count = ws->min_counter; + min_count + = profile_info->sum_max / PARAM_VALUE (HOT_BB_COUNT_FRACTION); + if (dump_file) + fprintf (dump_file, "Setting hotness threshold to %" PRId64 ".\n", + min_count); } return min_count; } diff --git a/gcc/profile.c b/gcc/profile.c index cb51e0d..2130319 100644 --- a/gcc/profile.c +++ b/gcc/profile.c @@ -84,11 +84,7 @@ struct bb_profile_info { /* Counter summary from the last set of coverage counts read. */ -const gcov_summary *profile_info; - -/* Counter working set information computed from the current counter - summary. Not initialized unless profile_info summary is non-NULL. */ -static gcov_working_set_t gcov_working_sets[NUM_GCOV_WORKING_SETS]; +gcov_summary *profile_info; /* Collect statistics on the performance of this pass for the entire source file. */ @@ -103,14 +99,6 @@ static int total_num_times_called; static int total_hist_br_prob[20]; static int total_num_branches; -/* Helper function to update gcov_working_sets. */ - -void add_working_set (gcov_working_set_t *set) { - int i = 0; - for (; i < NUM_GCOV_WORKING_SETS; i++) - gcov_working_sets[i] = set[i]; -} - /* Forward declarations. */ static void find_spanning_tree (struct edge_list *); @@ -207,60 +195,6 @@ instrument_values (histogram_values values) } -/* Fill the working set information into the profile_info structure. */ - -void -get_working_sets (void) -{ - unsigned ws_ix, pctinc, pct; - gcov_working_set_t *ws_info; - - if (!profile_info) - return; - - compute_working_sets (profile_info, gcov_working_sets); - - if (dump_file) - { - fprintf (dump_file, "Counter working sets:\n"); - /* Multiply the percentage by 100 to avoid float. */ - pctinc = 100 * 100 / NUM_GCOV_WORKING_SETS; - for (ws_ix = 0, pct = pctinc; ws_ix < NUM_GCOV_WORKING_SETS; - ws_ix++, pct += pctinc) - { - if (ws_ix == NUM_GCOV_WORKING_SETS - 1) - pct = 9990; - ws_info = &gcov_working_sets[ws_ix]; - /* Print out the percentage using int arithmatic to avoid float. */ - fprintf (dump_file, "\t\t%u.%02u%%: num counts=%u, min counter=" - "%" PRId64 "\n", - pct / 100, pct - (pct / 100 * 100), - ws_info->num_counters, - (int64_t)ws_info->min_counter); - } - } -} - -/* Given a the desired percentage of the full profile (sum_all from the - summary), multiplied by 10 to avoid float in PCT_TIMES_10, returns - the corresponding working set information. If an exact match for - the percentage isn't found, the closest value is used. */ - -gcov_working_set_t * -find_working_set (unsigned pct_times_10) -{ - unsigned i; - if (!profile_info) - return NULL; - gcc_assert (pct_times_10 <= 1000); - if (pct_times_10 >= 999) - return &gcov_working_sets[NUM_GCOV_WORKING_SETS - 1]; - i = pct_times_10 * NUM_GCOV_WORKING_SETS / 1000; - if (!i) - return &gcov_working_sets[0]; - return &gcov_working_sets[i - 1]; -} - /* Computes hybrid profile for all matching entries in da_file. CFG_CHECKSUM is the precomputed checksum for the CFG. */ @@ -283,21 +217,14 @@ get_exec_counts (unsigned cfg_checksum, unsigned lineno_checksum) num_edges++; } - counts = get_coverage_counts (GCOV_COUNTER_ARCS, num_edges, cfg_checksum, - lineno_checksum, &profile_info); + counts = get_coverage_counts (GCOV_COUNTER_ARCS, cfg_checksum, + lineno_checksum); if (!counts) return NULL; - get_working_sets (); - - if (dump_file && profile_info) - fprintf (dump_file, "Merged %u profiles with maximal count %u.\n", - profile_info->runs, (unsigned) profile_info->sum_max); - return counts; } - static bool is_edge_inconsistent (vec<edge, va_gc> *edges) { @@ -439,29 +366,7 @@ read_profile_edge_counts (gcov_type *exec_counts) { num_edges++; if (exec_counts) - { - edge_gcov_count (e) = exec_counts[exec_counts_pos++]; - if (edge_gcov_count (e) > profile_info->sum_max) - { - if (flag_profile_correction) - { - static bool informed = 0; - if (dump_enabled_p () && !informed) - { - dump_location_t loc - = dump_location_t::from_location_t - (input_location); - dump_printf_loc (MSG_NOTE, loc, - "corrupted profile info: edge count" - " exceeds maximal count\n"); - } - informed = 1; - } - else - error ("corrupted profile info: edge from %i to %i exceeds maximal count", - bb->index, e->dest->index); - } - } + edge_gcov_count (e) = exec_counts[exec_counts_pos++]; else edge_gcov_count (e) = 0; @@ -511,12 +416,6 @@ compute_branch_probabilities (unsigned cfg_checksum, unsigned lineno_checksum) bb_gcov_counts.safe_grow_cleared (last_basic_block_for_fn (cfun)); edge_gcov_counts = new hash_map<edge,gcov_type>; - 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. */ alloc_aux_for_blocks (sizeof (struct bb_profile_info)); FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb) @@ -871,10 +770,9 @@ compute_value_histograms (histogram_values values, unsigned cfg_checksum, continue; } - histogram_counts[t] = - get_coverage_counts (COUNTER_FOR_HIST_TYPE (t), - n_histogram_counters[t], cfg_checksum, - lineno_checksum, NULL); + histogram_counts[t] = get_coverage_counts (COUNTER_FOR_HIST_TYPE (t), + cfg_checksum, + lineno_checksum); if (histogram_counts[t]) any = 1; act_count[t] = histogram_counts[t]; diff --git a/gcc/profile.h b/gcc/profile.h index 6b37bb6..183e8d8 100644 --- a/gcc/profile.h +++ b/gcc/profile.h @@ -75,6 +75,6 @@ extern void get_working_sets (void); /* Counter summary from the last set of coverage counts read by profile.c. */ -extern const struct gcov_summary *profile_info; +extern struct gcov_summary *profile_info; #endif /* PROFILE_H */ |