Commit c8fda30f by Martin Liska Committed by Martin Liska

GCOV: introduce --json-format.

2018-10-29  Martin Liska  <mliska@suse.cz>

	* Makefile.in: Make dependency to json.o.
	* doc/gcov.texi: Document new JSON format, remove
	old intermediate format documentation.
	* gcov.c (struct function_info): Come up with m_name and
	m_demangled_name.
	(function_info::function_info): Initialize it.
	(function_info::~function_info): Release it.
	(main): Rename flag_intermediate_format to flag_json_format.
	(print_usage): Describe --json-format.
	(process_args): Set flag_json_format.
	(output_intermediate_line): Remove.
	(output_intermediate_json_line): Likewise.
	(get_gcov_intermediate_filename): Return new extension
	".gcov.json.gz".
	(output_intermediate_file): Implement JSON emission.
	(output_json_intermediate_file): Implement JSON emission.
	(generate_results): Use ::get_name for function name.
	Handle JSON output file.
	(read_graph_file): Use ::get_name instead of cplus_demangle.
	(read_count_file): Likewise.
	(solve_flow_graph): Likewise.
	(add_line_counts): Likewise.
	(accumulate_line_counts): Use new flag_json_format.
	(output_function_details): Use ::get_name instead of cplus_demangle.
	(output_lines): Likewise.
	* json.cc (test_writing_literals): Add new tests.
	* json.h (class literal): Add new boolean constructor.
2018-10-29  Martin Liska  <mliska@suse.cz>

	* g++.dg/gcov/gcov-8.C: Do not check intermediate format.
	* lib/gcov.exp: Remove legacy verify-intermediate.

From-SVN: r265587
parent d4eb0305
2018-10-29 Martin Liska <mliska@suse.cz>
* Makefile.in: Make dependency to json.o.
* doc/gcov.texi: Document new JSON format, remove
old intermediate format documentation.
* gcov.c (struct function_info): Come up with m_name and
m_demangled_name.
(function_info::function_info): Initialize it.
(function_info::~function_info): Release it.
(main): Rename flag_intermediate_format to flag_json_format.
(print_usage): Describe --json-format.
(process_args): Set flag_json_format.
(output_intermediate_line): Remove.
(output_intermediate_json_line): Likewise.
(get_gcov_intermediate_filename): Return new extension
".gcov.json.gz".
(output_intermediate_file): Implement JSON emission.
(output_json_intermediate_file): Implement JSON emission.
(generate_results): Use ::get_name for function name.
Handle JSON output file.
(read_graph_file): Use ::get_name instead of cplus_demangle.
(read_count_file): Likewise.
(solve_flow_graph): Likewise.
(add_line_counts): Likewise.
(accumulate_line_counts): Use new flag_json_format.
(output_function_details): Use ::get_name instead of cplus_demangle.
(output_lines): Likewise.
* json.cc (test_writing_literals): Add new tests.
* json.h (class literal): Add new boolean constructor.
2018-10-29 Segher Boessenkool <segher@kernel.crashing.org>
PR rtl-optimization/87701
......@@ -2899,10 +2899,13 @@ s-iov: build/gcov-iov$(build_exeext) $(BASEVER) $(DEVPHASE)
$(SHELL) $(srcdir)/../move-if-change tmp-gcov-iov.h gcov-iov.h
$(STAMP) s-iov
GCOV_OBJS = gcov.o
# gcov.o needs $(ZLIBINC) added to the include flags.
CFLAGS-gcov.o += $(ZLIBINC)
GCOV_OBJS = gcov.o json.o
gcov$(exeext): $(GCOV_OBJS) $(LIBDEPS)
+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) $(GCOV_OBJS) \
hash-table.o ggc-none.o $(LIBS) -o $@
hash-table.o ggc-none.o $(LIBS) $(ZLIB) -o $@
GCOV_DUMP_OBJS = gcov-dump.o
gcov-dump$(exeext): $(GCOV_DUMP_OBJS) $(LIBDEPS)
+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) $(GCOV_DUMP_OBJS) \
......
......@@ -124,7 +124,7 @@ gcov [@option{-v}|@option{--version}] [@option{-h}|@option{--help}]
[@option{-c}|@option{--branch-counts}]
[@option{-d}|@option{--display-progress}]
[@option{-f}|@option{--function-summaries}]
[@option{-i}|@option{--intermediate-format}]
[@option{-i}|@option{--json-format}]
[@option{-j}|@option{--human-readable}]
[@option{-k}|@option{--use-colors}]
[@option{-l}|@option{--long-file-names}]
......@@ -181,79 +181,142 @@ Display help about using @command{gcov} (on the standard output), and
exit without doing any further processing.
@item -i
@itemx --intermediate-format
Output gcov file in an easy-to-parse intermediate text format that can
be used by @command{lcov} or other tools. The output is a single
@file{.gcov} file per @file{.gcda} file. No source code is required.
@itemx --json-format
Output gcov file in an easy-to-parse JSON intermediate format
which does not require source code for generation. The JSON
file is compressed with gzip compression algorithm
and the files have @file{.gcov.json.gz} extension.
The format of the intermediate @file{.gcov} file is plain text with
one entry per line
Structure of the JSON is following:
@smallexample
version:@var{gcc_version}
cwd:@var{working_directory}
file:@var{source_file_name}
function:@var{start_line_number},@var{end_line_number},@var{execution_count},@var{function_name}
lcount:@var{line number},@var{execution_count},@var{has_unexecuted_block}
branch:@var{line_number},@var{branch_coverage_type}
Where the @var{branch_coverage_type} is
notexec (Branch not executed)
taken (Branch executed and taken)
nottaken (Branch executed, but not taken)
@{
"current_working_directory": @var{current_working_directory},
"format_version": @var{format_version},
"gcc_version": @var{gcc_version}
"files": [@var{file}]
@}
@end smallexample
There can be multiple @var{file} entries in an intermediate gcov
file. All entries following a @var{file} pertain to that source file
until the next @var{file} entry. If there are multiple functions that
start on a single line, then corresponding lcount is repeated multiple
times.
Fields of the root element have following semantics:
Here is a sample when @option{-i} is used in conjunction with @option{-b} option:
@itemize @bullet
@item
@var{current_working_directory}: working directory where
a compilation unit was compiled
@item
@var{format_version}: semantic version of the format
@item
@var{gcc_version}: version of the GCC compiler
@end itemize
Each @var{file} has the following form:
@smallexample
@{
"file": @var{file_name},
"functions": [@var{function}],
"lines": [@var{line}]
@}
@end smallexample
Fields of the @var{file} element have following semantics:
@itemize @bullet
@item
@var{file_name}: name of the source file
@end itemize
Each @var{function} has the following form:
@smallexample
@{
"blocks": @var{blocks},
"blocks_executed": @var{blocks_executed},
"demangled_name": "@var{demangled_name},
"end_line": @var{end_line},
"execution_count": @var{execution_count},
"name": @var{name},
"start_line": @var{start_line}
@}
@end smallexample
Fields of the @var{function} element have following semantics:
@itemize @bullet
@item
@var{blocks}: number of blocks that are in the function
@item
@var{blocks_executed}: number of executed blocks of the function
@item
@var{demangled_name}: demangled name of the function
@item
@var{end_line}: line in the source file where the function ends
@item
@var{execution_count}: number of executions of the function
@item
@var{name}: name of the function
@item
@var{start_line}: line in the source file where the function begins
@end itemize
Each @var{line} has the following form:
@smallexample
@{
"branches": [@var{branch}],
"count": @var{count},
"line_number": @var{line_number},
"unexecuted_block": @var{unexecuted_block}
@}
@end smallexample
Branches are present only with @var{-b} option.
Fields of the @var{line} element have following semantics:
@itemize @bullet
@item
@var{count}: number of executions of the line
@item
@var{line_number}: line number
@item
@var{unexecuted_block}: flag whether the line contains an unexecuted block
(not all statements on the line are executed)
@end itemize
Each @var{branch} has the following form:
@smallexample
version: 8.1.0 20180103
cwd:/home/gcc/testcase
file:tmp.cpp
function:7,7,0,_ZN3FooIcEC2Ev
function:7,7,1,_ZN3FooIiEC2Ev
function:8,8,0,_ZN3FooIcE3incEv
function:8,8,2,_ZN3FooIiE3incEv
function:18,37,1,main
lcount:7,0,1
lcount:7,1,0
lcount:8,0,1
lcount:8,2,0
lcount:18,1,0
lcount:21,1,0
branch:21,taken
branch:21,nottaken
lcount:23,1,0
branch:23,taken
branch:23,nottaken
lcount:24,1,0
branch:24,taken
branch:24,nottaken
lcount:25,1,0
lcount:27,11,0
branch:27,taken
branch:27,taken
lcount:28,10,0
lcount:30,1,1
branch:30,nottaken
branch:30,taken
lcount:32,1,0
branch:32,nottaken
branch:32,taken
lcount:33,0,1
branch:33,notexec
branch:33,notexec
lcount:35,1,0
branch:35,taken
branch:35,nottaken
lcount:36,1,0
@{
"count": @var{count},
"fallthrough": @var{fallthrough},
"throw": @var{throw}
@}
@end smallexample
Fields of the @var{branch} element have following semantics:
@itemize @bullet
@item
@var{count}: number of executions of the branch
@item
@var{fallthrough}: true when the branch is a fall through branch
@item
@var{throw}: true when the branch is an exceptional branch
@end itemize
@item -j
@itemx --human-readable
Write counts in human readable format (like 24.6k).
......@@ -842,7 +905,7 @@ some summary information.
It is not recommended to access the coverage files directly.
Consumers should use the intermediate format that is provided
by @command{gcov} tool via @option{--intermediate-format} option.
by @command{gcov} tool via @option{--json-format} option.
@node Cross-profiling
@section Data File Relocation to Support Cross-Profiling
......
......@@ -296,6 +296,9 @@ test_writing_literals ()
assert_print_eq (literal (JSON_TRUE), "true");
assert_print_eq (literal (JSON_FALSE), "false");
assert_print_eq (literal (JSON_NULL), "null");
assert_print_eq (literal (true), "true");
assert_print_eq (literal (false), "false");
}
/* Run all of the selftests within this file. */
......
......@@ -154,6 +154,9 @@ class literal : public value
public:
literal (enum kind kind) : m_kind (kind) {}
/* Construct literal for a boolean value. */
literal (bool value): m_kind (value ? JSON_TRUE : JSON_FALSE) {}
enum kind get_kind () const FINAL OVERRIDE { return m_kind; }
void print (pretty_printer *pp) const FINAL OVERRIDE;
......
2018-10-29 Martin Liska <mliska@suse.cz>
* g++.dg/gcov/gcov-8.C: Do not check intermediate format.
* lib/gcov.exp: Remove legacy verify-intermediate.
2018-10-28 Kugan Vivekanandarajah <kuganv@linaro.org>
* gcc.dg/gimplefe-30.c: New test.
......
/* Verify that intermediate coverage format can be generated for simple code. */
/* { dg-options "-fprofile-arcs -ftest-coverage" } */
/* { dg-do run { target native } } */
......@@ -32,4 +30,4 @@ int main()
foo();
}
/* { dg-final { run-gcov intermediate { -i -b gcov-8.C } } } */
/* { dg-final { run-gcov { -b gcov-8.C } } } */
......@@ -84,61 +84,6 @@ proc verify-lines { testname testcase file } {
#
# verify-intermediate -- check that intermediate file has certain lines
#
# TESTNAME is the name of the test, including unique flags.
# TESTCASE is the name of the test.
# FILE is the name of the gcov output file.
#
# Checks are very loose, they are based on certain tags being present
# in the output. They do not check for exact expected execution
# counts. For that the regular gcov format should be checked.
#
proc verify-intermediate { testname testcase file } {
set failed 0
set srcfile 0
set function 0
set lcount 0
set branch 0
set fd [open $file r]
while { [gets $fd line] >= 0 } {
if [regexp "^file:" $line] {
incr srcfile
}
if [regexp "^function:(\[0-9\]+),(\[0-9\]+),.*" $line] {
incr function
}
if [regexp "^lcount:(\[0-9\]+),(\[0-9\]+),(\[01\])" $line] {
incr lcount
}
if [regexp "^branch:(\[0-9\]+),(taken|nottaken|notexec)" $line] {
incr branch
}
}
# We should see at least one tag of each type
if {$srcfile == 0} {
fail "$testname expected 'file:' tag not found"
incr failed
}
if {$function == 0} {
fail "$testname expected 'function:' tag not found"
incr failed
}
if {$lcount == 0} {
fail "$testname expected 'lcount:' tag not found"
incr failed
}
if {$branch == 0} {
fail "$testname expected 'branch:' tag not found"
incr failed
}
close $fd
return $failed
}
#
# verify-branches -- check that branch percentages are as expected
#
# TESTNAME is the name of the test, including unique flags.
......
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