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> 2018-10-29 Segher Boessenkool <segher@kernel.crashing.org>
PR rtl-optimization/87701 PR rtl-optimization/87701
...@@ -2899,10 +2899,13 @@ s-iov: build/gcov-iov$(build_exeext) $(BASEVER) $(DEVPHASE) ...@@ -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 $(SHELL) $(srcdir)/../move-if-change tmp-gcov-iov.h gcov-iov.h
$(STAMP) s-iov $(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) gcov$(exeext): $(GCOV_OBJS) $(LIBDEPS)
+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) $(GCOV_OBJS) \ +$(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_OBJS = gcov-dump.o
gcov-dump$(exeext): $(GCOV_DUMP_OBJS) $(LIBDEPS) gcov-dump$(exeext): $(GCOV_DUMP_OBJS) $(LIBDEPS)
+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) $(GCOV_DUMP_OBJS) \ +$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) $(GCOV_DUMP_OBJS) \
......
...@@ -124,7 +124,7 @@ gcov [@option{-v}|@option{--version}] [@option{-h}|@option{--help}] ...@@ -124,7 +124,7 @@ gcov [@option{-v}|@option{--version}] [@option{-h}|@option{--help}]
[@option{-c}|@option{--branch-counts}] [@option{-c}|@option{--branch-counts}]
[@option{-d}|@option{--display-progress}] [@option{-d}|@option{--display-progress}]
[@option{-f}|@option{--function-summaries}] [@option{-f}|@option{--function-summaries}]
[@option{-i}|@option{--intermediate-format}] [@option{-i}|@option{--json-format}]
[@option{-j}|@option{--human-readable}] [@option{-j}|@option{--human-readable}]
[@option{-k}|@option{--use-colors}] [@option{-k}|@option{--use-colors}]
[@option{-l}|@option{--long-file-names}] [@option{-l}|@option{--long-file-names}]
...@@ -181,79 +181,142 @@ Display help about using @command{gcov} (on the standard output), and ...@@ -181,79 +181,142 @@ Display help about using @command{gcov} (on the standard output), and
exit without doing any further processing. exit without doing any further processing.
@item -i @item -i
@itemx --intermediate-format @itemx --json-format
Output gcov file in an easy-to-parse intermediate text format that can Output gcov file in an easy-to-parse JSON intermediate format
be used by @command{lcov} or other tools. The output is a single which does not require source code for generation. The JSON
@file{.gcov} file per @file{.gcda} file. No source code is required. 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 Structure of the JSON is following:
one entry per line
@smallexample @smallexample
version:@var{gcc_version} @{
cwd:@var{working_directory} "current_working_directory": @var{current_working_directory},
file:@var{source_file_name} "format_version": @var{format_version},
function:@var{start_line_number},@var{end_line_number},@var{execution_count},@var{function_name} "gcc_version": @var{gcc_version}
lcount:@var{line number},@var{execution_count},@var{has_unexecuted_block} "files": [@var{file}]
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)
@end smallexample @end smallexample
There can be multiple @var{file} entries in an intermediate gcov Fields of the root element have following semantics:
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.
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 @smallexample
version: 8.1.0 20180103 @{
cwd:/home/gcc/testcase "count": @var{count},
file:tmp.cpp "fallthrough": @var{fallthrough},
function:7,7,0,_ZN3FooIcEC2Ev "throw": @var{throw}
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
@end smallexample @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 @item -j
@itemx --human-readable @itemx --human-readable
Write counts in human readable format (like 24.6k). Write counts in human readable format (like 24.6k).
...@@ -842,7 +905,7 @@ some summary information. ...@@ -842,7 +905,7 @@ some summary information.
It is not recommended to access the coverage files directly. It is not recommended to access the coverage files directly.
Consumers should use the intermediate format that is provided 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 @node Cross-profiling
@section Data File Relocation to Support Cross-Profiling @section Data File Relocation to Support Cross-Profiling
......
...@@ -296,6 +296,9 @@ test_writing_literals () ...@@ -296,6 +296,9 @@ test_writing_literals ()
assert_print_eq (literal (JSON_TRUE), "true"); assert_print_eq (literal (JSON_TRUE), "true");
assert_print_eq (literal (JSON_FALSE), "false"); assert_print_eq (literal (JSON_FALSE), "false");
assert_print_eq (literal (JSON_NULL), "null"); 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. */ /* Run all of the selftests within this file. */
......
...@@ -154,6 +154,9 @@ class literal : public value ...@@ -154,6 +154,9 @@ class literal : public value
public: public:
literal (enum kind kind) : m_kind (kind) {} 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; } enum kind get_kind () const FINAL OVERRIDE { return m_kind; }
void print (pretty_printer *pp) const FINAL OVERRIDE; 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> 2018-10-28 Kugan Vivekanandarajah <kuganv@linaro.org>
* gcc.dg/gimplefe-30.c: New test. * 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-options "-fprofile-arcs -ftest-coverage" } */
/* { dg-do run { target native } } */ /* { dg-do run { target native } } */
...@@ -32,4 +30,4 @@ int main() ...@@ -32,4 +30,4 @@ int main()
foo(); 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 } { ...@@ -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 # verify-branches -- check that branch percentages are as expected
# #
# TESTNAME is the name of the test, including unique flags. # 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