From a82502ddf807cdd25fe04879390310727156ab42 Mon Sep 17 00:00:00 2001 From: marxin Date: Thu, 9 Nov 2017 09:11:17 +0000 Subject: GCOV: support multiple functions per a line (PR gcov-profile/48463) 2017-11-09 Martin Liska PR gcov-profile/48463 * coverage.c (coverage_begin_function): Output also end locus of a function and information whether the function is artificial. * gcov-dump.c (tag_function): Parse and print the information. * gcov.c (INCLUDE_MAP): Add include. (INCLUDE_SET): Likewise. (struct line_info): Move earlier in the source file because of vector in function_info structure. (line_info::line_info): Likewise. (line_info::has_block): Likewise. (struct source_info): Add new member index. (source_info::get_functions_at_location): New function. (function_info::group_line_p): New function. (output_intermediate_line): New function. (output_intermediate_file): Use the mentioned function. (struct function_start): New. (struct function_start_pair_hash): Likewise. (process_file): Add code that identifies group functions. Assign lines either to global or function scope. (generate_results): Skip artificial functions. (find_source): Assign index for each source file. (read_graph_file): Read new flag artificial and end_line. (add_line_counts): Assign it either to global of function scope. (accumulate_line_counts): Isolate core of the function to accumulate_line_info and call it for both function and global scope lines. (accumulate_line_info): New function. (output_line_beginning): Fix GNU coding style. (print_source_line): New function. (output_line_details): Likewise. (output_function_details): Likewise. (output_lines): Iterate both source (global) scope and function scope. (struct function_line_start_cmp): New class. * doc/gcov.texi: Reflect changes in documentation. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@254562 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/gcov.c | 855 ++++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 589 insertions(+), 266 deletions(-) (limited to 'gcc/gcov.c') diff --git a/gcc/gcov.c b/gcc/gcov.c index 48bcdc0d4c3..846a2326196 100644 --- a/gcc/gcov.c +++ b/gcc/gcov.c @@ -34,6 +34,8 @@ along with Gcov; see the file COPYING3. If not see #define INCLUDE_ALGORITHM #define INCLUDE_VECTOR #define INCLUDE_STRING +#define INCLUDE_MAP +#define INCLUDE_SET #include "system.h" #include "coretypes.h" #include "tm.h" @@ -183,6 +185,42 @@ block_info::block_info (): succ (NULL), pred (NULL), num_succ (0), num_pred (0), cycle.arc = NULL; } +/* Describes a single line of source. Contains a chain of basic blocks + with code on it. */ + +struct line_info +{ + /* Default constructor. */ + line_info (); + + /* Return true when NEEDLE is one of basic blocks the line belongs to. */ + bool has_block (block_t *needle); + + /* Execution count. */ + gcov_type count; + + /* Branches from blocks that end on this line. */ + vector branches; + + /* blocks which start on this line. Used in all-blocks mode. */ + vector blocks; + + unsigned exists : 1; + unsigned unexceptional : 1; + unsigned has_unexecuted_block : 1; +}; + +line_info::line_info (): count (0), branches (), blocks (), exists (false), + unexceptional (0), has_unexecuted_block (0) +{ +} + +bool +line_info::has_block (block_t *needle) +{ + return std::find (blocks.begin (), blocks.end (), needle) != blocks.end (); +} + /* Describes a single function. Contains an array of basic blocks. */ typedef struct function_info @@ -190,6 +228,10 @@ typedef struct function_info function_info (); ~function_info (); + /* Return true when line N belongs to the function in source file SRC_IDX. + The line must be defined in body of the function, can't be inlined. */ + bool group_line_p (unsigned n, unsigned src_idx); + /* Name of function. */ char *name; char *demangled_name; @@ -200,6 +242,13 @@ typedef struct function_info /* The graph contains at least one fake incoming edge. */ unsigned has_catch : 1; + /* True when the function is artificial and does not exist + in a source file. */ + unsigned artificial : 1; + + /* True when multiple functions start at a line in a source file. */ + unsigned is_group : 1; + /* Array of basic blocks. Like in GCC, the entry block is at blocks[0] and the exit block is at blocks[1]. */ #define ENTRY_BLOCK (0) @@ -211,17 +260,39 @@ typedef struct function_info gcov_type *counts; unsigned num_counts; - /* First line number & file. */ - unsigned line; + /* First line number. */ + unsigned start_line; + + /* First line column. */ + unsigned start_column; + + /* Last line number. */ + unsigned end_line; + + /* Index of source file where the function is defined. */ unsigned src; - /* Next function in same source file. */ - struct function_info *next_file_fn; + /* Vector of line information. */ + vector lines; /* Next function. */ struct function_info *next; } function_t; +/* Function info comparer that will sort functions according to starting + line. */ + +struct function_line_start_cmp +{ + inline bool operator() (const function_info *lhs, + const function_info *rhs) + { + return (lhs->start_line == rhs->start_line + ? lhs->start_column < rhs->start_column + : lhs->start_line < rhs->start_line); + } +}; + /* Describes coverage of a file or function. */ typedef struct coverage_info @@ -239,42 +310,6 @@ typedef struct coverage_info char *name; } coverage_t; -/* Describes a single line of source. Contains a chain of basic blocks - with code on it. */ - -struct line_info -{ - /* Default constructor. */ - line_info (); - - /* Return true when NEEDLE is one of basic blocks the line belongs to. */ - bool has_block (block_t *needle); - - /* Execution count. */ - gcov_type count; - - /* Branches from blocks that end on this line. */ - vector branches; - - /* blocks which start on this line. Used in all-blocks mode. */ - vector blocks; - - unsigned exists : 1; - unsigned unexceptional : 1; - unsigned has_unexecuted_block : 1; -}; - -line_info::line_info (): count (0), branches (), blocks (), exists (false), - unexceptional (0), has_unexecuted_block (0) -{ -} - -bool -line_info::has_block (block_t *needle) -{ - return std::find (blocks.begin (), blocks.end (), needle) != blocks.end (); -} - /* Describes a file mentioned in the block graph. Contains an array of line info. */ @@ -283,6 +318,11 @@ struct source_info /* Default constructor. */ source_info (); + vector get_functions_at_location (unsigned line_num) const; + + /* Index of the source_info in sources vector. */ + unsigned index; + /* Canonical name of source file. */ char *name; time_t file_time; @@ -294,14 +334,31 @@ struct source_info /* Functions in this source file. These are in ascending line number order. */ - function_t *functions; + vector functions; }; -source_info::source_info (): name (NULL), file_time (), lines (), - coverage (), functions (NULL) +source_info::source_info (): index (0), name (NULL), file_time (), + lines (), coverage (), functions () { } +vector +source_info::get_functions_at_location (unsigned line_num) const +{ + vector r; + + for (vector::const_iterator it = functions.begin (); + it != functions.end (); it++) + { + if ((*it)->start_line == line_num && (*it)->src == index) + r.push_back (*it); + } + + std::sort (r.begin (), r.end (), function_line_start_cmp ()); + + return r; +} + class name_map { public: @@ -495,8 +552,9 @@ extern int main (int, char **); function_info::function_info (): name (NULL), demangled_name (NULL), ident (0), lineno_checksum (0), cfg_checksum (0), has_catch (0), + artificial (0), is_group (0), blocks (), blocks_executed (0), counts (NULL), num_counts (0), - line (0), src (0), next_file_fn (NULL), next (NULL) + start_line (0), start_column (0), end_line (0), src (0), lines (), next (NULL) { } @@ -518,6 +576,11 @@ function_info::~function_info () free (name); } +bool function_info::group_line_p (unsigned n, unsigned src_idx) +{ + return is_group && src == src_idx && start_line <= n && n <= end_line; +} + /* Cycle detection! There are a bajillion algorithms that do this. Boost's function is named hawick_cycles, so I used the algorithm by K. A. Hawick and H. A. James in @@ -889,6 +952,42 @@ process_args (int argc, char **argv) return optind; } +/* Output intermediate LINE sitting on LINE_NUM to output file F. */ + +static void +output_intermediate_line (FILE *f, line_info *line, unsigned line_num) +{ + if (!line->exists) + return; + + fprintf (f, "lcount:%u,%s,%d\n", line_num, + format_gcov (line->count, 0, -1), + line->has_unexecuted_block); + + vector::const_iterator it; + if (flag_branches) + for (it = line->branches.begin (); it != line->branches.end (); + it++) + { + if (!(*it)->is_unconditional && !(*it)->is_call_non_return) + { + const char *branch_type; + /* branch:, + branch_coverage_type + : notexec (Branch not executed) + : taken (Branch executed and taken) + : nottaken (Branch executed, but not taken) + */ + if ((*it)->src->count) + branch_type + = ((*it)->count > 0) ? "taken" : "nottaken"; + else + branch_type = "notexec"; + fprintf (f, "branch:%d,%s\n", line_num, branch_type); + } + } +} + /* Output the result in intermediate format used by 'lcov'. The intermediate format contains a single file named 'foo.cc.gcov', @@ -902,50 +1001,95 @@ file 'foo.cc.gcov' similar to the above example. */ static void output_intermediate_file (FILE *gcov_file, source_info *src) { - unsigned line_num; /* current line number. */ - const line_info *line; /* current line info ptr. */ - function_t *fn; /* current function info ptr. */ - fprintf (gcov_file, "file:%s\n", src->name); /* source file name */ - for (fn = src->functions; fn; fn = fn->next_file_fn) + std::sort (src->functions.begin (), src->functions.end (), + function_line_start_cmp ()); + for (vector::iterator it = src->functions.begin (); + it != src->functions.end (); it++) { /* function:,, */ - fprintf (gcov_file, "function:%d,%s,%s\n", fn->line, - format_gcov (fn->blocks[0].count, 0, -1), - flag_demangled_names ? fn->demangled_name : fn->name); + fprintf (gcov_file, "function:%d,%d,%s,%s\n", (*it)->start_line, + (*it)->end_line, format_gcov ((*it)->blocks[0].count, 0, -1), + flag_demangled_names ? (*it)->demangled_name : (*it)->name); } - for (line_num = 1, line = &src->lines[line_num]; - line_num < src->lines.size (); - line_num++, line++) + for (unsigned line_num = 0; line_num <= src->lines.size (); line_num++) { - if (line->exists) - fprintf (gcov_file, "lcount:%u,%s,%d\n", line_num, - format_gcov (line->count, 0, -1), line->has_unexecuted_block); - if (flag_branches) - for (vector::const_iterator it = line->branches.begin (); - it != line->branches.end (); it++) - { - if (!(*it)->is_unconditional && !(*it)->is_call_non_return) - { - const char *branch_type; - /* branch:, - branch_coverage_type - : notexec (Branch not executed) - : taken (Branch executed and taken) - : nottaken (Branch executed, but not taken) - */ - if ((*it)->src->count) - branch_type = ((*it)->count > 0) ? "taken" : "nottaken"; - else - branch_type = "notexec"; - fprintf (gcov_file, "branch:%d,%s\n", line_num, branch_type); - } - } + vector fns = src->get_functions_at_location (line_num); + + /* Print first group functions that begin on the line. */ + for (vector::iterator it2 = fns.begin (); + it2 != fns.end (); it2++) + { + vector &lines = (*it2)->lines; + for (unsigned i = 0; i < lines.size (); i++) + { + line_info *line = &lines[i]; + output_intermediate_line (gcov_file, line, line_num + i); + } + } + + /* Follow with lines associated with the source file. */ + output_intermediate_line (gcov_file, &src->lines[line_num], line_num); } } +/* Function start pair. */ +struct function_start +{ + unsigned source_file_idx; + unsigned start_line; +}; + +/* Traits class for function start hash maps below. */ + +struct function_start_pair_hash : typed_noop_remove +{ + typedef function_start value_type; + typedef function_start compare_type; + + static hashval_t + hash (const function_start &ref) + { + inchash::hash hstate (0); + hstate.add_int (ref.source_file_idx); + hstate.add_int (ref.start_line); + return hstate.end (); + } + + static bool + equal (const function_start &ref1, const function_start &ref2) + { + return (ref1.source_file_idx == ref2.source_file_idx + && ref1.start_line == ref2.start_line); + } + + static void + mark_deleted (function_start &ref) + { + ref.start_line = ~1U; + } + + static void + mark_empty (function_start &ref) + { + ref.start_line = ~2U; + } + + static bool + is_deleted (const function_start &ref) + { + return ref.start_line == ~1U; + } + + static bool + is_empty (const function_start &ref) + { + return ref.start_line == ~2U; + } +}; + /* Process a single input file. */ static void @@ -959,6 +1103,28 @@ process_file (const char *file_name) return; read_count_file (fns); + + hash_map fn_map; + + /* Identify group functions. */ + for (function_t *f = fns; f; f = f->next) + if (!f->artificial) + { + function_start needle; + needle.source_file_idx = f->src; + needle.start_line = f->start_line; + + function_t **slot = fn_map.get (needle); + if (slot) + { + gcc_assert ((*slot)->end_line == f->end_line); + (*slot)->is_group = 1; + f->is_group = 1; + } + else + fn_map.put (needle, f); + } + while (fns) { function_t *fn = fns; @@ -968,46 +1134,50 @@ process_file (const char *file_name) if (fn->counts || no_data_file) { unsigned src = fn->src; - unsigned line = fn->line; unsigned block_no; - function_t *probe, **prev; - - /* Now insert it into the source file's list of - functions. Normally functions will be encountered in - ascending order, so a simple scan is quick. Note we're - building this list in reverse order. */ - for (prev = &sources[src].functions; - (probe = *prev); prev = &probe->next_file_fn) - if (probe->line <= line) - break; - fn->next_file_fn = probe; - *prev = fn; - /* Mark last line in files touched by function. */ - for (block_no = 0; block_no != fn->blocks.size (); block_no++) + /* Process only non-artificial functions. */ + if (!fn->artificial) { - block_t *block = &fn->blocks[block_no]; - for (unsigned i = 0; i < block->locations.size (); i++) - { - unsigned s = block->locations[i].source_file_idx; - - /* Sort lines of locations. */ - sort (block->locations[i].lines.begin (), - block->locations[i].lines.end ()); + source_info *s = &sources[src]; + s->functions.push_back (fn); - if (!block->locations[i].lines.empty ()) + /* Mark last line in files touched by function. */ + for (block_no = 0; block_no != fn->blocks.size (); block_no++) + { + block_t *block = &fn->blocks[block_no]; + for (unsigned i = 0; i < block->locations.size (); i++) { - unsigned last_line - = block->locations[i].lines.back () + 1; - if (last_line > sources[s].lines.size ()) - sources[s].lines.resize (last_line); + /* Sort lines of locations. */ + sort (block->locations[i].lines.begin (), + block->locations[i].lines.end ()); + + if (!block->locations[i].lines.empty ()) + { + s = &sources[block->locations[i].source_file_idx]; + unsigned last_line + = block->locations[i].lines.back (); + + /* Record new lines for the function. */ + if (last_line >= s->lines.size ()) + { + /* Record new lines for a source file. */ + s->lines.resize (last_line + 1); + } + } } + + /* Allocate lines for group function, following start_line + and end_line information of the function. */ + if (fn->is_group) + fn->lines.resize (fn->end_line - fn->start_line + 1); } + + solve_flow_graph (fn); + if (fn->has_catch) + find_exception_blocks (fn); } - solve_flow_graph (fn); - if (fn->has_catch) - find_exception_blocks (fn); *fn_end = fn; fn_end = &fn->next; } @@ -1057,6 +1227,8 @@ generate_results (const char *file_name) for (fn = functions; fn; fn = fn->next) { coverage_t coverage; + if (fn->artificial) + continue; memset (&coverage, 0, sizeof (coverage)); coverage.name = flag_demangled_names ? fn->demangled_name : fn->name; @@ -1237,6 +1409,7 @@ find_source (const char *file_name) src = &sources.back (); src->name = canon; src->coverage.name = src->name; + src->index = idx; if (source_length #if HAVE_DOS_BASED_FILE_SYSTEM /* You lose if separators don't match exactly in the @@ -1328,15 +1501,18 @@ read_graph_file (void) if (tag == GCOV_TAG_FUNCTION) { char *function_name; - unsigned ident, lineno; + unsigned ident; unsigned lineno_checksum, cfg_checksum; ident = gcov_read_unsigned (); lineno_checksum = gcov_read_unsigned (); cfg_checksum = gcov_read_unsigned (); function_name = xstrdup (gcov_read_string ()); + unsigned artificial = gcov_read_unsigned (); unsigned src_idx = find_source (gcov_read_string ()); - lineno = gcov_read_unsigned (); + unsigned start_line = gcov_read_unsigned (); + unsigned start_column = gcov_read_unsigned (); + unsigned end_line = gcov_read_unsigned (); fn = new function_t; fn->name = function_name; @@ -1350,9 +1526,11 @@ read_graph_file (void) fn->lineno_checksum = lineno_checksum; fn->cfg_checksum = cfg_checksum; fn->src = src_idx; - fn->line = lineno; + fn->start_line = start_line; + fn->start_column = start_column; + fn->end_line = end_line; + fn->artificial = artificial; - fn->next_file_fn = NULL; fn->next = NULL; *fns_end = fn; fns_end = &fn->next; @@ -2266,48 +2444,66 @@ add_line_counts (coverage_t *coverage, function_t *fn) fn->blocks_executed++; for (unsigned i = 0; i < block->locations.size (); i++) { - source_info *src = &sources[block->locations[i].source_file_idx]; - + unsigned src_idx = block->locations[i].source_file_idx; vector &lines = block->locations[i].lines; + + block->cycle.arc = NULL; + block->cycle.ident = ~0U; + for (unsigned j = 0; j < lines.size (); j++) { - line = &src->lines[lines[j]]; - if (coverage) + unsigned ln = lines[j]; + + /* Line belongs to a function that is in a group. */ + if (fn->group_line_p (ln, src_idx)) { - if (!line->exists) - coverage->lines++; - if (!line->count && block->count) - coverage->lines_executed++; + gcc_assert (lines[j] - fn->start_line < fn->lines.size ()); + line = &(fn->lines[lines[j] - fn->start_line]); + line->exists = 1; + if (!block->exceptional) + { + line->unexceptional = 1; + if (block->count == 0) + line->has_unexecuted_block = 1; + } + line->count += block->count; } - line->exists = 1; - if (!block->exceptional) + else { - line->unexceptional = 1; - if (block->count == 0) - line->has_unexecuted_block = 1; + gcc_assert (ln < sources[src_idx].lines.size ()); + line = &(sources[src_idx].lines[ln]); + if (coverage) + { + if (!line->exists) + coverage->lines++; + if (!line->count && block->count) + coverage->lines_executed++; + } + line->exists = 1; + if (!block->exceptional) + { + line->unexceptional = 1; + if (block->count == 0) + line->has_unexecuted_block = 1; + } + line->count += block->count; } - line->count += block->count; } - } - block->cycle.arc = NULL; - block->cycle.ident = ~0U; - has_any_line = true; - if (!ix || ix + 1 == fn->blocks.size ()) - /* Entry or exit block */; - else if (line != NULL) - { - line->blocks.push_back (block); + has_any_line = true; - if (flag_branches) + if (!ix || ix + 1 == fn->blocks.size ()) + /* Entry or exit block. */; + else if (line != NULL) { - arc_t *arc; + line->blocks.push_back (block); - for (arc = block->succ; arc; arc = arc->succ_next) + if (flag_branches) { - line->branches.push_back (arc); - if (coverage && !arc->is_unconditional) - add_branch_counts (coverage, arc); + arc_t *arc; + + for (arc = block->succ; arc; arc = arc->succ_next) + line->branches.push_back (arc); } } } @@ -2317,72 +2513,113 @@ add_line_counts (coverage_t *coverage, function_t *fn) fnotice (stderr, "%s:no lines for '%s'\n", bbg_file_name, fn->name); } +/* Accumulate info for LINE that belongs to SRC source file. If ADD_COVERAGE + is set to true, update source file summary. */ + +static void accumulate_line_info (line_info *line, source_info *src, + bool add_coverage) +{ + if (add_coverage) + for (vector::iterator it = line->branches.begin (); + it != line->branches.end (); it++) + add_branch_counts (&src->coverage, *it); + + if (!line->blocks.empty ()) + { + /* The user expects the line count to be the number of times + a line has been executed. Simply summing the block count + will give an artificially high number. The Right Thing + is to sum the entry counts to the graph of blocks on this + line, then find the elementary cycles of the local graph + and add the transition counts of those cycles. */ + gcov_type count = 0; + + /* Cycle detection. */ + for (vector::iterator it = line->blocks.begin (); + it != line->blocks.end (); it++) + { + for (arc_t *arc = (*it)->pred; arc; arc = arc->pred_next) + if (!line->has_block (arc->src)) + count += arc->count; + for (arc_t *arc = (*it)->succ; arc; arc = arc->succ_next) + arc->cs_count = arc->count; + } + + /* Now, add the count of loops entirely on this line. */ + count += get_cycles_count (*line); + line->count = count; + } + + if (line->exists && add_coverage) + { + src->coverage.lines++; + if (line->count) + src->coverage.lines_executed++; + } +} + /* Accumulate the line counts of a file. */ static void accumulate_line_counts (source_info *src) { - function_t *fn, *fn_p, *fn_n; - unsigned ix = 0; - - /* Reverse the function order. */ - for (fn = src->functions, fn_p = NULL; fn; fn_p = fn, fn = fn_n) + /* First work on group functions. */ + for (vector::iterator it = src->functions.begin (); + it != src->functions.end (); it++) { - fn_n = fn->next_file_fn; - fn->next_file_fn = fn_p; + function_info *fn = *it; + + if (fn->src != src->index || !fn->is_group) + continue; + + for (vector::iterator it2 = fn->lines.begin (); + it2 != fn->lines.end (); it2++) + { + line_info *line = &(*it2); + accumulate_line_info (line, src, false); + } } - src->functions = fn_p; - for (vector::reverse_iterator it = src->lines.rbegin (); - it != src->lines.rend (); it++) - { - line_info *line = &(*it); - if (!line->blocks.empty ()) - { - /* The user expects the line count to be the number of times - a line has been executed. Simply summing the block count - will give an artificially high number. The Right Thing - is to sum the entry counts to the graph of blocks on this - line, then find the elementary cycles of the local graph - and add the transition counts of those cycles. */ - gcov_type count = 0; - - /* Sum the entry arcs. */ - for (vector::iterator it = line->blocks.begin (); - it != line->blocks.end (); it++) - { - arc_t *arc; + /* Work on global lines that line in source file SRC. */ + for (vector::iterator it = src->lines.begin (); + it != src->lines.end (); it++) + accumulate_line_info (&(*it), src, true); - for (arc = (*it)->pred; arc; arc = arc->pred_next) - if (flag_branches) - add_branch_counts (&src->coverage, arc); - } + /* If not using intermediate mode, sum lines of group functions and + add them to lines that live in a source file. */ + if (!flag_intermediate_format) + for (vector::iterator it = src->functions.begin (); + it != src->functions.end (); it++) + { + function_info *fn = *it; - /* Cycle detection. */ - for (vector::iterator it = line->blocks.begin (); - it != line->blocks.end (); it++) - { - for (arc_t *arc = (*it)->pred; arc; arc = arc->pred_next) - if (!line->has_block (arc->src)) - count += arc->count; - for (arc_t *arc = (*it)->succ; arc; arc = arc->succ_next) - arc->cs_count = arc->count; - } + if (fn->src != src->index || !fn->is_group) + continue; - /* Now, add the count of loops entirely on this line. */ - count += get_cycles_count (*line); - line->count = count; - } + for (unsigned i = 0; i < fn->lines.size (); i++) + { + line_info *fn_line = &fn->lines[i]; + if (fn_line->exists) + { + unsigned ln = fn->start_line + i; + line_info *src_line = &src->lines[ln]; - if (line->exists) - { - src->coverage.lines++; - if (line->count) - src->coverage.lines_executed++; - } + if (!src_line->exists) + src->coverage.lines++; + if (!src_line->count && fn_line->count) + src->coverage.lines_executed++; - ix++; - } + src_line->count += fn_line->count; + src_line->exists = 1; + + if (fn_line->has_unexecuted_block) + src_line->has_unexecuted_block = 1; + + if (fn_line->unexceptional) + src_line->unexceptional = 1; + } + } + } } /* Output information about ARC number IX. Returns nonzero if @@ -2500,7 +2737,8 @@ output_line_beginning (FILE *f, bool exists, bool unexceptional, if (flag_use_colors) { pad_count_string (s); - s = SGR_SEQ (COLOR_BG_MAGENTA COLOR_SEPARATOR COLOR_FG_WHITE); + s.insert (0, SGR_SEQ (COLOR_BG_MAGENTA + COLOR_SEPARATOR COLOR_FG_WHITE)); s += SGR_RESET; } else @@ -2538,6 +2776,86 @@ output_line_beginning (FILE *f, bool exists, bool unexceptional, fprintf (f, "%s:%5u", s.c_str (), line_num); } +static void +print_source_line (FILE *f, const vector &source_lines, + unsigned line) +{ + gcc_assert (line >= 1); + gcc_assert (line <= source_lines.size ()); + + fprintf (f, ":%s\n", source_lines[line - 1]); +} + +/* Output line details for LINE and print it to F file. LINE lives on + LINE_NUM. */ + +static void +output_line_details (FILE *f, const line_info *line, unsigned line_num) +{ + if (flag_all_blocks) + { + arc_t *arc; + int ix, jx; + + ix = jx = 0; + for (vector::const_iterator it = line->blocks.begin (); + it != line->blocks.end (); it++) + { + if (!(*it)->is_call_return) + { + output_line_beginning (f, line->exists, + (*it)->exceptional, false, + (*it)->count, line_num, + "%%%%%", "$$$$$"); + fprintf (f, "-block %2d", ix++); + if (flag_verbose) + fprintf (f, " (BB %u)", (*it)->id); + fprintf (f, "\n"); + } + if (flag_branches) + for (arc = (*it)->succ; arc; arc = arc->succ_next) + jx += output_branch_count (f, jx, arc); + } + } + else if (flag_branches) + { + int ix; + + ix = 0; + for (vector::const_iterator it = line->branches.begin (); + it != line->branches.end (); it++) + ix += output_branch_count (f, ix, (*it)); + } +} + +/* Output detail statistics about function FN to file F. */ + +static void +output_function_details (FILE *f, const function_info *fn) +{ + if (!flag_branches) + return; + + arc_t *arc = fn->blocks[EXIT_BLOCK].pred; + gcov_type return_count = fn->blocks[EXIT_BLOCK].count; + gcov_type called_count = fn->blocks[ENTRY_BLOCK].count; + + for (; arc; arc = arc->pred_next) + if (arc->fake) + return_count -= arc->count; + + fprintf (f, "function %s", + flag_demangled_names ? fn->demangled_name : fn->name); + fprintf (f, " called %s", + format_gcov (called_count, 0, -1)); + fprintf (f, " returned %s", + format_gcov (return_count, called_count, 0)); + fprintf (f, " blocks executed %s", + format_gcov (fn->blocks_executed, fn->blocks.size () - 2, + 0)); + fprintf (f, "\n"); +} + /* Read in the source file one line at a time, and output that line to the gcov file preceded by its execution count and other information. */ @@ -2546,12 +2864,10 @@ static void output_lines (FILE *gcov_file, const source_info *src) { #define DEFAULT_LINE_START " -: 0:" +#define FN_SEPARATOR "------------------\n" FILE *source_file; - unsigned line_num; /* current line number. */ - const line_info *line; /* current line info ptr. */ - const char *retval = ""; /* status of source file reading. */ - function_t *fn = NULL; + const char *retval; fprintf (gcov_file, DEFAULT_LINE_START "Source:%s\n", src->coverage.name); if (!multiple_files) @@ -2565,43 +2881,40 @@ output_lines (FILE *gcov_file, const source_info *src) source_file = fopen (src->name, "r"); if (!source_file) - { - fnotice (stderr, "Cannot open source file %s\n", src->name); - retval = NULL; - } + fnotice (stderr, "Cannot open source file %s\n", src->name); else if (src->file_time == 0) fprintf (gcov_file, DEFAULT_LINE_START "Source is newer than graph\n"); - if (flag_branches) - fn = src->functions; + vector source_lines; + if (source_file) + while ((retval = read_line (source_file)) != NULL) + source_lines.push_back (xstrdup (retval)); - for (line_num = 1, line = &src->lines[line_num]; - line_num < src->lines.size (); line_num++, line++) + unsigned line_start_group = 0; + vector fns; + + for (unsigned line_num = 1; line_num <= source_lines.size (); line_num++) { - for (; fn && fn->line == line_num; fn = fn->next_file_fn) + if (line_num >= src->lines.size ()) { - arc_t *arc = fn->blocks[EXIT_BLOCK].pred; - gcov_type return_count = fn->blocks[EXIT_BLOCK].count; - gcov_type called_count = fn->blocks[ENTRY_BLOCK].count; - - for (; arc; arc = arc->pred_next) - if (arc->fake) - return_count -= arc->count; - - fprintf (gcov_file, "function %s", flag_demangled_names ? - fn->demangled_name : fn->name); - fprintf (gcov_file, " called %s", - format_gcov (called_count, 0, -1)); - fprintf (gcov_file, " returned %s", - format_gcov (return_count, called_count, 0)); - fprintf (gcov_file, " blocks executed %s", - format_gcov (fn->blocks_executed, fn->blocks.size () - 2, - 0)); - fprintf (gcov_file, "\n"); + fprintf (gcov_file, "%9s:%5u", "-", line_num); + print_source_line (gcov_file, source_lines, line_num); + continue; } - if (retval) - retval = read_line (source_file); + const line_info *line = &src->lines[line_num]; + + if (line_start_group == 0) + { + fns = src->get_functions_at_location (line_num); + if (fns.size () > 1) + line_start_group = fns[0]->end_line; + else if (fns.size () == 1) + { + function_t *fn = fns[0]; + output_function_details (gcov_file, fn); + } + } /* For lines which don't exist in the .bb file, print '-' before the source line. For lines which exist but were never @@ -2610,54 +2923,64 @@ output_lines (FILE *gcov_file, const source_info *src) There are 16 spaces of indentation added before the source line so that tabs won't be messed up. */ output_line_beginning (gcov_file, line->exists, line->unexceptional, - line->has_unexecuted_block, line->count, line_num, - "=====", "#####"); - fprintf (gcov_file, ":%s\n", retval ? retval : "/*EOF*/"); + line->has_unexecuted_block, line->count, + line_num, "=====", "#####"); - if (flag_all_blocks) - { - arc_t *arc; - int ix, jx; + print_source_line (gcov_file, source_lines, line_num); + output_line_details (gcov_file, line, line_num); - ix = jx = 0; - for (vector::const_iterator it = line->blocks.begin (); - it != line->blocks.end (); it++) + if (line_start_group == line_num) + { + for (vector::iterator it = fns.begin (); + it != fns.end (); it++) { - if (!(*it)->is_call_return) + function_info *fn = *it; + vector &lines = fn->lines; + + fprintf (gcov_file, FN_SEPARATOR); + + string fn_name + = flag_demangled_names ? fn->demangled_name : fn->name; + + if (flag_use_colors) { + fn_name.insert (0, SGR_SEQ (COLOR_FG_CYAN)); + fn_name += SGR_RESET; + } + + fprintf (gcov_file, "%s:\n", fn_name.c_str ()); + + output_function_details (gcov_file, fn); + + /* Print all lines covered by the function. */ + for (unsigned i = 0; i < lines.size (); i++) + { + line_info *line = &lines[i]; + unsigned l = fn->start_line + i; + + /* For lines which don't exist in the .bb file, print '-' + before the source line. For lines which exist but + were never executed, print '#####' or '=====' before + the source line. Otherwise, print the execution count + before the source line. + There are 16 spaces of indentation added before the source + line so that tabs won't be messed up. */ output_line_beginning (gcov_file, line->exists, - (*it)->exceptional, false, - (*it)->count, line_num, - "%%%%%", "$$$$$"); - fprintf (gcov_file, "-block %2d", ix++); - if (flag_verbose) - fprintf (gcov_file, " (BB %u)", (*it)->id); - fprintf (gcov_file, "\n"); + line->unexceptional, + line->has_unexecuted_block, + line->count, + l, "=====", "#####"); + + print_source_line (gcov_file, source_lines, l); + output_line_details (gcov_file, line, l); } - if (flag_branches) - for (arc = (*it)->succ; arc; arc = arc->succ_next) - jx += output_branch_count (gcov_file, jx, arc); } - } - else if (flag_branches) - { - int ix; - ix = 0; - for (vector::const_iterator it = line->branches.begin (); - it != line->branches.end (); it++) - ix += output_branch_count (gcov_file, ix, (*it)); + fprintf (gcov_file, FN_SEPARATOR); + line_start_group = 0; } } - /* Handle all remaining source lines. There may be lines after the - last line of code. */ - if (retval) - { - for (; (retval = read_line (source_file)); line_num++) - fprintf (gcov_file, "%9s:%5u:%s\n", "-", line_num, retval); - } - if (source_file) fclose (source_file); } -- cgit v1.2.1 From fa6f8ae7f11890248625f0274948e583fde457f2 Mon Sep 17 00:00:00 2001 From: marxin Date: Fri, 10 Nov 2017 14:40:17 +0000 Subject: GCOV: do not support unexecuted blocks in Ada 2017-11-10 Martin Liska * coverage.c (coverage_init): Stream information about support of has_unexecuted_blocks. * doc/gcov.texi: Document that. * gcov-dump.c (dump_gcov_file): Support it in gcov_dump tool. * gcov.c (read_graph_file): Likewise. (output_line_beginning): Fix a small issue with color output. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@254627 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/gcov.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'gcc/gcov.c') diff --git a/gcc/gcov.c b/gcc/gcov.c index 846a2326196..7152372ef31 100644 --- a/gcc/gcov.c +++ b/gcc/gcov.c @@ -424,6 +424,9 @@ static char *bbg_file_name; /* Stamp of the bbg file */ static unsigned bbg_stamp; +/* Supports has_unexecuted_blocks functionality. */ +static unsigned bbg_supports_has_unexecuted_blocks; + /* Name and file pointer of the input file for the count data (gcda). */ static char *da_file_name; @@ -1492,6 +1495,7 @@ read_graph_file (void) bbg_file_name, v, e); } bbg_stamp = gcov_read_unsigned (); + bbg_supports_has_unexecuted_blocks = gcov_read_unsigned (); while ((tag = gcov_read_unsigned ())) { @@ -2732,7 +2736,8 @@ output_line_beginning (FILE *f, bool exists, bool unexceptional, if (count > 0) { s = format_gcov (count, 0, -1); - if (has_unexecuted_block) + if (has_unexecuted_block + && bbg_supports_has_unexecuted_blocks) { if (flag_use_colors) { -- cgit v1.2.1 From a277f643ee5676eda2a4a969ab3cb2bee85fcd8e Mon Sep 17 00:00:00 2001 From: marxin Date: Fri, 10 Nov 2017 15:23:24 +0000 Subject: GCOV: create one intermediate file per a gcno file (PR gcov-profile/82702). 2017-11-10 Martin Liska PR gcov-profile/82702 * gcov.c (main): Handle intermediate files in a different way. (get_gcov_intermediate_filename): New function. (output_gcov_file): Remove support of intermediate files. (generate_results): Allocate intermediate file. (release_structures): Clean-up properly fn_end. (output_intermediate_file): Start iterating with line 1. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@254629 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/gcov.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 76 insertions(+), 20 deletions(-) (limited to 'gcc/gcov.c') diff --git a/gcc/gcov.c b/gcc/gcov.c index 7152372ef31..3c2c2700ab6 100644 --- a/gcc/gcov.c +++ b/gcc/gcov.c @@ -784,11 +784,13 @@ main (int argc, char **argv) printf ("Processing file %d out of %d\n", argno - first_arg + 1, argc - first_arg); process_file (argv[argno]); - } - - generate_results (multiple_files ? NULL : argv[argc - 1]); - release_structures (); + if (flag_intermediate_format || argno == argc - 1) + { + generate_results (argv[argno]); + release_structures (); + } + } return 0; } @@ -991,6 +993,31 @@ output_intermediate_line (FILE *f, line_info *line, unsigned line_num) } } +/* Get the name of the gcov file. The return value must be free'd. + + It appends the '.gcov' extension to the *basename* of the file. + The resulting file name will be in PWD. + + e.g., + input: foo.da, output: foo.da.gcov + input: a/b/foo.cc, output: foo.cc.gcov */ + +static char * +get_gcov_intermediate_filename (const char *file_name) +{ + const char *gcov = ".gcov"; + char *result; + const char *cptr; + + /* Find the 'basename'. */ + cptr = lbasename (file_name); + + result = XNEWVEC (char, strlen (cptr) + strlen (gcov) + 1); + sprintf (result, "%s%s", cptr, gcov); + + return result; +} + /* Output the result in intermediate format used by 'lcov'. The intermediate format contains a single file named 'foo.cc.gcov', @@ -1017,7 +1044,7 @@ output_intermediate_file (FILE *gcov_file, source_info *src) flag_demangled_names ? (*it)->demangled_name : (*it)->name); } - for (unsigned line_num = 0; line_num <= src->lines.size (); line_num++) + for (unsigned line_num = 1; line_num <= src->lines.size (); line_num++) { vector fns = src->get_functions_at_location (line_num); @@ -1200,19 +1227,16 @@ output_gcov_file (const char *file_name, source_info *src) { FILE *gcov_file = fopen (gcov_file_name, "w"); if (gcov_file) - { - fnotice (stdout, "Creating '%s'\n", gcov_file_name); - - if (flag_intermediate_format) - output_intermediate_file (gcov_file, src); - else - output_lines (gcov_file, src); - if (ferror (gcov_file)) - fnotice (stderr, "Error writing output file '%s'\n", gcov_file_name); - fclose (gcov_file); - } + { + fnotice (stdout, "Creating '%s'\n", gcov_file_name); + output_lines (gcov_file, src); + if (ferror (gcov_file)) + fnotice (stderr, "Error writing output file '%s'\n", + gcov_file_name); + fclose (gcov_file); + } else - fnotice (stderr, "Could not open output file '%s'\n", gcov_file_name); + fnotice (stderr, "Could not open output file '%s'\n", gcov_file_name); } else { @@ -1226,6 +1250,8 @@ static void generate_results (const char *file_name) { function_t *fn; + FILE *gcov_intermediate_file = NULL; + char *gcov_intermediate_filename = NULL; for (fn = functions; fn; fn = fn->next) { @@ -1256,6 +1282,19 @@ generate_results (const char *file_name) file_name = canonicalize_name (file_name); } + if (flag_gcov_file && flag_intermediate_format) + { + /* Open the intermediate file. */ + gcov_intermediate_filename = get_gcov_intermediate_filename (file_name); + gcov_intermediate_file = fopen (gcov_intermediate_filename, "w"); + if (!gcov_intermediate_file) + { + fnotice (stderr, "Cannot open intermediate output file %s\n", + gcov_intermediate_filename); + return; + } + } + for (vector::iterator it = sources.begin (); it != sources.end (); it++) { @@ -1280,9 +1319,21 @@ generate_results (const char *file_name) total_executed += src->coverage.lines_executed; if (flag_gcov_file) { - output_gcov_file (file_name, src); - fnotice (stdout, "\n"); - } + if (flag_intermediate_format) + /* Output the intermediate format without requiring source + files. This outputs a section to a *single* file. */ + output_intermediate_file (gcov_intermediate_file, src); + else + output_gcov_file (file_name, src); + fnotice (stdout, "\n"); + } + } + + if (flag_gcov_file && flag_intermediate_format) + { + /* Now we've finished writing the intermediate file. */ + fclose (gcov_intermediate_file); + XDELETEVEC (gcov_intermediate_filename); } if (!file_name) @@ -1296,11 +1347,16 @@ release_structures (void) { function_t *fn; + sources.resize (0); + names.resize (0); + while ((fn = functions)) { functions = fn->next; delete fn; } + + fn_end = &functions; } /* Generate the names of the graph and data files. If OBJECT_DIRECTORY -- cgit v1.2.1 From 457c9288ec3d3c554d4d129ecff5e422c29e2ccb Mon Sep 17 00:00:00 2001 From: marxin Date: Mon, 13 Nov 2017 09:05:20 +0000 Subject: GCOV: introduce global vector of functions 2017-11-13 Martin Liska * gcov.c (read_graph_file): Store to global vector of functions. (read_count_file): Iterate the vector. (process_file): Likewise. (generate_results): Likewise. (release_structures): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@254672 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/gcov.c | 110 +++++++++++++++++++++++++------------------------------------ 1 file changed, 44 insertions(+), 66 deletions(-) (limited to 'gcc/gcov.c') diff --git a/gcc/gcov.c b/gcc/gcov.c index 3c2c2700ab6..71239cf0cbd 100644 --- a/gcc/gcov.c +++ b/gcc/gcov.c @@ -392,10 +392,8 @@ public: unsigned src; /* Source file */ }; -/* Holds a list of function basic block graphs. */ - -static function_t *functions; -static function_t **fn_end = &functions; +/* Vector of all functions. */ +static vector functions; /* Vector of source files. */ static vector sources; @@ -535,8 +533,8 @@ static void generate_results (const char *); static void create_file_names (const char *); static char *canonicalize_name (const char *); static unsigned find_source (const char *); -static function_t *read_graph_file (void); -static int read_count_file (function_t *); +static void read_graph_file (void); +static int read_count_file (void); static void solve_flow_graph (function_t *); static void find_exception_blocks (function_t *); static void add_branch_counts (coverage_t *, const arc_t *); @@ -1125,42 +1123,40 @@ struct function_start_pair_hash : typed_noop_remove static void process_file (const char *file_name) { - function_t *fns; - create_file_names (file_name); - fns = read_graph_file (); - if (!fns) + read_graph_file (); + if (functions.empty ()) return; - read_count_file (fns); + read_count_file (); hash_map fn_map; /* Identify group functions. */ - for (function_t *f = fns; f; f = f->next) - if (!f->artificial) + for (vector::iterator it = functions.begin (); + it != functions.end (); it++) + if (!(*it)->artificial) { function_start needle; - needle.source_file_idx = f->src; - needle.start_line = f->start_line; + needle.source_file_idx = (*it)->src; + needle.start_line = (*it)->start_line; function_t **slot = fn_map.get (needle); if (slot) { - gcc_assert ((*slot)->end_line == f->end_line); + gcc_assert ((*slot)->end_line == (*it)->end_line); (*slot)->is_group = 1; - f->is_group = 1; + (*it)->is_group = 1; } else - fn_map.put (needle, f); + fn_map.put (needle, *it); } - while (fns) + for (vector::iterator it = functions.begin (); + it != functions.end (); it++) { - function_t *fn = fns; + function_t *fn = *it; - fns = fn->next; - fn->next = NULL; if (fn->counts || no_data_file) { unsigned src = fn->src; @@ -1207,14 +1203,12 @@ process_file (const char *file_name) if (fn->has_catch) find_exception_blocks (fn); } - - *fn_end = fn; - fn_end = &fn->next; } else - /* The function was not in the executable -- some other - instance must have been selected. */ - delete fn; + { + /* The function was not in the executable -- some other + instance must have been selected. */ + } } } @@ -1249,12 +1243,13 @@ output_gcov_file (const char *file_name, source_info *src) static void generate_results (const char *file_name) { - function_t *fn; FILE *gcov_intermediate_file = NULL; char *gcov_intermediate_filename = NULL; - for (fn = functions; fn; fn = fn->next) + for (vector::iterator it = functions.begin (); + it != functions.end (); it++) { + function_t *fn = *it; coverage_t coverage; if (fn->artificial) continue; @@ -1345,18 +1340,13 @@ generate_results (const char *file_name) static void release_structures (void) { - function_t *fn; + for (vector::iterator it = functions.begin (); + it != functions.end (); it++) + delete (*it); sources.resize (0); names.resize (0); - - while ((fn = functions)) - { - functions = fn->next; - delete fn; - } - - fn_end = &functions; + functions.resize (0); } /* Generate the names of the graph and data files. If OBJECT_DIRECTORY @@ -1514,29 +1504,26 @@ find_source (const char *file_name) return idx; } -/* Read the notes file. Return list of functions read -- in reverse order. */ +/* Read the notes file. Save functions to FUNCTIONS global vector. */ -static function_t * +static void read_graph_file (void) { unsigned version; unsigned current_tag = 0; - function_t *fn = NULL; - function_t *fns = NULL; - function_t **fns_end = &fns; unsigned tag; if (!gcov_open (bbg_file_name, 1)) { fnotice (stderr, "%s:cannot open notes file\n", bbg_file_name); - return fns; + return; } bbg_file_time = gcov_time (); if (!gcov_magic (gcov_read_unsigned (), GCOV_NOTE_MAGIC)) { fnotice (stderr, "%s:not a gcov notes file\n", bbg_file_name); gcov_close (); - return fns; + return; } version = gcov_read_unsigned (); @@ -1553,6 +1540,7 @@ read_graph_file (void) bbg_stamp = gcov_read_unsigned (); bbg_supports_has_unexecuted_blocks = gcov_read_unsigned (); + function_t *fn = NULL; while ((tag = gcov_read_unsigned ())) { unsigned length = gcov_read_unsigned (); @@ -1574,7 +1562,8 @@ read_graph_file (void) unsigned start_column = gcov_read_unsigned (); unsigned end_line = gcov_read_unsigned (); - fn = new function_t; + fn = new function_t (); + functions.push_back (fn); fn->name = function_name; if (flag_demangled_names) { @@ -1591,9 +1580,6 @@ read_graph_file (void) fn->end_line = end_line; fn->artificial = artificial; - fn->next = NULL; - *fns_end = fn; - fns_end = &fn->next; current_tag = tag; } else if (fn && tag == GCOV_TAG_BLOCKS) @@ -1719,17 +1705,15 @@ read_graph_file (void) } gcov_close (); - if (!fns) + if (functions.empty ()) fnotice (stderr, "%s:no functions found\n", bbg_file_name); - - return fns; } /* Reads profiles from the count file and attach to each function. Return nonzero if fatal error. */ static int -read_count_file (function_t *fns) +read_count_file (void) { unsigned ix; unsigned version; @@ -1786,26 +1770,20 @@ read_count_file (function_t *fns) else if (tag == GCOV_TAG_FUNCTION && length == GCOV_TAG_FUNCTION_LENGTH) { unsigned ident; - struct function_info *fn_n; /* Try to find the function in the list. To speed up the search, first start from the last function found. */ ident = gcov_read_unsigned (); - fn_n = fns; - for (fn = fn ? fn->next : NULL; ; fn = fn->next) + + fn = NULL; + for (vector::reverse_iterator it = functions.rbegin (); + it != functions.rend (); it++) { - if (fn) - ; - else if ((fn = fn_n)) - fn_n = NULL; - else + if ((*it)->ident == ident) { - fnotice (stderr, "%s:unknown function '%u'\n", - da_file_name, ident); + fn = *it; break; } - if (fn->ident == ident) - break; } if (!fn) -- cgit v1.2.1 From d93799f5b097b67a3a94dcb0d6901a5c5fe5af76 Mon Sep 17 00:00:00 2001 From: marxin Date: Mon, 13 Nov 2017 09:05:38 +0000 Subject: GCOV: simplify usage of function_info::artificial. 2017-11-13 Martin Liska * gcov.c (function_info::is_artificial): New function. (process_file): Erase all artificial early. (generate_results): Skip as all artificial are already removed. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@254673 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/gcov.c | 66 +++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 26 deletions(-) (limited to 'gcc/gcov.c') diff --git a/gcc/gcov.c b/gcc/gcov.c index 71239cf0cbd..01901ed7493 100644 --- a/gcc/gcov.c +++ b/gcc/gcov.c @@ -232,6 +232,14 @@ typedef struct function_info The line must be defined in body of the function, can't be inlined. */ bool group_line_p (unsigned n, unsigned src_idx); + /* Function filter based on function_info::artificial variable. */ + + static inline bool + is_artificial (function_info *fn) + { + return fn->artificial; + } + /* Name of function. */ char *name; char *demangled_name; @@ -1152,33 +1160,40 @@ process_file (const char *file_name) fn_map.put (needle, *it); } + /* Remove all artificial function. */ + functions.erase (remove_if (functions.begin (), functions.end (), + function_info::is_artificial), functions.end ()); + for (vector::iterator it = functions.begin (); it != functions.end (); it++) { function_t *fn = *it; + unsigned src = fn->src; if (fn->counts || no_data_file) { - unsigned src = fn->src; - unsigned block_no; + source_info *s = &sources[src]; + s->functions.push_back (fn); - /* Process only non-artificial functions. */ - if (!fn->artificial) + /* Mark last line in files touched by function. */ + for (unsigned block_no = 0; block_no != fn->blocks.size (); + block_no++) { - source_info *s = &sources[src]; - s->functions.push_back (fn); - - /* Mark last line in files touched by function. */ - for (block_no = 0; block_no != fn->blocks.size (); block_no++) + block_t *block = &fn->blocks[block_no]; + for (unsigned i = 0; i < block->locations.size (); i++) { - block_t *block = &fn->blocks[block_no]; - for (unsigned i = 0; i < block->locations.size (); i++) + /* Sort lines of locations. */ + sort (block->locations[i].lines.begin (), + block->locations[i].lines.end ()); + + if (!block->locations[i].lines.empty ()) { - /* Sort lines of locations. */ - sort (block->locations[i].lines.begin (), - block->locations[i].lines.end ()); + s = &sources[block->locations[i].source_file_idx]; + unsigned last_line + = block->locations[i].lines.back (); - if (!block->locations[i].lines.empty ()) + /* Record new lines for the function. */ + if (last_line >= s->lines.size ()) { s = &sources[block->locations[i].source_file_idx]; unsigned last_line @@ -1192,17 +1207,18 @@ process_file (const char *file_name) } } } - - /* Allocate lines for group function, following start_line - and end_line information of the function. */ - if (fn->is_group) - fn->lines.resize (fn->end_line - fn->start_line + 1); } - - solve_flow_graph (fn); - if (fn->has_catch) - find_exception_blocks (fn); } + + /* Allocate lines for group function, following start_line + and end_line information of the function. */ + if (fn->is_group) + fn->lines.resize (fn->end_line - fn->start_line + 1); + + + solve_flow_graph (fn); + if (fn->has_catch) + find_exception_blocks (fn); } else { @@ -1251,8 +1267,6 @@ generate_results (const char *file_name) { function_t *fn = *it; coverage_t coverage; - if (fn->artificial) - continue; memset (&coverage, 0, sizeof (coverage)); coverage.name = flag_demangled_names ? fn->demangled_name : fn->name; -- cgit v1.2.1 From 67da56f670339c317b7d454995f896e43b9f8964 Mon Sep 17 00:00:00 2001 From: marxin Date: Mon, 13 Nov 2017 09:05:55 +0000 Subject: GCOV: introduce vector for function_info::counts. 2017-11-13 Martin Liska * gcov.c (function_info::function_info): Remove num_counts and add vector. (function_info::~function_info): Use the vector. (process_file): Likewise. (read_graph_file): Likewise. (read_count_file): Likewise. (solve_flow_graph): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@254674 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/gcov.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) (limited to 'gcc/gcov.c') diff --git a/gcc/gcov.c b/gcc/gcov.c index 01901ed7493..fa1ada6d37f 100644 --- a/gcc/gcov.c +++ b/gcc/gcov.c @@ -265,8 +265,7 @@ typedef struct function_info unsigned blocks_executed; /* Raw arc coverage counts. */ - gcov_type *counts; - unsigned num_counts; + vector counts; /* First line number. */ unsigned start_line; @@ -562,8 +561,8 @@ extern int main (int, char **); function_info::function_info (): name (NULL), demangled_name (NULL), ident (0), lineno_checksum (0), cfg_checksum (0), has_catch (0), artificial (0), is_group (0), - blocks (), blocks_executed (0), counts (NULL), num_counts (0), - start_line (0), start_column (0), end_line (0), src (0), lines (), next (NULL) + blocks (), blocks_executed (0), counts (), + start_line (0), start_column (), end_line (0), src (0), lines (), next (NULL) { } @@ -579,7 +578,6 @@ function_info::~function_info () free (arc); } } - free (counts); if (flag_demangled_names && demangled_name != name) free (demangled_name); free (name); @@ -1170,7 +1168,7 @@ process_file (const char *file_name) function_t *fn = *it; unsigned src = fn->src; - if (fn->counts || no_data_file) + if (!fn->counts.empty () || no_data_file) { source_info *s = &sources[src]; s->functions.push_back (fn); @@ -1662,7 +1660,7 @@ read_graph_file (void) } if (!arc->on_tree) - fn->num_counts++; + fn->counts.push_back (0); } if (mark_catches) @@ -1813,13 +1811,10 @@ read_count_file (void) } else if (tag == GCOV_TAG_FOR_COUNTER (GCOV_COUNTER_ARCS) && fn) { - if (length != GCOV_TAG_COUNTER_LENGTH (fn->num_counts)) + if (length != GCOV_TAG_COUNTER_LENGTH (fn->counts.size ())) goto mismatch; - if (!fn->counts) - fn->counts = XCNEWVEC (gcov_type, fn->num_counts); - - for (ix = 0; ix != fn->num_counts; ix++) + for (ix = 0; ix != fn->counts.size (); ix++) fn->counts[ix] += gcov_read_counter (); } gcov_sync (base, length); @@ -1846,7 +1841,7 @@ solve_flow_graph (function_t *fn) { unsigned ix; arc_t *arc; - gcov_type *count_ptr = fn->counts; + gcov_type *count_ptr = &fn->counts.front (); block_t *blk; block_t *valid_blocks = NULL; /* valid, but unpropagated blocks. */ block_t *invalid_blocks = NULL; /* invalid, but inferable blocks. */ -- cgit v1.2.1 From 98888fd6d903354cd05da7240cf2cbdc4152ae6b Mon Sep 17 00:00:00 2001 From: marxin Date: Mon, 13 Nov 2017 09:06:13 +0000 Subject: GCOV: remove typedef for function_t 2017-11-13 Martin Liska * gcov.c (struct function_info): Remove typedef for function_t. (struct source_info): Likewise. (source_info::get_functions_at_location): Likewise. (solve_flow_graph): Likewise. (find_exception_blocks): Likewise. (add_line_counts): Likewise. (output_intermediate_file): Likewise. (process_file): Likewise. (generate_results): Likewise. (release_structures): Likewise. (read_graph_file): Likewise. (read_count_file): Likewise. (accumulate_line_counts): Likewise. (output_lines): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@254675 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/gcov.c | 70 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 35 insertions(+), 35 deletions(-) (limited to 'gcc/gcov.c') diff --git a/gcc/gcov.c b/gcc/gcov.c index fa1ada6d37f..3dac5c3122e 100644 --- a/gcc/gcov.c +++ b/gcc/gcov.c @@ -223,7 +223,7 @@ line_info::has_block (block_t *needle) /* Describes a single function. Contains an array of basic blocks. */ -typedef struct function_info +struct function_info { function_info (); ~function_info (); @@ -284,7 +284,7 @@ typedef struct function_info /* Next function. */ struct function_info *next; -} function_t; +}; /* Function info comparer that will sort functions according to starting line. */ @@ -325,7 +325,7 @@ struct source_info /* Default constructor. */ source_info (); - vector get_functions_at_location (unsigned line_num) const; + vector get_functions_at_location (unsigned line_num) const; /* Index of the source_info in sources vector. */ unsigned index; @@ -341,7 +341,7 @@ struct source_info /* Functions in this source file. These are in ascending line number order. */ - vector functions; + vector functions; }; source_info::source_info (): index (0), name (NULL), file_time (), @@ -349,12 +349,12 @@ source_info::source_info (): index (0), name (NULL), file_time (), { } -vector +vector source_info::get_functions_at_location (unsigned line_num) const { - vector r; + vector r; - for (vector::const_iterator it = functions.begin (); + for (vector::const_iterator it = functions.begin (); it != functions.end (); it++) { if ((*it)->start_line == line_num && (*it)->src == index) @@ -400,7 +400,7 @@ public: }; /* Vector of all functions. */ -static vector functions; +static vector functions; /* Vector of source files. */ static vector sources; @@ -542,10 +542,10 @@ static char *canonicalize_name (const char *); static unsigned find_source (const char *); static void read_graph_file (void); static int read_count_file (void); -static void solve_flow_graph (function_t *); -static void find_exception_blocks (function_t *); +static void solve_flow_graph (function_info *); +static void find_exception_blocks (function_info *); static void add_branch_counts (coverage_t *, const arc_t *); -static void add_line_counts (coverage_t *, function_t *); +static void add_line_counts (coverage_t *, function_info *); static void executed_summary (unsigned, unsigned); static void function_summary (const coverage_t *, const char *); static const char *format_gcov (gcov_type, gcov_type, int); @@ -1039,7 +1039,7 @@ output_intermediate_file (FILE *gcov_file, source_info *src) std::sort (src->functions.begin (), src->functions.end (), function_line_start_cmp ()); - for (vector::iterator it = src->functions.begin (); + for (vector::iterator it = src->functions.begin (); it != src->functions.end (); it++) { /* function:,, */ @@ -1050,10 +1050,10 @@ output_intermediate_file (FILE *gcov_file, source_info *src) for (unsigned line_num = 1; line_num <= src->lines.size (); line_num++) { - vector fns = src->get_functions_at_location (line_num); + vector fns = src->get_functions_at_location (line_num); /* Print first group functions that begin on the line. */ - for (vector::iterator it2 = fns.begin (); + for (vector::iterator it2 = fns.begin (); it2 != fns.end (); it2++) { vector &lines = (*it2)->lines; @@ -1136,10 +1136,10 @@ process_file (const char *file_name) read_count_file (); - hash_map fn_map; + hash_map fn_map; /* Identify group functions. */ - for (vector::iterator it = functions.begin (); + for (vector::iterator it = functions.begin (); it != functions.end (); it++) if (!(*it)->artificial) { @@ -1147,7 +1147,7 @@ process_file (const char *file_name) needle.source_file_idx = (*it)->src; needle.start_line = (*it)->start_line; - function_t **slot = fn_map.get (needle); + function_info **slot = fn_map.get (needle); if (slot) { gcc_assert ((*slot)->end_line == (*it)->end_line); @@ -1162,10 +1162,10 @@ process_file (const char *file_name) functions.erase (remove_if (functions.begin (), functions.end (), function_info::is_artificial), functions.end ()); - for (vector::iterator it = functions.begin (); + for (vector::iterator it = functions.begin (); it != functions.end (); it++) { - function_t *fn = *it; + function_info *fn = *it; unsigned src = fn->src; if (!fn->counts.empty () || no_data_file) @@ -1260,10 +1260,10 @@ generate_results (const char *file_name) FILE *gcov_intermediate_file = NULL; char *gcov_intermediate_filename = NULL; - for (vector::iterator it = functions.begin (); + for (vector::iterator it = functions.begin (); it != functions.end (); it++) { - function_t *fn = *it; + function_info *fn = *it; coverage_t coverage; memset (&coverage, 0, sizeof (coverage)); @@ -1352,7 +1352,7 @@ generate_results (const char *file_name) static void release_structures (void) { - for (vector::iterator it = functions.begin (); + for (vector::iterator it = functions.begin (); it != functions.end (); it++) delete (*it); @@ -1552,7 +1552,7 @@ read_graph_file (void) bbg_stamp = gcov_read_unsigned (); bbg_supports_has_unexecuted_blocks = gcov_read_unsigned (); - function_t *fn = NULL; + function_info *fn = NULL; while ((tag = gcov_read_unsigned ())) { unsigned length = gcov_read_unsigned (); @@ -1574,7 +1574,7 @@ read_graph_file (void) unsigned start_column = gcov_read_unsigned (); unsigned end_line = gcov_read_unsigned (); - fn = new function_t (); + fn = new function_info (); functions.push_back (fn); fn->name = function_name; if (flag_demangled_names) @@ -1730,7 +1730,7 @@ read_count_file (void) unsigned ix; unsigned version; unsigned tag; - function_t *fn = NULL; + function_info *fn = NULL; int error = 0; if (!gcov_open (da_file_name, 1)) @@ -1788,8 +1788,8 @@ read_count_file (void) ident = gcov_read_unsigned (); fn = NULL; - for (vector::reverse_iterator it = functions.rbegin (); - it != functions.rend (); it++) + for (vector::reverse_iterator it + = functions.rbegin (); it != functions.rend (); it++) { if ((*it)->ident == ident) { @@ -1837,7 +1837,7 @@ read_count_file (void) to the blocks and the uninstrumented arcs. */ static void -solve_flow_graph (function_t *fn) +solve_flow_graph (function_info *fn) { unsigned ix; arc_t *arc; @@ -2100,7 +2100,7 @@ solve_flow_graph (function_t *fn) /* Mark all the blocks only reachable via an incoming catch. */ static void -find_exception_blocks (function_t *fn) +find_exception_blocks (function_info *fn) { unsigned ix; block_t **queue = XALLOCAVEC (block_t *, fn->blocks.size ()); @@ -2479,7 +2479,7 @@ mangle_name (char const *base, char *ptr) the appropriate basic block. */ static void -add_line_counts (coverage_t *coverage, function_t *fn) +add_line_counts (coverage_t *coverage, function_info *fn) { bool has_any_line = false; /* Scan each basic block. */ @@ -2611,7 +2611,7 @@ static void accumulate_line_counts (source_info *src) { /* First work on group functions. */ - for (vector::iterator it = src->functions.begin (); + for (vector::iterator it = src->functions.begin (); it != src->functions.end (); it++) { function_info *fn = *it; @@ -2635,7 +2635,7 @@ accumulate_line_counts (source_info *src) /* If not using intermediate mode, sum lines of group functions and add them to lines that live in a source file. */ if (!flag_intermediate_format) - for (vector::iterator it = src->functions.begin (); + for (vector::iterator it = src->functions.begin (); it != src->functions.end (); it++) { function_info *fn = *it; @@ -2939,7 +2939,7 @@ output_lines (FILE *gcov_file, const source_info *src) source_lines.push_back (xstrdup (retval)); unsigned line_start_group = 0; - vector fns; + vector fns; for (unsigned line_num = 1; line_num <= source_lines.size (); line_num++) { @@ -2959,7 +2959,7 @@ output_lines (FILE *gcov_file, const source_info *src) line_start_group = fns[0]->end_line; else if (fns.size () == 1) { - function_t *fn = fns[0]; + function_info *fn = fns[0]; output_function_details (gcov_file, fn); } } @@ -2979,7 +2979,7 @@ output_lines (FILE *gcov_file, const source_info *src) if (line_start_group == line_num) { - for (vector::iterator it = fns.begin (); + for (vector::iterator it = fns.begin (); it != fns.end (); it++) { function_info *fn = *it; -- cgit v1.2.1 From 6f93d61e9f5f39dd0eba956d94c6426a787861ad Mon Sep 17 00:00:00 2001 From: marxin Date: Mon, 13 Nov 2017 09:06:26 +0000 Subject: GCOV: remove typedef for arc_t 2017-11-13 Martin Liska * gcov.c (struct arc_info): Remove typedef for arc_t. (struct line_info): Likewise. (add_branch_counts): Likewise. (output_branch_count): Likewise. (function_info::~function_info): Likewise. (circuit): Likewise. (output_intermediate_line): Likewise. (read_graph_file): Likewise. (solve_flow_graph): Likewise. (find_exception_blocks): Likewise. (add_line_counts): Likewise. (accumulate_line_info): Likewise. (output_line_details): Likewise. (output_function_details): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@254676 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/gcov.c | 58 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) (limited to 'gcc/gcov.c') diff --git a/gcc/gcov.c b/gcc/gcov.c index 3dac5c3122e..49652b7eafa 100644 --- a/gcc/gcov.c +++ b/gcc/gcov.c @@ -79,7 +79,7 @@ struct source_info; /* Describes an arc between two basic blocks. */ -typedef struct arc_info +struct arc_info { /* source and destination blocks. */ struct block_info *src; @@ -113,7 +113,7 @@ typedef struct arc_info /* Links to next arc on src and dst lists. */ struct arc_info *succ_next; struct arc_info *pred_next; -} arc_t; +}; /* Describes which locations (lines and files) are associated with a basic block. */ @@ -137,8 +137,8 @@ typedef struct block_info block_info (); /* Chain of exit and entry arcs. */ - arc_t *succ; - arc_t *pred; + arc_info *succ; + arc_info *pred; /* Number of unprocessed exit and entry arcs. */ gcov_type num_succ; @@ -166,7 +166,7 @@ typedef struct block_info { /* Single line graph cycle workspace. Used for all-blocks mode. */ - arc_t *arc; + arc_info *arc; unsigned ident; } cycle; /* Used in all-blocks mode, after blocks are linked onto lines. */ @@ -200,7 +200,7 @@ struct line_info gcov_type count; /* Branches from blocks that end on this line. */ - vector branches; + vector branches; /* blocks which start on this line. Used in all-blocks mode. */ vector blocks; @@ -544,14 +544,14 @@ static void read_graph_file (void); static int read_count_file (void); static void solve_flow_graph (function_info *); static void find_exception_blocks (function_info *); -static void add_branch_counts (coverage_t *, const arc_t *); +static void add_branch_counts (coverage_t *, const arc_info *); static void add_line_counts (coverage_t *, function_info *); static void executed_summary (unsigned, unsigned); static void function_summary (const coverage_t *, const char *); static const char *format_gcov (gcov_type, gcov_type, int); static void accumulate_line_counts (source_info *); static void output_gcov_file (const char *, source_info *); -static int output_branch_count (FILE *, int, const arc_t *); +static int output_branch_count (FILE *, int, const arc_info *); static void output_lines (FILE *, const source_info *); static char *make_gcov_file_name (const char *, const char *); static char *mangle_name (const char *, char *); @@ -570,7 +570,7 @@ function_info::~function_info () { for (int i = blocks.size () - 1; i >= 0; i--) { - arc_t *arc, *arc_n; + arc_info *arc, *arc_n; for (arc = blocks[i].succ; arc; arc = arc_n) { @@ -600,7 +600,7 @@ bool function_info::group_line_p (unsigned n, unsigned src_idx) simple paths)--the node is unblocked only when it participates in a cycle. */ -typedef vector arc_vector_t; +typedef vector arc_vector_t; typedef vector block_vector_t; /* Enum with types of loop in CFG. */ @@ -682,7 +682,7 @@ circuit (block_t *v, arc_vector_t &path, block_t *start, blocked.push_back (v); block_lists.push_back (block_vector_t ()); - for (arc_t *arc = v->succ; arc; arc = arc->succ_next) + for (arc_info *arc = v->succ; arc; arc = arc->succ_next) { block_t *w = arc->dst; if (w < start || !linfo.has_block (w)) @@ -701,7 +701,7 @@ circuit (block_t *v, arc_vector_t &path, block_t *start, if (result != NO_LOOP) unblock (v, blocked, block_lists); else - for (arc_t *arc = v->succ; arc; arc = arc->succ_next) + for (arc_info *arc = v->succ; arc; arc = arc->succ_next) { block_t *w = arc->dst; if (w < start || !linfo.has_block (w)) @@ -973,7 +973,7 @@ output_intermediate_line (FILE *f, line_info *line, unsigned line_num) format_gcov (line->count, 0, -1), line->has_unexecuted_block); - vector::const_iterator it; + vector::const_iterator it; if (flag_branches) for (it = line->branches.begin (); it != line->branches.end (); it++) @@ -1621,7 +1621,7 @@ read_graph_file (void) if (dest >= fn->blocks.size ()) goto corrupt; - arc = XCNEW (arc_t); + arc = XCNEW (arc_info); arc->dst = &fn->blocks[dest]; arc->src = src_blk; @@ -1840,7 +1840,7 @@ static void solve_flow_graph (function_info *fn) { unsigned ix; - arc_t *arc; + arc_info *arc; gcov_type *count_ptr = &fn->counts.front (); block_t *blk; block_t *valid_blocks = NULL; /* valid, but unpropagated blocks. */ @@ -1849,7 +1849,7 @@ solve_flow_graph (function_info *fn) /* The arcs were built in reverse order. Fix that now. */ for (ix = fn->blocks.size (); ix--;) { - arc_t *arc_p, *arc_n; + arc_info *arc_p, *arc_n; for (arc_p = NULL, arc = fn->blocks[ix].succ; arc; arc_p = arc, arc = arc_n) @@ -1942,12 +1942,12 @@ solve_flow_graph (function_info *fn) smart sort. */ if (out_of_order) { - arc_t *start = blk->succ; + arc_info *start = blk->succ; unsigned changes = 1; while (changes) { - arc_t *arc, *arc_p, *arc_n; + arc_info *arc, *arc_p, *arc_n; changes = 0; for (arc_p = NULL, arc = start; (arc_n = arc->succ_next);) @@ -1985,7 +1985,7 @@ solve_flow_graph (function_info *fn) while ((blk = invalid_blocks)) { gcov_type total = 0; - const arc_t *arc; + const arc_info *arc; invalid_blocks = blk->chain; blk->invalid_chain = 0; @@ -2007,7 +2007,7 @@ solve_flow_graph (function_info *fn) while ((blk = valid_blocks)) { gcov_type total; - arc_t *arc, *inv_arc; + arc_info *arc, *inv_arc; valid_blocks = blk->chain; blk->valid_chain = 0; @@ -2115,7 +2115,7 @@ find_exception_blocks (function_info *fn) for (ix = 1; ix;) { block_t *block = queue[--ix]; - const arc_t *arc; + const arc_info *arc; for (arc = block->succ; arc; arc = arc->succ_next) if (!arc->fake && !arc->is_throw && arc->dst->exceptional) @@ -2130,7 +2130,7 @@ find_exception_blocks (function_info *fn) /* Increment totals in COVERAGE according to arc ARC. */ static void -add_branch_counts (coverage_t *coverage, const arc_t *arc) +add_branch_counts (coverage_t *coverage, const arc_info *arc) { if (arc->is_call_non_return) { @@ -2547,7 +2547,7 @@ add_line_counts (coverage_t *coverage, function_info *fn) if (flag_branches) { - arc_t *arc; + arc_info *arc; for (arc = block->succ; arc; arc = arc->succ_next) line->branches.push_back (arc); @@ -2585,10 +2585,10 @@ static void accumulate_line_info (line_info *line, source_info *src, for (vector::iterator it = line->blocks.begin (); it != line->blocks.end (); it++) { - for (arc_t *arc = (*it)->pred; arc; arc = arc->pred_next) + for (arc_info *arc = (*it)->pred; arc; arc = arc->pred_next) if (!line->has_block (arc->src)) count += arc->count; - for (arc_t *arc = (*it)->succ; arc; arc = arc->succ_next) + for (arc_info *arc = (*it)->succ; arc; arc = arc->succ_next) arc->cs_count = arc->count; } @@ -2673,7 +2673,7 @@ accumulate_line_counts (source_info *src) anything is output. */ static int -output_branch_count (FILE *gcov_file, int ix, const arc_t *arc) +output_branch_count (FILE *gcov_file, int ix, const arc_info *arc) { if (arc->is_call_non_return) { @@ -2842,7 +2842,7 @@ output_line_details (FILE *f, const line_info *line, unsigned line_num) { if (flag_all_blocks) { - arc_t *arc; + arc_info *arc; int ix, jx; ix = jx = 0; @@ -2870,7 +2870,7 @@ output_line_details (FILE *f, const line_info *line, unsigned line_num) int ix; ix = 0; - for (vector::const_iterator it = line->branches.begin (); + for (vector::const_iterator it = line->branches.begin (); it != line->branches.end (); it++) ix += output_branch_count (f, ix, (*it)); } @@ -2884,7 +2884,7 @@ output_function_details (FILE *f, const function_info *fn) if (!flag_branches) return; - arc_t *arc = fn->blocks[EXIT_BLOCK].pred; + arc_info *arc = fn->blocks[EXIT_BLOCK].pred; gcov_type return_count = fn->blocks[EXIT_BLOCK].count; gcov_type called_count = fn->blocks[ENTRY_BLOCK].count; -- cgit v1.2.1 From 07f3f54d1e4d8621dbc48b7d0e91f5ebf1996ae1 Mon Sep 17 00:00:00 2001 From: marxin Date: Mon, 13 Nov 2017 09:06:43 +0000 Subject: GCOV: remove typedef for block_t 2017-11-13 Martin Liska * gcov.c (struct block_info): Remove typedef for block_t. (struct line_info): Likewise. (line_info::has_block): Likewise. (EXIT_BLOCK): Likewise. (unblock): Likewise. (circuit): Likewise. (get_cycles_count): Likewise. (process_file): Likewise. (read_graph_file): Likewise. (solve_flow_graph): Likewise. (find_exception_blocks): Likewise. (add_line_counts): Likewise. (accumulate_line_info): Likewise. (output_line_details): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@254677 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/gcov.c | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) (limited to 'gcc/gcov.c') diff --git a/gcc/gcov.c b/gcc/gcov.c index 49652b7eafa..c6a0a066593 100644 --- a/gcc/gcov.c +++ b/gcc/gcov.c @@ -131,7 +131,7 @@ struct block_location_info /* Describes a basic block. Contains lists of arcs to successor and predecessor blocks. */ -typedef struct block_info +struct block_info { /* Constructor. */ block_info (); @@ -175,7 +175,7 @@ typedef struct block_info line. */ struct block_info *chain; -} block_t; +}; block_info::block_info (): succ (NULL), pred (NULL), num_succ (0), num_pred (0), id (0), count (0), count_valid (0), valid_chain (0), invalid_chain (0), @@ -194,7 +194,7 @@ struct line_info line_info (); /* Return true when NEEDLE is one of basic blocks the line belongs to. */ - bool has_block (block_t *needle); + bool has_block (block_info *needle); /* Execution count. */ gcov_type count; @@ -203,7 +203,7 @@ struct line_info vector branches; /* blocks which start on this line. Used in all-blocks mode. */ - vector blocks; + vector blocks; unsigned exists : 1; unsigned unexceptional : 1; @@ -216,7 +216,7 @@ line_info::line_info (): count (0), branches (), blocks (), exists (false), } bool -line_info::has_block (block_t *needle) +line_info::has_block (block_info *needle) { return std::find (blocks.begin (), blocks.end (), needle) != blocks.end (); } @@ -261,7 +261,7 @@ struct function_info at blocks[0] and the exit block is at blocks[1]. */ #define ENTRY_BLOCK (0) #define EXIT_BLOCK (1) - vector blocks; + vector blocks; unsigned blocks_executed; /* Raw arc coverage counts. */ @@ -601,7 +601,7 @@ bool function_info::group_line_p (unsigned n, unsigned src_idx) */ typedef vector arc_vector_t; -typedef vector block_vector_t; +typedef vector block_vector_t; /* Enum with types of loop in CFG. */ @@ -646,7 +646,7 @@ handle_cycle (const arc_vector_t &edges, int64_t &count) blocked by U in BLOCK_LISTS. */ static void -unblock (const block_t *u, block_vector_t &blocked, +unblock (const block_info *u, block_vector_t &blocked, vector &block_lists) { block_vector_t::iterator it = find (blocked.begin (), blocked.end (), u); @@ -671,7 +671,7 @@ unblock (const block_t *u, block_vector_t &blocked, Returns what type of loop it contains. */ static loop_type -circuit (block_t *v, arc_vector_t &path, block_t *start, +circuit (block_info *v, arc_vector_t &path, block_info *start, block_vector_t &blocked, vector &block_lists, line_info &linfo, int64_t &count) { @@ -684,7 +684,7 @@ circuit (block_t *v, arc_vector_t &path, block_t *start, for (arc_info *arc = v->succ; arc; arc = arc->succ_next) { - block_t *w = arc->dst; + block_info *w = arc->dst; if (w < start || !linfo.has_block (w)) continue; @@ -703,7 +703,7 @@ circuit (block_t *v, arc_vector_t &path, block_t *start, else for (arc_info *arc = v->succ; arc; arc = arc->succ_next) { - block_t *w = arc->dst; + block_info *w = arc->dst; if (w < start || !linfo.has_block (w)) continue; @@ -732,7 +732,7 @@ get_cycles_count (line_info &linfo, bool handle_negative_cycles = true) loop_type result = NO_LOOP; gcov_type count = 0; - for (vector::iterator it = linfo.blocks.begin (); + for (vector::iterator it = linfo.blocks.begin (); it != linfo.blocks.end (); it++) { arc_vector_t path; @@ -1177,7 +1177,7 @@ process_file (const char *file_name) for (unsigned block_no = 0; block_no != fn->blocks.size (); block_no++) { - block_t *block = &fn->blocks[block_no]; + block_info *block = &fn->blocks[block_no]; for (unsigned i = 0; i < block->locations.size (); i++) { /* Sort lines of locations. */ @@ -1607,7 +1607,7 @@ read_graph_file (void) unsigned src = gcov_read_unsigned (); fn->blocks[src].id = src; unsigned num_dests = GCOV_TAG_ARCS_NUM (length); - block_t *src_blk = &fn->blocks[src]; + block_info *src_blk = &fn->blocks[src]; unsigned mark_catches = 0; struct arc_info *arc; @@ -1680,7 +1680,7 @@ read_graph_file (void) else if (fn && tag == GCOV_TAG_LINES) { unsigned blockno = gcov_read_unsigned (); - block_t *block = &fn->blocks[blockno]; + block_info *block = &fn->blocks[blockno]; if (blockno >= fn->blocks.size ()) goto corrupt; @@ -1842,9 +1842,9 @@ solve_flow_graph (function_info *fn) unsigned ix; arc_info *arc; gcov_type *count_ptr = &fn->counts.front (); - block_t *blk; - block_t *valid_blocks = NULL; /* valid, but unpropagated blocks. */ - block_t *invalid_blocks = NULL; /* invalid, but inferable blocks. */ + block_info *blk; + block_info *valid_blocks = NULL; /* valid, but unpropagated blocks. */ + block_info *invalid_blocks = NULL; /* invalid, but inferable blocks. */ /* The arcs were built in reverse order. Fix that now. */ for (ix = fn->blocks.size (); ix--;) @@ -1895,7 +1895,7 @@ solve_flow_graph (function_info *fn) for (unsigned i = 0; i < fn->blocks.size (); i++) { blk = &fn->blocks[i]; - block_t const *prev_dst = NULL; + block_info const *prev_dst = NULL; int out_of_order = 0; int non_fake_succ = 0; @@ -2013,7 +2013,7 @@ solve_flow_graph (function_info *fn) blk->valid_chain = 0; if (blk->num_succ == 1) { - block_t *dst; + block_info *dst; total = blk->count; inv_arc = NULL; @@ -2049,7 +2049,7 @@ solve_flow_graph (function_info *fn) } if (blk->num_pred == 1) { - block_t *src; + block_info *src; total = blk->count; inv_arc = NULL; @@ -2103,7 +2103,7 @@ static void find_exception_blocks (function_info *fn) { unsigned ix; - block_t **queue = XALLOCAVEC (block_t *, fn->blocks.size ()); + block_info **queue = XALLOCAVEC (block_info *, fn->blocks.size ()); /* First mark all blocks as exceptional. */ for (ix = fn->blocks.size (); ix--;) @@ -2114,7 +2114,7 @@ find_exception_blocks (function_info *fn) queue[0]->exceptional = 0; for (ix = 1; ix;) { - block_t *block = queue[--ix]; + block_info *block = queue[--ix]; const arc_info *arc; for (arc = block->succ; arc; arc = arc->succ_next) @@ -2486,7 +2486,7 @@ add_line_counts (coverage_t *coverage, function_info *fn) for (unsigned ix = 0; ix != fn->blocks.size (); ix++) { line_info *line = NULL; - block_t *block = &fn->blocks[ix]; + block_info *block = &fn->blocks[ix]; if (block->count && ix && ix + 1 != fn->blocks.size ()) fn->blocks_executed++; for (unsigned i = 0; i < block->locations.size (); i++) @@ -2582,7 +2582,7 @@ static void accumulate_line_info (line_info *line, source_info *src, gcov_type count = 0; /* Cycle detection. */ - for (vector::iterator it = line->blocks.begin (); + for (vector::iterator it = line->blocks.begin (); it != line->blocks.end (); it++) { for (arc_info *arc = (*it)->pred; arc; arc = arc->pred_next) @@ -2846,7 +2846,7 @@ output_line_details (FILE *f, const line_info *line, unsigned line_num) int ix, jx; ix = jx = 0; - for (vector::const_iterator it = line->blocks.begin (); + for (vector::const_iterator it = line->blocks.begin (); it != line->blocks.end (); it++) { if (!(*it)->is_call_return) -- cgit v1.2.1 From 7ea14e0563d164603686df7e05bbbd20810b7f80 Mon Sep 17 00:00:00 2001 From: marxin Date: Mon, 13 Nov 2017 09:06:54 +0000 Subject: GCOV: remove typedef of coverage_t. 2017-11-13 Martin Liska * gcov.c (struct coverage_info): Remove typedef of coverage_t. (struct source_info): Likewise. (add_branch_counts): Likewise. (add_line_counts): Likewise. (function_summary): Likewise. (output_intermediate_line): Likewise. (generate_results): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@254678 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/gcov.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'gcc/gcov.c') diff --git a/gcc/gcov.c b/gcc/gcov.c index c6a0a066593..24e6da09fcf 100644 --- a/gcc/gcov.c +++ b/gcc/gcov.c @@ -302,7 +302,7 @@ struct function_line_start_cmp /* Describes coverage of a file or function. */ -typedef struct coverage_info +struct coverage_info { int lines; int lines_executed; @@ -315,7 +315,7 @@ typedef struct coverage_info int calls_executed; char *name; -} coverage_t; +}; /* Describes a file mentioned in the block graph. Contains an array of line info. */ @@ -337,7 +337,7 @@ struct source_info /* Vector of line information. */ vector lines; - coverage_t coverage; + coverage_info coverage; /* Functions in this source file. These are in ascending line number order. */ @@ -544,10 +544,10 @@ static void read_graph_file (void); static int read_count_file (void); static void solve_flow_graph (function_info *); static void find_exception_blocks (function_info *); -static void add_branch_counts (coverage_t *, const arc_info *); -static void add_line_counts (coverage_t *, function_info *); +static void add_branch_counts (coverage_info *, const arc_info *); +static void add_line_counts (coverage_info *, function_info *); static void executed_summary (unsigned, unsigned); -static void function_summary (const coverage_t *, const char *); +static void function_summary (const coverage_info *, const char *); static const char *format_gcov (gcov_type, gcov_type, int); static void accumulate_line_counts (source_info *); static void output_gcov_file (const char *, source_info *); @@ -981,8 +981,8 @@ output_intermediate_line (FILE *f, line_info *line, unsigned line_num) if (!(*it)->is_unconditional && !(*it)->is_call_non_return) { const char *branch_type; - /* branch:, - branch_coverage_type + /* branch:, + branch_coverage_infoype : notexec (Branch not executed) : taken (Branch executed and taken) : nottaken (Branch executed, but not taken) @@ -1264,7 +1264,7 @@ generate_results (const char *file_name) it != functions.end (); it++) { function_info *fn = *it; - coverage_t coverage; + coverage_info coverage; memset (&coverage, 0, sizeof (coverage)); coverage.name = flag_demangled_names ? fn->demangled_name : fn->name; @@ -2130,7 +2130,7 @@ find_exception_blocks (function_info *fn) /* Increment totals in COVERAGE according to arc ARC. */ static void -add_branch_counts (coverage_t *coverage, const arc_info *arc) +add_branch_counts (coverage_info *coverage, const arc_info *arc) { if (arc->is_call_non_return) { @@ -2242,7 +2242,7 @@ executed_summary (unsigned lines, unsigned executed) /* Output summary info for a function or file. */ static void -function_summary (const coverage_t *coverage, const char *title) +function_summary (const coverage_info *coverage, const char *title) { fnotice (stdout, "%s '%s'\n", title, coverage->name); executed_summary (coverage->lines, coverage->lines_executed); @@ -2479,7 +2479,7 @@ mangle_name (char const *base, char *ptr) the appropriate basic block. */ static void -add_line_counts (coverage_t *coverage, function_info *fn) +add_line_counts (coverage_info *coverage, function_info *fn) { bool has_any_line = false; /* Scan each basic block. */ -- cgit v1.2.1