Mercurial > hg > CbC > CbC_gcc
diff gcc/gcov-io.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
line wrap: on
line diff
--- a/gcc/gcov-io.c Fri Oct 27 22:46:09 2017 +0900 +++ b/gcc/gcov-io.c Thu Oct 25 07:37:49 2018 +0900 @@ -1,5 +1,5 @@ /* File format for coverage information - Copyright (C) 1996-2017 Free Software Foundation, Inc. + Copyright (C) 1996-2018 Free Software Foundation, Inc. Contributed by Bob Manson <manson@cygnus.com>. Completely remangled by Nathan Sidwell <nathan@codesourcery.com>. @@ -446,49 +446,11 @@ GCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t tag, const struct gcov_summary *summary) { - unsigned ix, h_ix, bv_ix, h_cnt = 0; - const struct gcov_ctr_summary *csum; - unsigned histo_bitvector[GCOV_HISTOGRAM_BITVECTOR_SIZE]; + gcov_write_tag_length (tag, GCOV_TAG_SUMMARY_LENGTH); + gcov_write_unsigned (summary->runs); + gcov_write_unsigned (summary->sum_max); +} - /* 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; - csum = &summary->ctrs[GCOV_COUNTER_ARCS]; - for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++) - if (csum->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); - for (csum = summary->ctrs, ix = GCOV_COUNTERS_SUMMABLE; ix--; csum++) - { - gcov_write_unsigned (csum->num); - gcov_write_unsigned (csum->runs); - gcov_write_counter (csum->sum_all); - gcov_write_counter (csum->run_max); - gcov_write_counter (csum->sum_max); - if (ix != GCOV_COUNTER_ARCS) - { - for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++) - gcov_write_unsigned (0); - continue; - } - 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 (!csum->histogram[h_ix].num_counters) - continue; - gcov_write_unsigned (csum->histogram[h_ix].num_counters); - gcov_write_counter (csum->histogram[h_ix].min_value); - gcov_write_counter (csum->histogram[h_ix].cum_value); - } - } -} #endif /* IN_LIBGCOV */ #endif /*!IN_GCOV */ @@ -576,6 +538,55 @@ return value; } +/* Mangle filename path of BASE and output new allocated pointer with + mangled path. */ + +char * +mangle_path (char const *base) +{ + /* Convert '/' to '#', convert '..' to '^', + convert ':' to '~' on DOS based file system. */ + const char *probe; + char *buffer = (char *)xmalloc (strlen (base) + 10); + char *ptr = buffer; + +#if HAVE_DOS_BASED_FILE_SYSTEM + if (base[0] && base[1] == ':') + { + ptr[0] = base[0]; + ptr[1] = '~'; + ptr += 2; + base += 2; + } +#endif + for (; *base; base = probe) + { + size_t len; + + for (probe = base; *probe; probe++) + if (*probe == '/') + break; + len = probe - base; + if (len == 2 && base[0] == '.' && base[1] == '.') + *ptr++ = '^'; + else + { + memcpy (ptr, base, len); + ptr += len; + } + if (*probe) + { + *ptr++ = '#'; + probe++; + } + } + + /* Terminate the string. */ + *ptr = '\0'; + + return buffer; +} + /* We need to expose the below function when compiling for gcov-tool. */ #if !IN_LIBGCOV || defined (IN_GCOV_TOOL) @@ -598,69 +609,8 @@ GCOV_LINKAGE void gcov_read_summary (struct gcov_summary *summary) { - unsigned ix, h_ix, bv_ix, h_cnt = 0; - struct gcov_ctr_summary *csum; - unsigned histo_bitvector[GCOV_HISTOGRAM_BITVECTOR_SIZE]; - unsigned cur_bitvector; - - summary->checksum = gcov_read_unsigned (); - for (csum = summary->ctrs, ix = GCOV_COUNTERS_SUMMABLE; ix--; csum++) - { - csum->num = gcov_read_unsigned (); - csum->runs = gcov_read_unsigned (); - csum->sum_all = gcov_read_counter (); - csum->run_max = gcov_read_counter (); - csum->sum_max = gcov_read_counter (); - memset (csum->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"); - - csum->histogram[h_ix].num_counters = gcov_read_unsigned (); - csum->histogram[h_ix].min_value = gcov_read_counter (); - csum->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->runs = gcov_read_unsigned (); + summary->sum_max = gcov_read_unsigned (); } /* We need to expose the below function when compiling for gcov-tool. */ @@ -712,308 +662,3 @@ 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 struct gcov_ctr_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 */