From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from nikam.ms.mff.cuni.cz (nikam.ms.mff.cuni.cz [195.113.20.16]) by sourceware.org (Postfix) with ESMTPS id 3D33C3858D32 for ; Fri, 14 Apr 2023 12:34:24 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 3D33C3858D32 Authentication-Results: sourceware.org; dmarc=fail (p=none dis=none) header.from=ucw.cz Authentication-Results: sourceware.org; spf=none smtp.mailfrom=kam.mff.cuni.cz Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id E724B28A6EC; Fri, 14 Apr 2023 14:34:22 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ucw.cz; s=gen1; t=1681475662; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/ZWyeRs3ADyDPFCLFn68j8Z/xLEJa6z94Yk+LupV61w=; b=lCBT7GzWU07Wuef7GQyZ/qK8xwCNU2ZA0Cvr7tZKvgC2bC5JX4Y2/ejvI4hLv52ecvbfd7 InxbDs4ev80vWdtBSTAa4fkHhmmG8fOabD91g4GWhmJTviC0zPMfNEJOlf3zu53UoyFGqc ufJIJO/cNS4cf/HqKiqLODOSoaCCGM4= Date: Fri, 14 Apr 2023 14:34:22 +0200 From: Jan Hubicka To: Martin =?iso-8859-2?Q?Li=B9ka?= Cc: Richard Biener , gcc-patches@gcc.gnu.org Subject: Re: [PATCH] gcov: add info about "calls" to JSON output format Message-ID: References: <3041a27a-8599-23da-237b-d802f83c40ae@suse.cz> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: X-Spam-Status: No, score=-11.1 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,GIT_PATCH_0,HEADER_FROM_DIFFERENT_DOMAINS,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_NONE,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: > On 4/11/23 11:23, Richard Biener wrote: > > On Thu, Apr 6, 2023 at 3:58 PM Martin Liška wrote: > >> > >> Patch can bootstrap on x86_64-linux-gnu and survives regression tests. > >> > >> Ready to be installed after stage1 opens? > > > > Did we release a compiler with version 1? If not we might want to sneak > > Yes, all compilers starting with 9.1 emit version 1. > > > this in before 13.1 ... > > Yep, I would welcome sneaking in. > > > > > Up to Honza. > > PING: Honza! THe motivation is for external tools to effectively track execution counts after function calls that does not return normally? What about other cases we produce fake edges for, like trapping statements or volatile asms (via stmt_can_terminate_bb_p). Are those handled as branches with "throw" flag? Calls not returning is just one of special cases where control of function may terminate. Also do we want to handle function returning twice (fork and setjmp?) Patch looks OK. Honza > > Thanks, > Martin > > > > > Thanks, > > Richard. > > > >> Thanks, > >> Martin > >> > >> gcc/ChangeLog: > >> > >> * doc/gcov.texi: Document the new "calls" field and document > >> the API bump. > >> * gcov.cc (output_intermediate_json_line): Output info about > >> calls. > >> (generate_results): Bump version to 2. > >> > >> 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. > >> --- > >> gcc/doc/gcov.texi | 27 +++++++++++++++++++++-- > >> gcc/gcov.cc | 12 +++++++++- > >> gcc/testsuite/g++.dg/gcov/gcov-17.C | 7 ++++++ > >> gcc/testsuite/g++.dg/gcov/test-gcov-17.py | 17 ++++++++++---- > >> gcc/testsuite/lib/gcov.exp | 2 +- > >> 5 files changed, 57 insertions(+), 8 deletions(-) > >> > >> diff --git a/gcc/doc/gcov.texi b/gcc/doc/gcov.texi > >> index d39cce3a683..6739ebb3643 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 > >> @@ -292,6 +298,7 @@ Each @var{line} has the following form: > >> @smallexample > >> @{ > >> "branches": ["$branch"], > >> + "calls": ["$call"], > >> "count": 2, > >> "line_number": 15, > >> "unexecuted_block": false, > >> @@ -299,7 +306,7 @@ 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 > >> @@ -341,6 +348,22 @@ Fields of the @var{branch} element have following semantics: > >> @var{throw}: true when the branch is an exceptional branch > >> @end itemize > >> > >> +Each @var{call} has the following form: > >> + > >> +@smallexample > >> +@{ > >> + "returned": 11, > >> +@} > >> +@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}) > >> +@end itemize > >> + > >> @item -H > >> @itemx --human-readable > >> Write counts in human readable format (like 24.6k). > >> diff --git a/gcc/gcov.cc b/gcc/gcov.cc > >> index 2ec7248cc0e..88324143640 100644 > >> --- a/gcc/gcov.cc > >> +++ b/gcc/gcov.cc > >> @@ -1116,6 +1116,9 @@ output_intermediate_json_line (json::array *object, > >> json::array *branches = new json::array (); > >> lineo->set ("branches", branches); > >> > >> + json::array *calls = new json::array (); > >> + lineo->set ("calls", calls); > >> + > >> vector::const_iterator it; > >> if (flag_branches) > >> for (it = line->branches.begin (); it != line->branches.end (); > >> @@ -1130,6 +1133,13 @@ output_intermediate_json_line (json::array *object, > >> new json::literal ((*it)->fall_through)); > >> 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 ("returned", new json::integer_number (returns)); > >> + calls->append (call); > >> + } > >> } > >> > >> object->append (lineo); > >> @@ -1523,7 +1533,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) > >> diff --git a/gcc/testsuite/g++.dg/gcov/gcov-17.C b/gcc/testsuite/g++.dg/gcov/gcov-17.C > >> index d11883cfd39..efe019599a5 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; > >> template class Foo; > >> > >> +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 ec5df3dec03..a0b8b09b85c 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,16 @@ 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'] == [{'returned': 1}] > >> + > >> + line43 = linesdict[43][0] > >> + assert line43['count'] == 1 > >> + assert line43['calls'] == [{'returned': 0}] > >> diff --git a/gcc/testsuite/lib/gcov.exp b/gcc/testsuite/lib/gcov.exp > >> index 80e74aeb220..e5e94fa5a76 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] } { > >> -- > >> 2.40.0 > >> >