mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-23 10:54:07 +08:00
Do not stream all zeros for gcda files.
gcc/ChangeLog: PR gcov-profile/95348 * coverage.c (read_counts_file): Read only COUNTERS that are not all-zero. * gcov-dump.c (tag_function): Change signature from unsigned to signed integer. (tag_blocks): Likewise. (tag_arcs): Likewise. (tag_lines): Likewise. (tag_counters): Likewise. (tag_summary): Likewise. * gcov.c (read_count_file): Read all non-zero counters sensitively. libgcc/ChangeLog: PR gcov-profile/95348 * libgcov-driver.c (merge_one_data): Merge only profiles that are not of non-zero type. (write_one_data): Write counters only if there's one non-zero value. * libgcov-util.c (tag_function): Change signature from unsigned to int. (tag_blocks): Likewise. (tag_arcs): Likewise. (tag_counters): Likewise. (tag_summary): Likewise. (tag_lines): Read only if COUNTERS is non-zero. (read_gcda_file): Handle negative length for COUNTERS type.
This commit is contained in:
parent
8f8ea4a47f
commit
ece21ff6ea
@ -245,7 +245,9 @@ read_counts_file (void)
|
||||
else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident)
|
||||
{
|
||||
counts_entry **slot, *entry, elt;
|
||||
unsigned n_counts = GCOV_TAG_COUNTER_NUM (length);
|
||||
int read_length = (int)length;
|
||||
length = read_length > 0 ? read_length : 0;
|
||||
unsigned n_counts = GCOV_TAG_COUNTER_NUM (abs (read_length));
|
||||
unsigned ix;
|
||||
|
||||
elt.ident = fn_ident;
|
||||
@ -274,8 +276,9 @@ read_counts_file (void)
|
||||
counts_hash = NULL;
|
||||
break;
|
||||
}
|
||||
for (ix = 0; ix != n_counts; ix++)
|
||||
entry->counts[ix] += gcov_read_counter ();
|
||||
if (read_length > 0)
|
||||
for (ix = 0; ix != n_counts; ix++)
|
||||
entry->counts[ix] = gcov_read_counter ();
|
||||
}
|
||||
gcov_sync (offset, length);
|
||||
if ((is_error = gcov_is_error ()))
|
||||
|
@ -32,19 +32,19 @@ static void dump_gcov_file (const char *);
|
||||
static void print_prefix (const char *, unsigned, gcov_position_t);
|
||||
static void print_usage (void);
|
||||
static void print_version (void);
|
||||
static void tag_function (const char *, unsigned, unsigned, unsigned);
|
||||
static void tag_blocks (const char *, unsigned, unsigned, unsigned);
|
||||
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 tag_function (const char *, unsigned, int, unsigned);
|
||||
static void tag_blocks (const char *, unsigned, int, unsigned);
|
||||
static void tag_arcs (const char *, unsigned, int, unsigned);
|
||||
static void tag_lines (const char *, unsigned, int, unsigned);
|
||||
static void tag_counters (const char *, unsigned, int, unsigned);
|
||||
static void tag_summary (const char *, unsigned, int, unsigned);
|
||||
extern int main (int, char **);
|
||||
|
||||
typedef struct tag_format
|
||||
{
|
||||
unsigned tag;
|
||||
char const *name;
|
||||
void (*proc) (const char *, unsigned, unsigned, unsigned);
|
||||
void (*proc) (const char *, unsigned, int, unsigned);
|
||||
} tag_format_t;
|
||||
|
||||
static int flag_dump_contents = 0;
|
||||
@ -225,6 +225,7 @@ dump_gcov_file (const char *filename)
|
||||
while (1)
|
||||
{
|
||||
gcov_position_t base, position = gcov_position ();
|
||||
int read_length;
|
||||
unsigned tag, length;
|
||||
tag_format_t const *format;
|
||||
unsigned tag_depth;
|
||||
@ -234,7 +235,8 @@ dump_gcov_file (const char *filename)
|
||||
tag = gcov_read_unsigned ();
|
||||
if (!tag)
|
||||
break;
|
||||
length = gcov_read_unsigned ();
|
||||
read_length = (int)gcov_read_unsigned ();
|
||||
length = read_length > 0 ? read_length : 0;
|
||||
base = gcov_position ();
|
||||
mask = GCOV_TAG_MASK (tag) >> 1;
|
||||
for (tag_depth = 4; mask; mask >>= 8)
|
||||
@ -264,9 +266,9 @@ dump_gcov_file (const char *filename)
|
||||
}
|
||||
|
||||
print_prefix (filename, tag_depth, position);
|
||||
printf ("%08x:%4u:%s", tag, length, format->name);
|
||||
printf ("%08x:%4u:%s", tag, abs (read_length), format->name);
|
||||
if (format->proc)
|
||||
(*format->proc) (filename, tag, length, depth);
|
||||
(*format->proc) (filename, tag, read_length, depth);
|
||||
|
||||
printf ("\n");
|
||||
if (flag_dump_contents && format->proc)
|
||||
@ -294,10 +296,10 @@ dump_gcov_file (const char *filename)
|
||||
|
||||
static void
|
||||
tag_function (const char *filename ATTRIBUTE_UNUSED,
|
||||
unsigned tag ATTRIBUTE_UNUSED, unsigned length,
|
||||
unsigned tag ATTRIBUTE_UNUSED, int length,
|
||||
unsigned depth ATTRIBUTE_UNUSED)
|
||||
{
|
||||
unsigned long pos = gcov_position ();
|
||||
long pos = gcov_position ();
|
||||
|
||||
if (!length)
|
||||
printf (" placeholder");
|
||||
@ -330,7 +332,7 @@ tag_function (const char *filename ATTRIBUTE_UNUSED,
|
||||
|
||||
static void
|
||||
tag_blocks (const char *filename ATTRIBUTE_UNUSED,
|
||||
unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED,
|
||||
unsigned tag ATTRIBUTE_UNUSED, int length ATTRIBUTE_UNUSED,
|
||||
unsigned depth ATTRIBUTE_UNUSED)
|
||||
{
|
||||
printf (" %u blocks", gcov_read_unsigned ());
|
||||
@ -338,7 +340,7 @@ tag_blocks (const char *filename ATTRIBUTE_UNUSED,
|
||||
|
||||
static void
|
||||
tag_arcs (const char *filename ATTRIBUTE_UNUSED,
|
||||
unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED,
|
||||
unsigned tag ATTRIBUTE_UNUSED, int length ATTRIBUTE_UNUSED,
|
||||
unsigned depth)
|
||||
{
|
||||
unsigned n_arcs = GCOV_TAG_ARCS_NUM (length);
|
||||
@ -380,7 +382,7 @@ tag_arcs (const char *filename ATTRIBUTE_UNUSED,
|
||||
|
||||
static void
|
||||
tag_lines (const char *filename ATTRIBUTE_UNUSED,
|
||||
unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED,
|
||||
unsigned tag ATTRIBUTE_UNUSED, int length ATTRIBUTE_UNUSED,
|
||||
unsigned depth)
|
||||
{
|
||||
if (flag_dump_contents)
|
||||
@ -425,7 +427,7 @@ tag_lines (const char *filename ATTRIBUTE_UNUSED,
|
||||
|
||||
static void
|
||||
tag_counters (const char *filename ATTRIBUTE_UNUSED,
|
||||
unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED,
|
||||
unsigned tag ATTRIBUTE_UNUSED, int length ATTRIBUTE_UNUSED,
|
||||
unsigned depth)
|
||||
{
|
||||
#define DEF_GCOV_COUNTER(COUNTER, NAME, MERGE_FN) NAME,
|
||||
@ -433,15 +435,16 @@ tag_counters (const char *filename ATTRIBUTE_UNUSED,
|
||||
#include "gcov-counter.def"
|
||||
};
|
||||
#undef DEF_GCOV_COUNTER
|
||||
unsigned n_counts = GCOV_TAG_COUNTER_NUM (length);
|
||||
int n_counts = GCOV_TAG_COUNTER_NUM (length);
|
||||
bool has_zeros = n_counts < 0;
|
||||
n_counts = abs (n_counts);
|
||||
|
||||
printf (" %s %u counts",
|
||||
counter_names[GCOV_COUNTER_FOR_TAG (tag)], n_counts);
|
||||
printf (" %s %u counts%s",
|
||||
counter_names[GCOV_COUNTER_FOR_TAG (tag)], n_counts,
|
||||
has_zeros ? " (all zero)" : "");
|
||||
if (flag_dump_contents)
|
||||
{
|
||||
unsigned ix;
|
||||
|
||||
for (ix = 0; ix != n_counts; ix++)
|
||||
for (int ix = 0; ix != n_counts; ix++)
|
||||
{
|
||||
gcov_type count;
|
||||
|
||||
@ -457,7 +460,7 @@ tag_counters (const char *filename ATTRIBUTE_UNUSED,
|
||||
printf (VALUE_PADDING_PREFIX VALUE_PREFIX, ix);
|
||||
}
|
||||
|
||||
count = gcov_read_counter ();
|
||||
count = has_zeros ? 0 : gcov_read_counter ();
|
||||
printf ("%" PRId64 " ", count);
|
||||
}
|
||||
}
|
||||
@ -465,7 +468,7 @@ 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 tag ATTRIBUTE_UNUSED, int length ATTRIBUTE_UNUSED,
|
||||
unsigned depth ATTRIBUTE_UNUSED)
|
||||
{
|
||||
gcov_summary summary;
|
||||
|
@ -1972,11 +1972,16 @@ read_count_file (void)
|
||||
}
|
||||
else if (tag == GCOV_TAG_FOR_COUNTER (GCOV_COUNTER_ARCS) && fn)
|
||||
{
|
||||
int read_length = (int)length;
|
||||
length = abs (read_length);
|
||||
if (length != GCOV_TAG_COUNTER_LENGTH (fn->counts.size ()))
|
||||
goto mismatch;
|
||||
|
||||
for (ix = 0; ix != fn->counts.size (); ix++)
|
||||
fn->counts[ix] += gcov_read_counter ();
|
||||
if (read_length > 0)
|
||||
for (ix = 0; ix != fn->counts.size (); ix++)
|
||||
fn->counts[ix] += gcov_read_counter ();
|
||||
else
|
||||
length = 0;
|
||||
}
|
||||
gcov_sync (base, length);
|
||||
if ((error = gcov_is_error ()))
|
||||
|
@ -302,13 +302,16 @@ merge_one_data (const char *filename,
|
||||
continue;
|
||||
|
||||
tag = gcov_read_unsigned ();
|
||||
length = gcov_read_unsigned ();
|
||||
int read_length = (int)gcov_read_unsigned ();
|
||||
length = abs (read_length);
|
||||
if (tag != GCOV_TAG_FOR_COUNTER (t_ix)
|
||||
|| (length != GCOV_TAG_COUNTER_LENGTH (ci_ptr->num)
|
||||
&& t_ix != GCOV_COUNTER_V_TOPN
|
||||
&& t_ix != GCOV_COUNTER_V_INDIR))
|
||||
goto read_mismatch;
|
||||
(*merge) (ci_ptr->values, ci_ptr->num);
|
||||
/* Merging with all zero counters does not make sense. */
|
||||
if (read_length > 0)
|
||||
(*merge) (ci_ptr->values, ci_ptr->num);
|
||||
ci_ptr++;
|
||||
}
|
||||
if ((error = gcov_is_error ()))
|
||||
@ -414,27 +417,40 @@ write_one_data (const struct gcov_info *gi_ptr,
|
||||
ci_ptr = gfi_ptr->ctrs;
|
||||
for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
|
||||
{
|
||||
gcov_unsigned_t n_counts;
|
||||
gcov_type *c_ptr;
|
||||
gcov_position_t n_counts;
|
||||
|
||||
if (!gi_ptr->merge[t_ix])
|
||||
continue;
|
||||
if (!gi_ptr->merge[t_ix])
|
||||
continue;
|
||||
|
||||
n_counts = ci_ptr->num;
|
||||
n_counts = ci_ptr->num;
|
||||
|
||||
if (gi_ptr->merge[t_ix] == __gcov_merge_topn)
|
||||
write_top_counters (ci_ptr, t_ix, n_counts);
|
||||
else
|
||||
{
|
||||
gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
|
||||
GCOV_TAG_COUNTER_LENGTH (n_counts));
|
||||
c_ptr = ci_ptr->values;
|
||||
while (n_counts--)
|
||||
gcov_write_counter (*c_ptr++);
|
||||
/* Do not stream when all counters are zero. */
|
||||
int all_zeros = 1;
|
||||
for (unsigned i = 0; i < n_counts; i++)
|
||||
if (ci_ptr->values[i] != 0)
|
||||
{
|
||||
all_zeros = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (all_zeros)
|
||||
gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
|
||||
GCOV_TAG_COUNTER_LENGTH (-n_counts));
|
||||
else
|
||||
{
|
||||
gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
|
||||
GCOV_TAG_COUNTER_LENGTH (n_counts));
|
||||
for (unsigned i = 0; i < n_counts; i++)
|
||||
gcov_write_counter (ci_ptr->values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
ci_ptr++;
|
||||
}
|
||||
ci_ptr++;
|
||||
}
|
||||
if (buffered)
|
||||
fn_buffer = free_fn_data (gi_ptr, fn_buffer, GCOV_COUNTERS);
|
||||
}
|
||||
|
@ -57,12 +57,12 @@ void gcov_set_verbose (void)
|
||||
#include <ftw.h>
|
||||
#endif
|
||||
|
||||
static void tag_function (unsigned, unsigned);
|
||||
static void tag_blocks (unsigned, unsigned);
|
||||
static void tag_arcs (unsigned, unsigned);
|
||||
static void tag_lines (unsigned, unsigned);
|
||||
static void tag_counters (unsigned, unsigned);
|
||||
static void tag_summary (unsigned, unsigned);
|
||||
static void tag_function (unsigned, int);
|
||||
static void tag_blocks (unsigned, int);
|
||||
static void tag_arcs (unsigned, int);
|
||||
static void tag_lines (unsigned, int);
|
||||
static void tag_counters (unsigned, int);
|
||||
static void tag_summary (unsigned, int);
|
||||
|
||||
/* The gcov_info for the first module. */
|
||||
static struct gcov_info *curr_gcov_info;
|
||||
@ -117,7 +117,7 @@ typedef struct tag_format
|
||||
{
|
||||
unsigned tag;
|
||||
char const *name;
|
||||
void (*proc) (unsigned, unsigned);
|
||||
void (*proc) (unsigned, int);
|
||||
} tag_format_t;
|
||||
|
||||
/* Handler table for various Tags. */
|
||||
@ -138,7 +138,7 @@ static const tag_format_t tag_table[] =
|
||||
/* Handler for reading function tag. */
|
||||
|
||||
static void
|
||||
tag_function (unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED)
|
||||
tag_function (unsigned tag ATTRIBUTE_UNUSED, int length ATTRIBUTE_UNUSED)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -171,7 +171,7 @@ tag_function (unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED)
|
||||
/* Handler for reading block tag. */
|
||||
|
||||
static void
|
||||
tag_blocks (unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED)
|
||||
tag_blocks (unsigned tag ATTRIBUTE_UNUSED, int length ATTRIBUTE_UNUSED)
|
||||
{
|
||||
/* TBD: gcov-tool currently does not handle gcno files. Assert here. */
|
||||
gcc_unreachable ();
|
||||
@ -180,7 +180,7 @@ tag_blocks (unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED)
|
||||
/* Handler for reading flow arc tag. */
|
||||
|
||||
static void
|
||||
tag_arcs (unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED)
|
||||
tag_arcs (unsigned tag ATTRIBUTE_UNUSED, int length ATTRIBUTE_UNUSED)
|
||||
{
|
||||
/* TBD: gcov-tool currently does not handle gcno files. Assert here. */
|
||||
gcc_unreachable ();
|
||||
@ -189,7 +189,7 @@ tag_arcs (unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED)
|
||||
/* Handler for reading line tag. */
|
||||
|
||||
static void
|
||||
tag_lines (unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED)
|
||||
tag_lines (unsigned tag ATTRIBUTE_UNUSED, int length ATTRIBUTE_UNUSED)
|
||||
{
|
||||
/* TBD: gcov-tool currently does not handle gcno files. Assert here. */
|
||||
gcc_unreachable ();
|
||||
@ -198,9 +198,9 @@ tag_lines (unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED)
|
||||
/* Handler for reading counters array tag with value as TAG and length of LENGTH. */
|
||||
|
||||
static void
|
||||
tag_counters (unsigned tag, unsigned length)
|
||||
tag_counters (unsigned tag, int length)
|
||||
{
|
||||
unsigned n_counts = GCOV_TAG_COUNTER_NUM (length);
|
||||
unsigned n_counts = GCOV_TAG_COUNTER_NUM (abs (length));
|
||||
gcov_type *values;
|
||||
unsigned ix;
|
||||
unsigned tag_ix;
|
||||
@ -211,17 +211,19 @@ tag_counters (unsigned tag, unsigned length)
|
||||
gcc_assert (k_ctrs[tag_ix].num == 0);
|
||||
k_ctrs[tag_ix].num = n_counts;
|
||||
|
||||
k_ctrs[tag_ix].values = values = (gcov_type *) xmalloc (n_counts * sizeof (gcov_type));
|
||||
k_ctrs[tag_ix].values = values = (gcov_type *) xcalloc (sizeof (gcov_type),
|
||||
n_counts);
|
||||
gcc_assert (values);
|
||||
|
||||
for (ix = 0; ix != n_counts; ix++)
|
||||
values[ix] = gcov_read_counter ();
|
||||
if (length > 0)
|
||||
for (ix = 0; ix != n_counts; ix++)
|
||||
values[ix] = gcov_read_counter ();
|
||||
}
|
||||
|
||||
/* Handler for reading summary tag. */
|
||||
|
||||
static void
|
||||
tag_summary (unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED)
|
||||
tag_summary (unsigned tag ATTRIBUTE_UNUSED, int ATTRIBUTE_UNUSED)
|
||||
{
|
||||
gcov_read_summary (&curr_gcov_info->summary);
|
||||
}
|
||||
@ -320,7 +322,8 @@ read_gcda_file (const char *filename)
|
||||
tag = gcov_read_unsigned ();
|
||||
if (!tag)
|
||||
break;
|
||||
length = gcov_read_unsigned ();
|
||||
int read_length = (int)gcov_read_unsigned ();
|
||||
length = read_length > 0 ? read_length : 0;
|
||||
base = gcov_position ();
|
||||
mask = GCOV_TAG_MASK (tag) >> 1;
|
||||
for (tag_depth = 4; mask; mask >>= 8)
|
||||
@ -353,7 +356,7 @@ read_gcda_file (const char *filename)
|
||||
{
|
||||
unsigned long actual_length;
|
||||
|
||||
(*format->proc) (tag, length);
|
||||
(*format->proc) (tag, read_length);
|
||||
|
||||
actual_length = gcov_position () - base;
|
||||
if (actual_length > length)
|
||||
|
Loading…
Reference in New Issue
Block a user