diff options
author | Martin Liska <mliska@suse.cz> | 2023-04-06 11:54:51 +0200 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2023-04-25 13:11:29 +0200 |
commit | 171fe0681ef91ecf29164d278ca5b064a6056f80 (patch) | |
tree | a3c8fcb2126373d995b6e8a86a42b0ddda71ce44 /gcc | |
parent | dee5cef280d6c6da92b56cc0dc2158761c266992 (diff) | |
download | gcc-171fe0681ef91ecf29164d278ca5b064a6056f80.zip gcc-171fe0681ef91ecf29164d278ca5b064a6056f80.tar.gz gcc-171fe0681ef91ecf29164d278ca5b064a6056f80.tar.bz2 |
gcov: add info about "calls" to JSON output format
gcc/ChangeLog:
* doc/gcov.texi: Document the new "calls" field and document
the API bump. Mention also "block_ids" for lines.
* gcov.cc (output_intermediate_json_line): Output info about
calls and extend branches as well.
(generate_results): Bump version to 2.
(output_line_details): Use block ID instead of a non-sensual
index.
gcc/testsuite/ChangeLog:
* g++.dg/gcov/gcov-17.C: Add call to a noreturn function.
* g++.dg/gcov/test-gcov-17.py: Cover new format.
* lib/gcov.exp: Add options for gcov that emit the extra info.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/doc/gcov.texi | 47 | ||||
-rw-r--r-- | gcc/gcov.cc | 31 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/gcov/gcov-17.C | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/gcov/test-gcov-17.py | 20 | ||||
-rw-r--r-- | gcc/testsuite/lib/gcov.exp | 2 |
5 files changed, 95 insertions, 12 deletions
diff --git a/gcc/doc/gcov.texi b/gcc/doc/gcov.texi index d39cce3..3019efc 100644 --- a/gcc/doc/gcov.texi +++ b/gcc/doc/gcov.texi @@ -195,7 +195,7 @@ Structure of the JSON is following: @{ "current_working_directory": "foo/bar", "data_file": "a.out", - "format_version": "1", + "format_version": "2", "gcc_version": "11.1.1 20210510" "files": ["$file"] @} @@ -214,6 +214,12 @@ a compilation unit was compiled @item @var{format_version}: semantic version of the format +Changes in version @emph{2}: +@itemize @bullet +@item +@var{calls}: information about function calls is added +@end itemize + @item @var{gcc_version}: version of the GCC compiler @end itemize @@ -291,7 +297,9 @@ Each @var{line} has the following form: @smallexample @{ + "block_ids": ["$block_id"], "branches": ["$branch"], + "calls": ["$call"], "count": 2, "line_number": 15, "unexecuted_block": false, @@ -299,11 +307,14 @@ Each @var{line} has the following form: @} @end smallexample -Branches are present only with @var{-b} option. +Branches and calls are present only with @var{-b} option. Fields of the @var{line} element have following semantics: @itemize @bullet @item +@var{block_ids}: IDs of basic blocks that belong to the line + +@item @var{count}: number of executions of the line @item @@ -323,7 +334,9 @@ Each @var{branch} has the following form: @smallexample @{ "count": 11, + "destination_block_id": 17, "fallthrough": true, + "source_block_id": 13, "throw": false @} @end smallexample @@ -339,6 +352,36 @@ Fields of the @var{branch} element have following semantics: @item @var{throw}: true when the branch is an exceptional branch + +@item +@var{isource_block_id}: ID of the basic block where this branch happens + +@item +@var{destination_block_id}: ID of the basic block this branch jumps to +@end itemize + +Each @var{call} has the following form: + +@smallexample +@{ + "destination_block_id": 1, + "returned": 11, + "source_block_id": 13 +@} +@end smallexample + +Fields of the @var{call} element have following semantics: + +@itemize @bullet +@item +@var{returned}: number of times a function call returned (call count is equal +to @var{line::count}) + +@item +@var{isource_block_id}: ID of the basic block where this call happens + +@item +@var{destination_block_id}: ID of the basic block this calls continues after return @end itemize @item -H diff --git a/gcc/gcov.cc b/gcc/gcov.cc index 2ec7248..d96b4f7 100644 --- a/gcc/gcov.cc +++ b/gcc/gcov.cc @@ -1113,9 +1113,17 @@ output_intermediate_json_line (json::array *object, lineo->set ("unexecuted_block", new json::literal (line->has_unexecuted_block)); + json::array *bb_ids = new json::array (); + for (const block_info *block : line->blocks) + bb_ids->append (new json::integer_number (block->id)); + lineo->set ("block_ids", bb_ids); + json::array *branches = new json::array (); lineo->set ("branches", branches); + json::array *calls = new json::array (); + lineo->set ("calls", calls); + vector<arc_info *>::const_iterator it; if (flag_branches) for (it = line->branches.begin (); it != line->branches.end (); @@ -1128,8 +1136,23 @@ output_intermediate_json_line (json::array *object, branch->set ("throw", new json::literal ((*it)->is_throw)); branch->set ("fallthrough", new json::literal ((*it)->fall_through)); + branch->set ("source_block_id", + new json::integer_number ((*it)->src->id)); + branch->set ("destination_block_id", + new json::integer_number ((*it)->dst->id)); branches->append (branch); } + else if ((*it)->is_call_non_return) + { + json::object *call = new json::object (); + gcov_type returns = (*it)->src->count - (*it)->count; + call->set ("source_block_id", + new json::integer_number ((*it)->src->id)); + call->set ("destination_block_id", + new json::integer_number ((*it)->dst->id)); + call->set ("returned", new json::integer_number (returns)); + calls->append (call); + } } object->append (lineo); @@ -1523,7 +1546,7 @@ generate_results (const char *file_name) gcov_intermediate_filename = get_gcov_intermediate_filename (file_name); json::object *root = new json::object (); - root->set ("format_version", new json::string ("1")); + root->set ("format_version", new json::string ("2")); root->set ("gcc_version", new json::string (version_string)); if (bbg_cwd != NULL) @@ -3060,9 +3083,7 @@ output_line_details (FILE *f, const line_info *line, unsigned line_num) if (flag_all_blocks) { arc_info *arc; - int ix, jx; - - ix = jx = 0; + int jx = 0; for (vector<block_info *>::const_iterator it = line->blocks.begin (); it != line->blocks.end (); it++) { @@ -3072,7 +3093,7 @@ output_line_details (FILE *f, const line_info *line, unsigned line_num) (*it)->exceptional, false, (*it)->count, line_num, "%%%%%", "$$$$$", 0); - fprintf (f, "-block %2d", ix++); + fprintf (f, "-block %d", (*it)->id); if (flag_verbose) fprintf (f, " (BB %u)", (*it)->id); fprintf (f, "\n"); diff --git a/gcc/testsuite/g++.dg/gcov/gcov-17.C b/gcc/testsuite/g++.dg/gcov/gcov-17.C index d11883c..efe0195 100644 --- a/gcc/testsuite/g++.dg/gcov/gcov-17.C +++ b/gcc/testsuite/g++.dg/gcov/gcov-17.C @@ -15,6 +15,11 @@ private: template class Foo<int>; template class Foo<char>; +static void noret() +{ + __builtin_exit (0); +} + int main (void) { @@ -34,6 +39,8 @@ main (void) __builtin_printf ("Failure\n"); else __builtin_printf ("Success\n"); + + noret (); return 0; } diff --git a/gcc/testsuite/g++.dg/gcov/test-gcov-17.py b/gcc/testsuite/g++.dg/gcov/test-gcov-17.py index ec5df3d..ad065b0 100644 --- a/gcc/testsuite/g++.dg/gcov/test-gcov-17.py +++ b/gcc/testsuite/g++.dg/gcov/test-gcov-17.py @@ -12,7 +12,7 @@ def test_basics(gcov): files = gcov['files'] assert len(files) == 1 functions = files[0]['functions'] - assert len(functions) == 5 + assert len(functions) == 6 def test_lines(gcov): @@ -31,7 +31,19 @@ def test_lines(gcov): assert line9[1]['count'] == 2 assert line9[0]['unexecuted_block'] assert not line9[1]['unexecuted_block'] - assert linesdict[31][0]['unexecuted_block'] - assert linesdict[34][0]['unexecuted_block'] - assert not linesdict[37][0]['unexecuted_block'] + assert linesdict[36][0]['unexecuted_block'] + assert linesdict[39][0]['unexecuted_block'] + assert not linesdict[41][0]['unexecuted_block'] assert 32 not in linesdict + print(lines) + + line41 = linesdict[41][0] + assert line41['count'] == 1 + assert line41['calls'][0]['returned'] == 1 + assert line41['calls'][0]['source_block_id'] == 13 + assert line41['calls'][0]['destination_block_id'] == 1 + assert len(line41['block_ids']) > 0 + + line43 = linesdict[43][0] + assert line43['count'] == 1 + assert line43['calls'][0]['returned'] == 0 diff --git a/gcc/testsuite/lib/gcov.exp b/gcc/testsuite/lib/gcov.exp index 80e74ae..e5e94fa 100644 --- a/gcc/testsuite/lib/gcov.exp +++ b/gcc/testsuite/lib/gcov.exp @@ -274,7 +274,7 @@ proc run-gcov-pytest { args } { verbose "Running $GCOV $testcase in $srcdir/$subdir" 2 set testcase [remote_download host $testcase] - set result [remote_exec host $GCOV "$testcase -i"] + set result [remote_exec host $GCOV "$testcase -i -abc"] set pytest_script [lindex $args 1] if { ![check_effective_target_pytest3] } { |