Commit 211bea6b by Martin Liska Committed by Martin Liska

GCOV: introduce global vector of functions

2017-11-13  Martin Liska  <mliska@suse.cz>

	* 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.

From-SVN: r254672
parent 5bfd2f9b
2017-11-13 Martin Liska <mliska@suse.cz>
* 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.
2017-11-13 Jakub Jelinek <jakub@redhat.com> 2017-11-13 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/82954 PR tree-optimization/82954
...@@ -392,10 +392,8 @@ public: ...@@ -392,10 +392,8 @@ public:
unsigned src; /* Source file */ unsigned src; /* Source file */
}; };
/* Holds a list of function basic block graphs. */ /* Vector of all functions. */
static vector<function_t *> functions;
static function_t *functions;
static function_t **fn_end = &functions;
/* Vector of source files. */ /* Vector of source files. */
static vector<source_info> sources; static vector<source_info> sources;
...@@ -535,8 +533,8 @@ static void generate_results (const char *); ...@@ -535,8 +533,8 @@ static void generate_results (const char *);
static void create_file_names (const char *); static void create_file_names (const char *);
static char *canonicalize_name (const char *); static char *canonicalize_name (const char *);
static unsigned find_source (const char *); static unsigned find_source (const char *);
static function_t *read_graph_file (void); static void read_graph_file (void);
static int read_count_file (function_t *); static int read_count_file (void);
static void solve_flow_graph (function_t *); static void solve_flow_graph (function_t *);
static void find_exception_blocks (function_t *); static void find_exception_blocks (function_t *);
static void add_branch_counts (coverage_t *, const arc_t *); static void add_branch_counts (coverage_t *, const arc_t *);
...@@ -1125,42 +1123,40 @@ struct function_start_pair_hash : typed_noop_remove <function_start> ...@@ -1125,42 +1123,40 @@ struct function_start_pair_hash : typed_noop_remove <function_start>
static void static void
process_file (const char *file_name) process_file (const char *file_name)
{ {
function_t *fns;
create_file_names (file_name); create_file_names (file_name);
fns = read_graph_file (); read_graph_file ();
if (!fns) if (functions.empty ())
return; return;
read_count_file (fns); read_count_file ();
hash_map<function_start_pair_hash, function_t *> fn_map; hash_map<function_start_pair_hash, function_t *> fn_map;
/* Identify group functions. */ /* Identify group functions. */
for (function_t *f = fns; f; f = f->next) for (vector<function_t *>::iterator it = functions.begin ();
if (!f->artificial) it != functions.end (); it++)
if (!(*it)->artificial)
{ {
function_start needle; function_start needle;
needle.source_file_idx = f->src; needle.source_file_idx = (*it)->src;
needle.start_line = f->start_line; needle.start_line = (*it)->start_line;
function_t **slot = fn_map.get (needle); function_t **slot = fn_map.get (needle);
if (slot) if (slot)
{ {
gcc_assert ((*slot)->end_line == f->end_line); gcc_assert ((*slot)->end_line == (*it)->end_line);
(*slot)->is_group = 1; (*slot)->is_group = 1;
f->is_group = 1; (*it)->is_group = 1;
} }
else else
fn_map.put (needle, f); fn_map.put (needle, *it);
} }
while (fns) for (vector<function_t *>::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) if (fn->counts || no_data_file)
{ {
unsigned src = fn->src; unsigned src = fn->src;
...@@ -1207,14 +1203,12 @@ process_file (const char *file_name) ...@@ -1207,14 +1203,12 @@ process_file (const char *file_name)
if (fn->has_catch) if (fn->has_catch)
find_exception_blocks (fn); find_exception_blocks (fn);
} }
*fn_end = fn;
fn_end = &fn->next;
} }
else else
/* The function was not in the executable -- some other {
instance must have been selected. */ /* The function was not in the executable -- some other
delete fn; instance must have been selected. */
}
} }
} }
...@@ -1249,12 +1243,13 @@ output_gcov_file (const char *file_name, source_info *src) ...@@ -1249,12 +1243,13 @@ output_gcov_file (const char *file_name, source_info *src)
static void static void
generate_results (const char *file_name) generate_results (const char *file_name)
{ {
function_t *fn;
FILE *gcov_intermediate_file = NULL; FILE *gcov_intermediate_file = NULL;
char *gcov_intermediate_filename = NULL; char *gcov_intermediate_filename = NULL;
for (fn = functions; fn; fn = fn->next) for (vector<function_t *>::iterator it = functions.begin ();
it != functions.end (); it++)
{ {
function_t *fn = *it;
coverage_t coverage; coverage_t coverage;
if (fn->artificial) if (fn->artificial)
continue; continue;
...@@ -1345,18 +1340,13 @@ generate_results (const char *file_name) ...@@ -1345,18 +1340,13 @@ generate_results (const char *file_name)
static void static void
release_structures (void) release_structures (void)
{ {
function_t *fn; for (vector<function_t *>::iterator it = functions.begin ();
it != functions.end (); it++)
delete (*it);
sources.resize (0); sources.resize (0);
names.resize (0); names.resize (0);
functions.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 /* Generate the names of the graph and data files. If OBJECT_DIRECTORY
...@@ -1514,29 +1504,26 @@ find_source (const char *file_name) ...@@ -1514,29 +1504,26 @@ find_source (const char *file_name)
return idx; 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) read_graph_file (void)
{ {
unsigned version; unsigned version;
unsigned current_tag = 0; unsigned current_tag = 0;
function_t *fn = NULL;
function_t *fns = NULL;
function_t **fns_end = &fns;
unsigned tag; unsigned tag;
if (!gcov_open (bbg_file_name, 1)) if (!gcov_open (bbg_file_name, 1))
{ {
fnotice (stderr, "%s:cannot open notes file\n", bbg_file_name); fnotice (stderr, "%s:cannot open notes file\n", bbg_file_name);
return fns; return;
} }
bbg_file_time = gcov_time (); bbg_file_time = gcov_time ();
if (!gcov_magic (gcov_read_unsigned (), GCOV_NOTE_MAGIC)) if (!gcov_magic (gcov_read_unsigned (), GCOV_NOTE_MAGIC))
{ {
fnotice (stderr, "%s:not a gcov notes file\n", bbg_file_name); fnotice (stderr, "%s:not a gcov notes file\n", bbg_file_name);
gcov_close (); gcov_close ();
return fns; return;
} }
version = gcov_read_unsigned (); version = gcov_read_unsigned ();
...@@ -1553,6 +1540,7 @@ read_graph_file (void) ...@@ -1553,6 +1540,7 @@ read_graph_file (void)
bbg_stamp = gcov_read_unsigned (); bbg_stamp = gcov_read_unsigned ();
bbg_supports_has_unexecuted_blocks = gcov_read_unsigned (); bbg_supports_has_unexecuted_blocks = gcov_read_unsigned ();
function_t *fn = NULL;
while ((tag = gcov_read_unsigned ())) while ((tag = gcov_read_unsigned ()))
{ {
unsigned length = gcov_read_unsigned (); unsigned length = gcov_read_unsigned ();
...@@ -1574,7 +1562,8 @@ read_graph_file (void) ...@@ -1574,7 +1562,8 @@ read_graph_file (void)
unsigned start_column = gcov_read_unsigned (); unsigned start_column = gcov_read_unsigned ();
unsigned end_line = 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; fn->name = function_name;
if (flag_demangled_names) if (flag_demangled_names)
{ {
...@@ -1591,9 +1580,6 @@ read_graph_file (void) ...@@ -1591,9 +1580,6 @@ read_graph_file (void)
fn->end_line = end_line; fn->end_line = end_line;
fn->artificial = artificial; fn->artificial = artificial;
fn->next = NULL;
*fns_end = fn;
fns_end = &fn->next;
current_tag = tag; current_tag = tag;
} }
else if (fn && tag == GCOV_TAG_BLOCKS) else if (fn && tag == GCOV_TAG_BLOCKS)
...@@ -1719,17 +1705,15 @@ read_graph_file (void) ...@@ -1719,17 +1705,15 @@ read_graph_file (void)
} }
gcov_close (); gcov_close ();
if (!fns) if (functions.empty ())
fnotice (stderr, "%s:no functions found\n", bbg_file_name); fnotice (stderr, "%s:no functions found\n", bbg_file_name);
return fns;
} }
/* Reads profiles from the count file and attach to each /* Reads profiles from the count file and attach to each
function. Return nonzero if fatal error. */ function. Return nonzero if fatal error. */
static int static int
read_count_file (function_t *fns) read_count_file (void)
{ {
unsigned ix; unsigned ix;
unsigned version; unsigned version;
...@@ -1786,26 +1770,20 @@ read_count_file (function_t *fns) ...@@ -1786,26 +1770,20 @@ read_count_file (function_t *fns)
else if (tag == GCOV_TAG_FUNCTION && length == GCOV_TAG_FUNCTION_LENGTH) else if (tag == GCOV_TAG_FUNCTION && length == GCOV_TAG_FUNCTION_LENGTH)
{ {
unsigned ident; unsigned ident;
struct function_info *fn_n;
/* Try to find the function in the list. To speed up the /* Try to find the function in the list. To speed up the
search, first start from the last function found. */ search, first start from the last function found. */
ident = gcov_read_unsigned (); ident = gcov_read_unsigned ();
fn_n = fns;
for (fn = fn ? fn->next : NULL; ; fn = fn->next) fn = NULL;
for (vector<function_t *>::reverse_iterator it = functions.rbegin ();
it != functions.rend (); it++)
{ {
if (fn) if ((*it)->ident == ident)
;
else if ((fn = fn_n))
fn_n = NULL;
else
{ {
fnotice (stderr, "%s:unknown function '%u'\n", fn = *it;
da_file_name, ident);
break; break;
} }
if (fn->ident == ident)
break;
} }
if (!fn) if (!fn)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment