GCOV: Vector refactoring II

2017-10-31  Martin Liska  <mliska@suse.cz>

	* gcov.c (struct line_info): Remove it's typedef.
	(line_info::line_info): Add proper ctor.
	(line_info::has_block): Do not use a typedef.
	(struct source_info): Do not use typedef.
	(circuit): Likewise.
	(get_cycles_count): Likewise.
	(output_intermediate_file): Iterate via vector iterator.
	(add_line_counts): Use std::vector methods.
	(accumulate_line_counts): Likewise.
	(output_lines): Likewise.

From-SVN: r254261
This commit is contained in:
Martin Liska 2017-10-31 12:59:14 +01:00 committed by Martin Liska
parent c7432e7603
commit 4695d816a3
2 changed files with 86 additions and 76 deletions

View File

@ -1,3 +1,16 @@
2017-10-31 Martin Liska <mliska@suse.cz>
* gcov.c (struct line_info): Remove it's typedef.
(line_info::line_info): Add proper ctor.
(line_info::has_block): Do not use a typedef.
(struct source_info): Do not use typedef.
(circuit): Likewise.
(get_cycles_count): Likewise.
(output_intermediate_file): Iterate via vector iterator.
(add_line_counts): Use std::vector methods.
(accumulate_line_counts): Likewise.
(output_lines): Likewise.
2017-10-31 Martin Liska <mliska@suse.cz> 2017-10-31 Martin Liska <mliska@suse.cz>
* gcov.c (struct source_info): Remove typedef. * gcov.c (struct source_info): Remove typedef.

View File

@ -108,9 +108,6 @@ typedef struct arc_info
/* Loop making arc. */ /* Loop making arc. */
unsigned int cycle : 1; unsigned int cycle : 1;
/* Next branch on line. */
struct arc_info *line_next;
/* Links to next arc on src and dst lists. */ /* Links to next arc on src and dst lists. */
struct arc_info *succ_next; struct arc_info *succ_next;
struct arc_info *pred_next; struct arc_info *pred_next;
@ -245,28 +242,37 @@ typedef struct coverage_info
/* Describes a single line of source. Contains a chain of basic blocks /* Describes a single line of source. Contains a chain of basic blocks
with code on it. */ with code on it. */
typedef struct line_info struct line_info
{ {
/* Default constructor. */
line_info ();
/* Return true when NEEDLE is one of basic blocks the line belongs to. */ /* Return true when NEEDLE is one of basic blocks the line belongs to. */
bool has_block (block_t *needle); bool has_block (block_t *needle);
gcov_type count; /* execution count */ /* Execution count. */
arc_t *branches; /* branches from blocks that end on this line. */ gcov_type count;
block_t *blocks; /* blocks which start on this line.
Used in all-blocks mode. */ /* Branches from blocks that end on this line. */
vector<arc_t *> branches;
/* blocks which start on this line. Used in all-blocks mode. */
vector<block_t *> blocks;
unsigned exists : 1; unsigned exists : 1;
unsigned unexceptional : 1; unsigned unexceptional : 1;
unsigned has_unexecuted_block : 1; unsigned has_unexecuted_block : 1;
} line_t; };
line_info::line_info (): count (0), branches (), blocks (), exists (false),
unexceptional (0), has_unexecuted_block (0)
{
}
bool bool
line_t::has_block (block_t *needle) line_info::has_block (block_t *needle)
{ {
for (block_t *n = blocks; n; n = n->chain) return std::find (blocks.begin (), blocks.end (), needle) != blocks.end ();
if (n == needle)
return true;
return false;
} }
/* Describes a file mentioned in the block graph. Contains an array /* Describes a file mentioned in the block graph. Contains an array
@ -282,7 +288,7 @@ struct source_info
time_t file_time; time_t file_time;
/* Vector of line information. */ /* Vector of line information. */
vector<line_t> lines; vector<line_info> lines;
coverage_t coverage; coverage_t coverage;
@ -569,7 +575,7 @@ unblock (const block_t *u, block_vector_t &blocked,
static loop_type static loop_type
circuit (block_t *v, arc_vector_t &path, block_t *start, circuit (block_t *v, arc_vector_t &path, block_t *start,
block_vector_t &blocked, vector<block_vector_t> &block_lists, block_vector_t &blocked, vector<block_vector_t> &block_lists,
line_t &linfo, int64_t &count) line_info &linfo, int64_t &count)
{ {
loop_type result = NO_LOOP; loop_type result = NO_LOOP;
@ -618,7 +624,7 @@ circuit (block_t *v, arc_vector_t &path, block_t *start,
contains a negative loop, then perform the same function once again. */ contains a negative loop, then perform the same function once again. */
static gcov_type static gcov_type
get_cycles_count (line_t &linfo, bool handle_negative_cycles = true) get_cycles_count (line_info &linfo, bool handle_negative_cycles = true)
{ {
/* Note that this algorithm works even if blocks aren't in sorted order. /* Note that this algorithm works even if blocks aren't in sorted order.
Each iteration of the circuit detection is completely independent Each iteration of the circuit detection is completely independent
@ -628,12 +634,13 @@ get_cycles_count (line_t &linfo, bool handle_negative_cycles = true)
loop_type result = NO_LOOP; loop_type result = NO_LOOP;
gcov_type count = 0; gcov_type count = 0;
for (block_t *block = linfo.blocks; block; block = block->chain) for (vector<block_t *>::iterator it = linfo.blocks.begin ();
it != linfo.blocks.end (); it++)
{ {
arc_vector_t path; arc_vector_t path;
block_vector_t blocked; block_vector_t blocked;
vector<block_vector_t > block_lists; vector<block_vector_t > block_lists;
result |= circuit (block, path, block, blocked, block_lists, linfo, result |= circuit (*it, path, *it, blocked, block_lists, linfo,
count); count);
} }
@ -866,7 +873,7 @@ static void
output_intermediate_file (FILE *gcov_file, source_info *src) output_intermediate_file (FILE *gcov_file, source_info *src)
{ {
unsigned line_num; /* current line number. */ unsigned line_num; /* current line number. */
const line_t *line; /* current line info ptr. */ const line_info *line; /* current line info ptr. */
function_t *fn; /* current function info ptr. */ function_t *fn; /* current function info ptr. */
fprintf (gcov_file, "file:%s\n", src->name); /* source file name */ fprintf (gcov_file, "file:%s\n", src->name); /* source file name */
@ -883,29 +890,29 @@ output_intermediate_file (FILE *gcov_file, source_info *src)
line_num < src->lines.size (); line_num < src->lines.size ();
line_num++, line++) line_num++, line++)
{ {
arc_t *arc;
if (line->exists) if (line->exists)
fprintf (gcov_file, "lcount:%u,%s,%d\n", line_num, fprintf (gcov_file, "lcount:%u,%s,%d\n", line_num,
format_gcov (line->count, 0, -1), line->has_unexecuted_block); format_gcov (line->count, 0, -1), line->has_unexecuted_block);
if (flag_branches) if (flag_branches)
for (arc = line->branches; arc; arc = arc->line_next) for (vector<arc_t *>::const_iterator it = line->branches.begin ();
{ it != line->branches.end (); it++)
if (!arc->is_unconditional && !arc->is_call_non_return) {
{ if (!(*it)->is_unconditional && !(*it)->is_call_non_return)
const char *branch_type; {
/* branch:<line_num>,<branch_coverage_type> const char *branch_type;
branch_coverage_type /* branch:<line_num>,<branch_coverage_type>
: notexec (Branch not executed) branch_coverage_type
: taken (Branch executed and taken) : notexec (Branch not executed)
: nottaken (Branch executed, but not taken) : taken (Branch executed and taken)
*/ : nottaken (Branch executed, but not taken)
if (arc->src->count) */
branch_type = (arc->count > 0) ? "taken" : "nottaken"; if ((*it)->src->count)
else branch_type = ((*it)->count > 0) ? "taken" : "nottaken";
branch_type = "notexec"; else
fprintf (gcov_file, "branch:%d,%s\n", line_num, branch_type); branch_type = "notexec";
} fprintf (gcov_file, "branch:%d,%s\n", line_num, branch_type);
} }
}
} }
} }
@ -2234,7 +2241,7 @@ add_line_counts (coverage_t *coverage, function_t *fn)
/* Scan each basic block. */ /* Scan each basic block. */
for (unsigned ix = 0; ix != fn->blocks.size (); ix++) for (unsigned ix = 0; ix != fn->blocks.size (); ix++)
{ {
line_t *line = NULL; line_info *line = NULL;
block_t *block = &fn->blocks[ix]; block_t *block = &fn->blocks[ix];
if (block->count && ix && ix + 1 != fn->blocks.size ()) if (block->count && ix && ix + 1 != fn->blocks.size ())
fn->blocks_executed++; fn->blocks_executed++;
@ -2271,8 +2278,7 @@ add_line_counts (coverage_t *coverage, function_t *fn)
/* Entry or exit block */; /* Entry or exit block */;
else if (line != NULL) else if (line != NULL)
{ {
block->chain = line->blocks; line->blocks.push_back (block);
line->blocks = block;
if (flag_branches) if (flag_branches)
{ {
@ -2280,8 +2286,7 @@ add_line_counts (coverage_t *coverage, function_t *fn)
for (arc = block->succ; arc; arc = arc->succ_next) for (arc = block->succ; arc; arc = arc->succ_next)
{ {
arc->line_next = line->branches; line->branches.push_back (arc);
line->branches = arc;
if (coverage && !arc->is_unconditional) if (coverage && !arc->is_unconditional)
add_branch_counts (coverage, arc); add_branch_counts (coverage, arc);
} }
@ -2309,11 +2314,11 @@ accumulate_line_counts (source_info *src)
} }
src->functions = fn_p; src->functions = fn_p;
for (vector<line_t>::reverse_iterator it = src->lines.rbegin (); for (vector<line_info>::reverse_iterator it = src->lines.rbegin ();
it != src->lines.rend (); it++) it != src->lines.rend (); it++)
{ {
line_t *line = &(*it); line_info *line = &(*it);
if (line->blocks) if (!line->blocks.empty ())
{ {
/* The user expects the line count to be the number of times /* The user expects the line count to be the number of times
a line has been executed. Simply summing the block count a line has been executed. Simply summing the block count
@ -2321,36 +2326,27 @@ accumulate_line_counts (source_info *src)
is to sum the entry counts to the graph of blocks on this is to sum the entry counts to the graph of blocks on this
line, then find the elementary cycles of the local graph line, then find the elementary cycles of the local graph
and add the transition counts of those cycles. */ and add the transition counts of those cycles. */
block_t *block, *block_p, *block_n;
gcov_type count = 0; gcov_type count = 0;
/* Reverse the block information. */
for (block = line->blocks, block_p = NULL; block;
block_p = block, block = block_n)
{
block_n = block->chain;
block->chain = block_p;
block->cycle.ident = ix;
}
line->blocks = block_p;
/* Sum the entry arcs. */ /* Sum the entry arcs. */
for (block = line->blocks; block; block = block->chain) for (vector<block_t *>::iterator it = line->blocks.begin ();
it != line->blocks.end (); it++)
{ {
arc_t *arc; arc_t *arc;
for (arc = block->pred; arc; arc = arc->pred_next) for (arc = (*it)->pred; arc; arc = arc->pred_next)
if (flag_branches) if (flag_branches)
add_branch_counts (&src->coverage, arc); add_branch_counts (&src->coverage, arc);
} }
/* Cycle detection. */ /* Cycle detection. */
for (block = line->blocks; block; block = block->chain) for (vector<block_t *>::iterator it = line->blocks.begin ();
it != line->blocks.end (); it++)
{ {
for (arc_t *arc = block->pred; arc; arc = arc->pred_next) for (arc_t *arc = (*it)->pred; arc; arc = arc->pred_next)
if (!line->has_block (arc->src)) if (!line->has_block (arc->src))
count += arc->count; count += arc->count;
for (arc_t *arc = block->succ; arc; arc = arc->succ_next) for (arc_t *arc = (*it)->succ; arc; arc = arc->succ_next)
arc->cs_count = arc->count; arc->cs_count = arc->count;
} }
@ -2534,7 +2530,7 @@ output_lines (FILE *gcov_file, const source_info *src)
FILE *source_file; FILE *source_file;
unsigned line_num; /* current line number. */ unsigned line_num; /* current line number. */
const line_t *line; /* current line info ptr. */ const line_info *line; /* current line info ptr. */
const char *retval = ""; /* status of source file reading. */ const char *retval = ""; /* status of source file reading. */
function_t *fn = NULL; function_t *fn = NULL;
@ -2601,36 +2597,37 @@ output_lines (FILE *gcov_file, const source_info *src)
if (flag_all_blocks) if (flag_all_blocks)
{ {
block_t *block;
arc_t *arc; arc_t *arc;
int ix, jx; int ix, jx;
for (ix = jx = 0, block = line->blocks; block; ix = jx = 0;
block = block->chain) for (vector<block_t *>::const_iterator it = line->blocks.begin ();
it != line->blocks.end (); it++)
{ {
if (!block->is_call_return) if (!(*it)->is_call_return)
{ {
output_line_beginning (gcov_file, line->exists, output_line_beginning (gcov_file, line->exists,
block->exceptional, false, (*it)->exceptional, false,
block->count, line_num, (*it)->count, line_num,
"%%%%%", "$$$$$"); "%%%%%", "$$$$$");
fprintf (gcov_file, "-block %2d", ix++); fprintf (gcov_file, "-block %2d", ix++);
if (flag_verbose) if (flag_verbose)
fprintf (gcov_file, " (BB %u)", block->id); fprintf (gcov_file, " (BB %u)", (*it)->id);
fprintf (gcov_file, "\n"); fprintf (gcov_file, "\n");
} }
if (flag_branches) if (flag_branches)
for (arc = block->succ; arc; arc = arc->succ_next) for (arc = (*it)->succ; arc; arc = arc->succ_next)
jx += output_branch_count (gcov_file, jx, arc); jx += output_branch_count (gcov_file, jx, arc);
} }
} }
else if (flag_branches) else if (flag_branches)
{ {
int ix; int ix;
arc_t *arc;
for (ix = 0, arc = line->branches; arc; arc = arc->line_next) ix = 0;
ix += output_branch_count (gcov_file, ix, arc); for (vector<arc_t *>::const_iterator it = line->branches.begin ();
it != line->branches.end (); it++)
ix += output_branch_count (gcov_file, ix, (*it));
} }
} }