X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fgcov.c;h=83515967cddd02c7c445142c859cec12a5fe7323;hb=03b7130b9aa43ec8fbfbd2463c37797fcd1ab450;hp=276918f051b741ee95ebf65f20ecfb374a6e1e5d;hpb=5a2784f82e64394ffa17f8cacdb5270482ee8423;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/gcov.c b/gcc/gcov.c index 276918f051b..83515967cdd 100644 --- a/gcc/gcov.c +++ b/gcc/gcov.c @@ -1,7 +1,7 @@ /* Gcov.c: prepend line execution counts and branch probabilities to a source file. Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. Contributed by James E. Wilson of Cygnus Support. Mangled by Bob Manson of Cygnus Support. Mangled further by Nathan Sidwell @@ -47,7 +47,6 @@ Boston, MA 02111-1307, USA. */ #include "tm.h" #include "intl.h" #include "version.h" -#undef abort #include @@ -82,6 +81,8 @@ typedef struct arc_info /* transition counts. */ gcov_type count; + /* used in cycle search, so that we do not clobber original counts. */ + gcov_type cs_count; unsigned int count_valid : 1; unsigned int on_tree : 1; @@ -371,17 +372,6 @@ fnotice (FILE *file, const char *msgid, ...) vfprintf (file, _(msgid), ap); va_end (ap); } - -/* More 'friendly' abort that prints the line and file. - config.h can #define abort fancy_abort if you like that sort of thing. */ -extern void fancy_abort (void) ATTRIBUTE_NORETURN; - -void -fancy_abort (void) -{ - fnotice (stderr, "Internal gcov abort.\n"); - exit (FATAL_EXIT_CODE); -} /* Print a usage message and exit. If ERROR_P is nonzero, this is an error, otherwise the output of --help. */ @@ -417,17 +407,13 @@ print_usage (int error_p) static void print_version (void) { - char v[4]; - unsigned version = GCOV_VERSION; - unsigned ix; - - for (ix = 4; ix--; version >>= 8) - v[ix] = version; - fnotice (stdout, "gcov %.4s (GCC %s)\n", v, version_string); - fnotice (stdout, "Copyright (C) 2002 Free Software Foundation, Inc.\n"); + fnotice (stdout, "gcov (GCC) %s\n", version_string); + fprintf (stdout, "Copyright %s 2004 Free Software Foundation, Inc.\n", + _("(C)")); fnotice (stdout, - "This is free software; see the source for copying conditions. There is NO\n\ -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"); + _("This is free software; see the source for copying conditions.\n" + "There is NO warranty; not even for MERCHANTABILITY or \n" + "FITNESS FOR A PARTICULAR PURPOSE.\n\n")); exit (SUCCESS_EXIT_CODE); } @@ -525,7 +511,7 @@ process_file (const char *file_name) for (fn = functions; fn; fn = fn->next) solve_flow_graph (fn); for (src = sources; src; src = src->next) - src->lines = (line_t *) xcalloc (src->num_lines, sizeof (line_t)); + src->lines = xcalloc (src->num_lines, sizeof (line_t)); for (fn = functions; fn; fn = fn->next) { coverage_t coverage; @@ -660,10 +646,10 @@ create_file_names (const char *file_name) *cptr = 0; length = strlen (name); - - bbg_file_name = xmalloc (length + strlen (GCOV_GRAPH_SUFFIX) + 1); + + bbg_file_name = xmalloc (length + strlen (GCOV_NOTE_SUFFIX) + 1); strcpy (bbg_file_name, name); - strcpy (bbg_file_name + length, GCOV_GRAPH_SUFFIX); + strcpy (bbg_file_name + length, GCOV_NOTE_SUFFIX); da_file_name = xmalloc (length + strlen (GCOV_DATA_SUFFIX) + 1); strcpy (da_file_name, name); @@ -687,7 +673,7 @@ find_source (const char *file_name) if (!strcmp (file_name, src->name)) return src; - src = (source_t *)xcalloc (1, sizeof (source_t)); + src = xcalloc (1, sizeof (source_t)); src->name = xstrdup (file_name); src->coverage.name = src->name; src->index = sources ? sources->index + 1 : 1; @@ -715,7 +701,7 @@ read_graph_file (void) return 1; } bbg_file_time = gcov_time (); - if (gcov_read_unsigned () != GCOV_GRAPH_MAGIC) + if (!gcov_magic (gcov_read_unsigned (), GCOV_NOTE_MAGIC)) { fnotice (stderr, "%s:not a gcov graph file\n", bbg_file_name); gcov_close (); @@ -726,13 +712,10 @@ read_graph_file (void) if (version != GCOV_VERSION) { char v[4], e[4]; - unsigned required = GCOV_VERSION; - for (ix = 4; ix--; required >>= 8, version >>= 8) - { - v[ix] = version; - e[ix] = required; - } + GCOV_UNSIGNED2STRING (v, version); + GCOV_UNSIGNED2STRING (e, GCOV_VERSION); + fnotice (stderr, "%s:version `%.4s', prefer `%.4s'\n", bbg_file_name, v, e); } @@ -756,7 +739,7 @@ read_graph_file (void) src = find_source (gcov_read_string ()); lineno = gcov_read_unsigned (); - fn = (function_t *)xcalloc (1, sizeof (function_t)); + fn = xcalloc (1, sizeof (function_t)); fn->name = function_name; fn->ident = ident; fn->checksum = checksum; @@ -789,11 +772,10 @@ read_graph_file (void) bbg_file_name, fn->name); else { - unsigned ix, num_blocks = length / 4; + unsigned ix, num_blocks = GCOV_TAG_BLOCKS_NUM (length); fn->num_blocks = num_blocks; - fn->blocks - = (block_t *)xcalloc (fn->num_blocks, sizeof (block_t)); + fn->blocks = xcalloc (fn->num_blocks, sizeof (block_t)); for (ix = 0; ix != num_blocks; ix++) fn->blocks[ix].flags = gcov_read_unsigned (); } @@ -801,7 +783,7 @@ read_graph_file (void) else if (fn && tag == GCOV_TAG_ARCS) { unsigned src = gcov_read_unsigned (); - unsigned num_dests = (length - 4) / 8; + unsigned num_dests = GCOV_TAG_ARCS_NUM (length); if (src >= fn->num_blocks || fn->blocks[src].succ) goto corrupt; @@ -814,7 +796,7 @@ read_graph_file (void) if (dest >= fn->num_blocks) goto corrupt; - arc = (arc_t *) xcalloc (1, sizeof (arc_t)); + arc = xcalloc (1, sizeof (arc_t)); arc->dst = &fn->blocks[dest]; arc->src = &fn->blocks[src]; @@ -859,8 +841,7 @@ read_graph_file (void) else if (fn && tag == GCOV_TAG_LINES) { unsigned blockno = gcov_read_unsigned (); - unsigned *line_nos - = (unsigned *)xcalloc ((length - 4) / 4, sizeof (unsigned)); + unsigned *line_nos = xcalloc (length - 1, sizeof (unsigned)); if (blockno >= fn->num_blocks || fn->blocks[blockno].u.line.encoding) goto corrupt; @@ -903,18 +884,16 @@ read_graph_file (void) } gcov_sync (base, length); if (gcov_is_error ()) - break; - } - if (!gcov_is_eof ()) - { - corrupt:; - fnotice (stderr, "%s:corrupted\n", bbg_file_name); - gcov_close (); - return 1; + { + corrupt:; + fnotice (stderr, "%s:corrupted\n", bbg_file_name); + gcov_close (); + return 1; + } } gcov_close (); - /* We built everything backwards, so nreverse them all */ + /* We built everything backwards, so nreverse them all. */ /* Reverse sources. Not strictly necessary, but we'll then process them in the 'expected' order. */ @@ -984,7 +963,7 @@ read_count_file (void) fnotice (stderr, "%s:cannot open data file\n", da_file_name); return 1; } - if (gcov_read_unsigned () != GCOV_DATA_MAGIC) + if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC)) { fnotice (stderr, "%s:not a gcov data file\n", da_file_name); cleanup:; @@ -995,13 +974,10 @@ read_count_file (void) if (version != GCOV_VERSION) { char v[4], e[4]; - unsigned desired = GCOV_VERSION; - for (ix = 4; ix--; desired >>= 8, version >>= 8) - { - v[ix] = version; - e[ix] = desired; - } + GCOV_UNSIGNED2STRING (v, version); + GCOV_UNSIGNED2STRING (e, GCOV_VERSION); + fnotice (stderr, "%s:version `%.4s', prefer version `%.4s'\n", da_file_name, v, e); } @@ -1054,26 +1030,22 @@ read_count_file (void) } else if (tag == GCOV_TAG_FOR_COUNTER (GCOV_COUNTER_ARCS) && fn) { - if (length != 8 * fn->num_counts) + if (length != GCOV_TAG_COUNTER_LENGTH (fn->num_counts)) goto mismatch; if (!fn->counts) - fn->counts - = (gcov_type *)xcalloc (fn->num_counts, sizeof (gcov_type)); + fn->counts = xcalloc (fn->num_counts, sizeof (gcov_type)); for (ix = 0; ix != fn->num_counts; ix++) fn->counts[ix] += gcov_read_counter (); } gcov_sync (base, length); if ((error = gcov_is_error ())) - break; - } - - if (!gcov_is_eof ()) - { - fnotice (stderr, error < 0 ? "%s:overflowed\n" : "%s:corrupted\n", - da_file_name); - goto cleanup; + { + fnotice (stderr, error < 0 ? "%s:overflowed\n" : "%s:corrupted\n", + da_file_name); + goto cleanup; + } } gcov_close (); @@ -1402,7 +1374,7 @@ function_summary (const coverage_t *coverage, const char *title) format_gcov (coverage->lines_executed, coverage->lines, 2), coverage->lines); else - fnotice (stdout, "No executable lines"); + fnotice (stdout, "No executable lines\n"); if (flag_branches) { @@ -1501,7 +1473,7 @@ static void add_line_counts (coverage_t *coverage, function_t *fn) { unsigned ix; - line_t *line = NULL; /* this is propagated from one iteration to the + line_t *line = NULL; /* This is propagated from one iteration to the next. */ /* Scan each basic block. */ @@ -1636,6 +1608,10 @@ accumulate_line_counts (source_t *src) if (flag_branches) add_branch_counts (&src->coverage, arc); } + + /* Initialize the cs_count. */ + for (arc = block->succ; arc; arc = arc->succ_next) + arc->cs_count = arc->count; } /* Find the loops. This uses the algorithm described in @@ -1652,7 +1628,8 @@ accumulate_line_counts (source_t *src) For each loop we find, locate the arc with the smallest transition count, and add that to the cumulative - count. Remove the arc from consideration. */ + count. Decrease flow over the cycle and remove the arc + from consideration. */ for (block = line->u.blocks; block; block = block->chain) { block_t *head = block; @@ -1678,25 +1655,33 @@ accumulate_line_counts (source_t *src) if (dst == block) { /* Found a closing arc. */ - gcov_type cycle_count = arc->count; + gcov_type cycle_count = arc->cs_count; arc_t *cycle_arc = arc; arc_t *probe_arc; /* Locate the smallest arc count of the loop. */ for (dst = head; (probe_arc = dst->u.cycle.arc); dst = probe_arc->src) - if (cycle_count > probe_arc->count) + if (cycle_count > probe_arc->cs_count) { - cycle_count = probe_arc->count; + cycle_count = probe_arc->cs_count; cycle_arc = probe_arc; } count += cycle_count; cycle_arc->cycle = 1; + + /* Remove the flow from the cycle. */ + arc->cs_count -= cycle_count; + for (dst = head; (probe_arc = dst->u.cycle.arc); + dst = probe_arc->src) + probe_arc->cs_count -= cycle_count; + /* Unwind to the cyclic arc. */ while (head != cycle_arc->src) { arc = head->u.cycle.arc; + head->u.cycle.arc = NULL; head = arc->src; } /* Move on. */ @@ -1736,7 +1721,7 @@ accumulate_line_counts (source_t *src) } } -/* Ouput information about ARC number IX. Returns nonzero if +/* Output information about ARC number IX. Returns nonzero if anything is output. */ static int