public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 0/3] Condition coverage docs, bugfix
@ 2024-06-25  8:03 Jørgen Kvalsvik
  2024-06-25  8:03 ` [PATCH 1/3] Release structures on function return Jørgen Kvalsvik
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Jørgen Kvalsvik @ 2024-06-25  8:03 UTC (permalink / raw)
  To: gcc-patches; +Cc: hubicka, Jørgen Kvalsvik


This patch set includes a memory leak fix and some documentation
additions for condition coverage. Without prior knowledge it would be
hard to find out what exactly gcc/gcov means by "condition coverage",
so I fleshed it out and made sure to include some searchable keywords --
masking, MC/DC. The flags leave room for other condition coverage
flavors, and relies on docs to make it clear.

Jørgen Kvalsvik (3):
  Release structures on function return
  Add section on MC/DC in gcov manual
  Use the term MC/DC in help for gcov --conditions

 gcc/doc/gcov.texi   | 72 +++++++++++++++++++++++++++++++++++++++++++++
 gcc/gcov.cc         |  2 +-
 gcc/tree-profile.cc |  3 ++
 3 files changed, 76 insertions(+), 1 deletion(-)

-- 
2.39.2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 1/3] Release structures on function return
  2024-06-25  8:03 [PATCH 0/3] Condition coverage docs, bugfix Jørgen Kvalsvik
@ 2024-06-25  8:03 ` Jørgen Kvalsvik
  2024-06-25 10:23   ` Jan Hubicka
  2024-06-25  8:03 ` [PATCH 2/3] Add section on MC/DC in gcov manual Jørgen Kvalsvik
  2024-06-25  8:03 ` [PATCH 3/3] Use the term MC/DC in help for gcov --conditions Jørgen Kvalsvik
  2 siblings, 1 reply; 13+ messages in thread
From: Jørgen Kvalsvik @ 2024-06-25  8:03 UTC (permalink / raw)
  To: gcc-patches; +Cc: hubicka, Jørgen Kvalsvik

The value vec objects are destroyed on exit, but release still needs to
be called explicitly.

gcc/ChangeLog:

	* tree-profile.cc (find_conditions): Release vectors before
	  return.
---
 gcc/tree-profile.cc | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gcc/tree-profile.cc b/gcc/tree-profile.cc
index e4bb689cef5..18f48e8d04e 100644
--- a/gcc/tree-profile.cc
+++ b/gcc/tree-profile.cc
@@ -919,6 +919,9 @@ find_conditions (struct function *fn)
     if (!have_post_dom)
 	free_dominance_info (fn, CDI_POST_DOMINATORS);
 
+    for (auto expr : exprs)
+      expr.second.release ();
+
     cov->m_masks.safe_grow_cleared (2 * cov->m_index.last ());
     const size_t length = cov_length (cov);
     for (size_t i = 0; i != length; i++)
-- 
2.39.2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 2/3] Add section on MC/DC in gcov manual
  2024-06-25  8:03 [PATCH 0/3] Condition coverage docs, bugfix Jørgen Kvalsvik
  2024-06-25  8:03 ` [PATCH 1/3] Release structures on function return Jørgen Kvalsvik
@ 2024-06-25  8:03 ` Jørgen Kvalsvik
  2024-06-25 10:23   ` Jan Hubicka
  2024-06-25  8:03 ` [PATCH 3/3] Use the term MC/DC in help for gcov --conditions Jørgen Kvalsvik
  2 siblings, 1 reply; 13+ messages in thread
From: Jørgen Kvalsvik @ 2024-06-25  8:03 UTC (permalink / raw)
  To: gcc-patches; +Cc: hubicka, Jørgen Kvalsvik

gcc/ChangeLog:

	* doc/gcov.texi: Add MC/DC section.
---
 gcc/doc/gcov.texi | 72 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)

diff --git a/gcc/doc/gcov.texi b/gcc/doc/gcov.texi
index dc79bccb8cf..a9221738cce 100644
--- a/gcc/doc/gcov.texi
+++ b/gcc/doc/gcov.texi
@@ -917,6 +917,78 @@ of times the call was executed will be printed.  This will usually be
 100%, but may be less for functions that call @code{exit} or @code{longjmp},
 and thus may not return every time they are called.
 
+When you use the @option{-g} option, your output looks like this:
+
+@smallexample
+$ gcov -t -m -g tmp
+        -:    0:Source:tmp.cpp
+        -:    0:Graph:tmp.gcno
+        -:    0:Data:tmp.gcda
+        -:    0:Runs:1
+        -:    1:#include <stdio.h>
+        -:    2:
+        -:    3:int
+        1:    4:main (void)
+        -:    5:@{
+        -:    6:  int i, total;
+        1:    7:  total = 0;
+        -:    8:
+       11:    9:  for (i = 0; i < 10; i++)
+condition outcomes covered 2/2
+       10:   10:    total += i;
+        -:   11:
+       1*:   12:  int v = total > 100 ? 1 : 2;
+condition outcomes covered 1/2
+condition  0 not covered (true)
+        -:   13:
+       1*:   14:  if (total != 45 && v == 1)
+condition outcomes covered 1/4
+condition  0 not covered (true)
+condition  1 not covered (true false)
+    #####:   15:    printf ("Failure\n");
+        -:   16:  else
+        1:   17:    printf ("Success\n");
+        1:   18:  return 0;
+        -:   19:@}
+@end smallexample
+
+For every condition the number of taken and total outcomes are
+printed, and if there are uncovered outcomes a line will be printed
+for each condition showing the uncovered outcome in parentheses.
+Conditions are identified by their index -- index 0 is the left-most
+condition.  In @code{a || (b && c)}, @var{a} is condition 0, @var{b}
+condition 1, and @var{c} condition 2.
+
+An outcome is considered covered if it has an independent effect on
+the decision, also known as masking MC/DC (Modified Condition/Decision
+Coverage).  In this example the decision evaluates to true and @var{a}
+is evaluated, but not covered.  This is because @var{a} cannot affect
+the decision independently -- both @var{a} and @var{b} must change
+value for the decision to change.
+
+@smallexample
+$ gcov -t -m -g tmp
+        -:    0:Source:tmp.c
+        -:    0:Graph:tmp.gcno
+        -:    0:Data:tmp.gcda
+        -:    0:Runs:1
+        -:    1:#include <stdio.h>
+        -:    2:
+        1:    3:int main()
+        -:    4:@{
+        1:    5:  int a = 1;
+        1:    6:  int b = 0;
+        -:    7:
+        1:    8:  if (a && b)
+condition outcomes covered 1/4
+condition  0 not covered (true false)
+condition  1 not covered (true)
+    #####:    9:    printf ("Success!\n");
+        -:   10:  else
+        1:   11:    printf ("Failure!\n");
+        -:   12:@}
+@end smallexample
+
 The execution counts are cumulative.  If the example program were
 executed again without removing the @file{.gcda} file, the count for the
 number of times each line in the source was executed would be added to
-- 
2.39.2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 3/3] Use the term MC/DC in help for gcov --conditions
  2024-06-25  8:03 [PATCH 0/3] Condition coverage docs, bugfix Jørgen Kvalsvik
  2024-06-25  8:03 ` [PATCH 1/3] Release structures on function return Jørgen Kvalsvik
  2024-06-25  8:03 ` [PATCH 2/3] Add section on MC/DC in gcov manual Jørgen Kvalsvik
@ 2024-06-25  8:03 ` Jørgen Kvalsvik
  2024-06-25 10:25   ` Jan Hubicka
  2 siblings, 1 reply; 13+ messages in thread
From: Jørgen Kvalsvik @ 2024-06-25  8:03 UTC (permalink / raw)
  To: gcc-patches; +Cc: hubicka, Jørgen Kvalsvik

Without key terms like "masking" and "MC/DC" it is not at all obvious
what --conditions actually reports on, and there is no easy path for the
user to figure out. By at least including the two key terms MC/DC and
masking users have something to search for.

gcc/ChangeLog:

        * gcov.cc (print_usage): Reference masking MC/DC.
---
 gcc/gcov.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/gcov.cc b/gcc/gcov.cc
index f6787f0be8f..1e2e193d79d 100644
--- a/gcc/gcov.cc
+++ b/gcc/gcov.cc
@@ -1015,7 +1015,7 @@ print_usage (int error_p)
   fnotice (file, "  -c, --branch-counts             Output counts of branches taken\n\
                                     rather than percentages\n");
   fnotice (file, "  -g, --conditions                Include modified condition/decision\n\
-                                    coverage in output\n");
+                                    coverage (masking MC/DC) in output\n");
   fnotice (file, "  -d, --display-progress          Display progress information\n");
   fnotice (file, "  -D, --debug			    Display debugging dumps\n");
   fnotice (file, "  -f, --function-summaries        Output summaries for each function\n");
-- 
2.39.2


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/3] Release structures on function return
  2024-06-25  8:03 ` [PATCH 1/3] Release structures on function return Jørgen Kvalsvik
@ 2024-06-25 10:23   ` Jan Hubicka
  2024-06-25 10:37     ` Jørgen Kvalsvik
                       ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Jan Hubicka @ 2024-06-25 10:23 UTC (permalink / raw)
  To: Jørgen Kvalsvik; +Cc: gcc-patches

> The value vec objects are destroyed on exit, but release still needs to
> be called explicitly.
> 
> gcc/ChangeLog:
> 
> 	* tree-profile.cc (find_conditions): Release vectors before
> 	  return.
I wonder if you turn
    hash_map<int_hash<unsigned, 0>, vec<basic_block>> exprs;
to
    hash_map<int_hash<unsigned, 0>, auto_vec<basic_block>> exprs;
Won't hash_map destructor take care of this by itself?

Honza
> ---
>  gcc/tree-profile.cc | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/gcc/tree-profile.cc b/gcc/tree-profile.cc
> index e4bb689cef5..18f48e8d04e 100644
> --- a/gcc/tree-profile.cc
> +++ b/gcc/tree-profile.cc
> @@ -919,6 +919,9 @@ find_conditions (struct function *fn)
>      if (!have_post_dom)
>  	free_dominance_info (fn, CDI_POST_DOMINATORS);
>  
> +    for (auto expr : exprs)
> +      expr.second.release ();
> +
>      cov->m_masks.safe_grow_cleared (2 * cov->m_index.last ());
>      const size_t length = cov_length (cov);
>      for (size_t i = 0; i != length; i++)
> -- 
> 2.39.2
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/3] Add section on MC/DC in gcov manual
  2024-06-25  8:03 ` [PATCH 2/3] Add section on MC/DC in gcov manual Jørgen Kvalsvik
@ 2024-06-25 10:23   ` Jan Hubicka
  2024-06-26 10:21     ` Jørgen Kvalsvik
  0 siblings, 1 reply; 13+ messages in thread
From: Jan Hubicka @ 2024-06-25 10:23 UTC (permalink / raw)
  To: Jørgen Kvalsvik; +Cc: gcc-patches

> gcc/ChangeLog:
> 
> 	* doc/gcov.texi: Add MC/DC section.
OK,
thanks!
Honza
> ---
>  gcc/doc/gcov.texi | 72 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 72 insertions(+)
> 
> diff --git a/gcc/doc/gcov.texi b/gcc/doc/gcov.texi
> index dc79bccb8cf..a9221738cce 100644
> --- a/gcc/doc/gcov.texi
> +++ b/gcc/doc/gcov.texi
> @@ -917,6 +917,78 @@ of times the call was executed will be printed.  This will usually be
>  100%, but may be less for functions that call @code{exit} or @code{longjmp},
>  and thus may not return every time they are called.
>  
> +When you use the @option{-g} option, your output looks like this:
> +
> +@smallexample
> +$ gcov -t -m -g tmp
> +        -:    0:Source:tmp.cpp
> +        -:    0:Graph:tmp.gcno
> +        -:    0:Data:tmp.gcda
> +        -:    0:Runs:1
> +        -:    1:#include <stdio.h>
> +        -:    2:
> +        -:    3:int
> +        1:    4:main (void)
> +        -:    5:@{
> +        -:    6:  int i, total;
> +        1:    7:  total = 0;
> +        -:    8:
> +       11:    9:  for (i = 0; i < 10; i++)
> +condition outcomes covered 2/2
> +       10:   10:    total += i;
> +        -:   11:
> +       1*:   12:  int v = total > 100 ? 1 : 2;
> +condition outcomes covered 1/2
> +condition  0 not covered (true)
> +        -:   13:
> +       1*:   14:  if (total != 45 && v == 1)
> +condition outcomes covered 1/4
> +condition  0 not covered (true)
> +condition  1 not covered (true false)
> +    #####:   15:    printf ("Failure\n");
> +        -:   16:  else
> +        1:   17:    printf ("Success\n");
> +        1:   18:  return 0;
> +        -:   19:@}
> +@end smallexample
> +
> +For every condition the number of taken and total outcomes are
> +printed, and if there are uncovered outcomes a line will be printed
> +for each condition showing the uncovered outcome in parentheses.
> +Conditions are identified by their index -- index 0 is the left-most
> +condition.  In @code{a || (b && c)}, @var{a} is condition 0, @var{b}
> +condition 1, and @var{c} condition 2.
> +
> +An outcome is considered covered if it has an independent effect on
> +the decision, also known as masking MC/DC (Modified Condition/Decision
> +Coverage).  In this example the decision evaluates to true and @var{a}
> +is evaluated, but not covered.  This is because @var{a} cannot affect
> +the decision independently -- both @var{a} and @var{b} must change
> +value for the decision to change.
> +
> +@smallexample
> +$ gcov -t -m -g tmp
> +        -:    0:Source:tmp.c
> +        -:    0:Graph:tmp.gcno
> +        -:    0:Data:tmp.gcda
> +        -:    0:Runs:1
> +        -:    1:#include <stdio.h>
> +        -:    2:
> +        1:    3:int main()
> +        -:    4:@{
> +        1:    5:  int a = 1;
> +        1:    6:  int b = 0;
> +        -:    7:
> +        1:    8:  if (a && b)
> +condition outcomes covered 1/4
> +condition  0 not covered (true false)
> +condition  1 not covered (true)
> +    #####:    9:    printf ("Success!\n");
> +        -:   10:  else
> +        1:   11:    printf ("Failure!\n");
> +        -:   12:@}
> +@end smallexample
> +
>  The execution counts are cumulative.  If the example program were
>  executed again without removing the @file{.gcda} file, the count for the
>  number of times each line in the source was executed would be added to
> -- 
> 2.39.2
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 3/3] Use the term MC/DC in help for gcov --conditions
  2024-06-25  8:03 ` [PATCH 3/3] Use the term MC/DC in help for gcov --conditions Jørgen Kvalsvik
@ 2024-06-25 10:25   ` Jan Hubicka
  2024-06-25 10:42     ` Jørgen Kvalsvik
  2024-06-26 10:21     ` Jørgen Kvalsvik
  0 siblings, 2 replies; 13+ messages in thread
From: Jan Hubicka @ 2024-06-25 10:25 UTC (permalink / raw)
  To: Jørgen Kvalsvik; +Cc: gcc-patches

> Without key terms like "masking" and "MC/DC" it is not at all obvious
> what --conditions actually reports on, and there is no easy path for the
> user to figure out. By at least including the two key terms MC/DC and
> masking users have something to search for.
> 
> gcc/ChangeLog:
> 
>         * gcov.cc (print_usage): Reference masking MC/DC.

So the main purpose is to turn users into masking MC/DC description in
the manual?  Asking google does not seem to do the trick so far, but
I don't know if better options.

OK,
Thanks
> ---
>  gcc/gcov.cc | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/gcc/gcov.cc b/gcc/gcov.cc
> index f6787f0be8f..1e2e193d79d 100644
> --- a/gcc/gcov.cc
> +++ b/gcc/gcov.cc
> @@ -1015,7 +1015,7 @@ print_usage (int error_p)
>    fnotice (file, "  -c, --branch-counts             Output counts of branches taken\n\
>                                      rather than percentages\n");
>    fnotice (file, "  -g, --conditions                Include modified condition/decision\n\
> -                                    coverage in output\n");
> +                                    coverage (masking MC/DC) in output\n");
>    fnotice (file, "  -d, --display-progress          Display progress information\n");
>    fnotice (file, "  -D, --debug			    Display debugging dumps\n");
>    fnotice (file, "  -f, --function-summaries        Output summaries for each function\n");
> -- 
> 2.39.2
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/3] Release structures on function return
  2024-06-25 10:23   ` Jan Hubicka
@ 2024-06-25 10:37     ` Jørgen Kvalsvik
  2024-06-26 10:20     ` Jørgen Kvalsvik
  2024-06-27  6:26     ` Jørgen Kvalsvik
  2 siblings, 0 replies; 13+ messages in thread
From: Jørgen Kvalsvik @ 2024-06-25 10:37 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches

On 6/25/24 12:23, Jan Hubicka wrote:
>> The value vec objects are destroyed on exit, but release still needs to
>> be called explicitly.
>>
>> gcc/ChangeLog:
>>
>> 	* tree-profile.cc (find_conditions): Release vectors before
>> 	  return.
> I wonder if you turn
>      hash_map<int_hash<unsigned, 0>, vec<basic_block>> exprs;
> to
>      hash_map<int_hash<unsigned, 0>, auto_vec<basic_block>> exprs;
> Won't hash_map destructor take care of this by itself?

It does, actually - I think I tried something to that effect at one 
point and the auto_vec's non-copy semantics got in the way. Apparently I 
either misremember trying, or I did something differently at the time. 
auto_vec is much nicer, of course, I'll update the patch. Thanks!

> 
> Honza
>> ---
>>   gcc/tree-profile.cc | 3 +++
>>   1 file changed, 3 insertions(+)
>>
>> diff --git a/gcc/tree-profile.cc b/gcc/tree-profile.cc
>> index e4bb689cef5..18f48e8d04e 100644
>> --- a/gcc/tree-profile.cc
>> +++ b/gcc/tree-profile.cc
>> @@ -919,6 +919,9 @@ find_conditions (struct function *fn)
>>       if (!have_post_dom)
>>   	free_dominance_info (fn, CDI_POST_DOMINATORS);
>>   
>> +    for (auto expr : exprs)
>> +      expr.second.release ();
>> +
>>       cov->m_masks.safe_grow_cleared (2 * cov->m_index.last ());
>>       const size_t length = cov_length (cov);
>>       for (size_t i = 0; i != length; i++)
>> -- 
>> 2.39.2
>>


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 3/3] Use the term MC/DC in help for gcov --conditions
  2024-06-25 10:25   ` Jan Hubicka
@ 2024-06-25 10:42     ` Jørgen Kvalsvik
  2024-06-26 10:21     ` Jørgen Kvalsvik
  1 sibling, 0 replies; 13+ messages in thread
From: Jørgen Kvalsvik @ 2024-06-25 10:42 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches

On 6/25/24 12:25, Jan Hubicka wrote:
>> Without key terms like "masking" and "MC/DC" it is not at all obvious
>> what --conditions actually reports on, and there is no easy path for the
>> user to figure out. By at least including the two key terms MC/DC and
>> masking users have something to search for.
>>
>> gcc/ChangeLog:
>>
>>          * gcov.cc (print_usage): Reference masking MC/DC.
> 
> So the main purpose is to turn users into masking MC/DC description in
> the manual?  Asking google does not seem to do the trick so far, but
> I don't know if better options.

Either in the manual (which has a very brief example), or into google to 
find random blog posts or papers like An Investigation of Three Forms of 
the Modified Condition Decision Coverage (MCDC) Criterion by Chilenski 
(2001) and 
https://ntrs.nasa.gov/api/citations/20040086014/downloads/20040086014.pdf 
(a tutorial on MC/DC by Hayhurst et al). Granted, the web is a bit 
sparse on anything beyond trivial (and usually quietly unique cause) 
MC/DC examples, but I'm not sure if the gcc/gcov manual is the home for it.

Thanks,
Jørgen

> 
> OK,
> Thanks
>> ---
>>   gcc/gcov.cc | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/gcc/gcov.cc b/gcc/gcov.cc
>> index f6787f0be8f..1e2e193d79d 100644
>> --- a/gcc/gcov.cc
>> +++ b/gcc/gcov.cc
>> @@ -1015,7 +1015,7 @@ print_usage (int error_p)
>>     fnotice (file, "  -c, --branch-counts             Output counts of branches taken\n\
>>                                       rather than percentages\n");
>>     fnotice (file, "  -g, --conditions                Include modified condition/decision\n\
>> -                                    coverage in output\n");
>> +                                    coverage (masking MC/DC) in output\n");
>>     fnotice (file, "  -d, --display-progress          Display progress information\n");
>>     fnotice (file, "  -D, --debug			    Display debugging dumps\n");
>>     fnotice (file, "  -f, --function-summaries        Output summaries for each function\n");
>> -- 
>> 2.39.2
>>


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/3] Release structures on function return
  2024-06-25 10:23   ` Jan Hubicka
  2024-06-25 10:37     ` Jørgen Kvalsvik
@ 2024-06-26 10:20     ` Jørgen Kvalsvik
  2024-06-27  6:26     ` Jørgen Kvalsvik
  2 siblings, 0 replies; 13+ messages in thread
From: Jørgen Kvalsvik @ 2024-06-26 10:20 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches

On 6/25/24 12:23, Jan Hubicka wrote:
>> The value vec objects are destroyed on exit, but release still needs to
>> be called explicitly.
>>
>> gcc/ChangeLog:
>>
>> 	* tree-profile.cc (find_conditions): Release vectors before
>> 	  return.
> I wonder if you turn
>      hash_map<int_hash<unsigned, 0>, vec<basic_block>> exprs;
> to
>      hash_map<int_hash<unsigned, 0>, auto_vec<basic_block>> exprs;
> Won't hash_map destructor take care of this by itself?
> 
> Honza

I updated this to use auto_vec and pushed it.

Thanks,
Jørgen

>> ---
>>   gcc/tree-profile.cc | 3 +++
>>   1 file changed, 3 insertions(+)
>>
>> diff --git a/gcc/tree-profile.cc b/gcc/tree-profile.cc
>> index e4bb689cef5..18f48e8d04e 100644
>> --- a/gcc/tree-profile.cc
>> +++ b/gcc/tree-profile.cc
>> @@ -919,6 +919,9 @@ find_conditions (struct function *fn)
>>       if (!have_post_dom)
>>   	free_dominance_info (fn, CDI_POST_DOMINATORS);
>>   
>> +    for (auto expr : exprs)
>> +      expr.second.release ();
>> +
>>       cov->m_masks.safe_grow_cleared (2 * cov->m_index.last ());
>>       const size_t length = cov_length (cov);
>>       for (size_t i = 0; i != length; i++)
>> -- 
>> 2.39.2
>>


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/3] Add section on MC/DC in gcov manual
  2024-06-25 10:23   ` Jan Hubicka
@ 2024-06-26 10:21     ` Jørgen Kvalsvik
  0 siblings, 0 replies; 13+ messages in thread
From: Jørgen Kvalsvik @ 2024-06-26 10:21 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches

On 6/25/24 12:23, Jan Hubicka wrote:
>> gcc/ChangeLog:
>>
>> 	* doc/gcov.texi: Add MC/DC section.
> OK,
> thanks!

Pushed.

Thanks,
Jørgen

> Honza
>> ---
>>   gcc/doc/gcov.texi | 72 +++++++++++++++++++++++++++++++++++++++++++++++
>>   1 file changed, 72 insertions(+)
>>
>> diff --git a/gcc/doc/gcov.texi b/gcc/doc/gcov.texi
>> index dc79bccb8cf..a9221738cce 100644
>> --- a/gcc/doc/gcov.texi
>> +++ b/gcc/doc/gcov.texi
>> @@ -917,6 +917,78 @@ of times the call was executed will be printed.  This will usually be
>>   100%, but may be less for functions that call @code{exit} or @code{longjmp},
>>   and thus may not return every time they are called.
>>   
>> +When you use the @option{-g} option, your output looks like this:
>> +
>> +@smallexample
>> +$ gcov -t -m -g tmp
>> +        -:    0:Source:tmp.cpp
>> +        -:    0:Graph:tmp.gcno
>> +        -:    0:Data:tmp.gcda
>> +        -:    0:Runs:1
>> +        -:    1:#include <stdio.h>
>> +        -:    2:
>> +        -:    3:int
>> +        1:    4:main (void)
>> +        -:    5:@{
>> +        -:    6:  int i, total;
>> +        1:    7:  total = 0;
>> +        -:    8:
>> +       11:    9:  for (i = 0; i < 10; i++)
>> +condition outcomes covered 2/2
>> +       10:   10:    total += i;
>> +        -:   11:
>> +       1*:   12:  int v = total > 100 ? 1 : 2;
>> +condition outcomes covered 1/2
>> +condition  0 not covered (true)
>> +        -:   13:
>> +       1*:   14:  if (total != 45 && v == 1)
>> +condition outcomes covered 1/4
>> +condition  0 not covered (true)
>> +condition  1 not covered (true false)
>> +    #####:   15:    printf ("Failure\n");
>> +        -:   16:  else
>> +        1:   17:    printf ("Success\n");
>> +        1:   18:  return 0;
>> +        -:   19:@}
>> +@end smallexample
>> +
>> +For every condition the number of taken and total outcomes are
>> +printed, and if there are uncovered outcomes a line will be printed
>> +for each condition showing the uncovered outcome in parentheses.
>> +Conditions are identified by their index -- index 0 is the left-most
>> +condition.  In @code{a || (b && c)}, @var{a} is condition 0, @var{b}
>> +condition 1, and @var{c} condition 2.
>> +
>> +An outcome is considered covered if it has an independent effect on
>> +the decision, also known as masking MC/DC (Modified Condition/Decision
>> +Coverage).  In this example the decision evaluates to true and @var{a}
>> +is evaluated, but not covered.  This is because @var{a} cannot affect
>> +the decision independently -- both @var{a} and @var{b} must change
>> +value for the decision to change.
>> +
>> +@smallexample
>> +$ gcov -t -m -g tmp
>> +        -:    0:Source:tmp.c
>> +        -:    0:Graph:tmp.gcno
>> +        -:    0:Data:tmp.gcda
>> +        -:    0:Runs:1
>> +        -:    1:#include <stdio.h>
>> +        -:    2:
>> +        1:    3:int main()
>> +        -:    4:@{
>> +        1:    5:  int a = 1;
>> +        1:    6:  int b = 0;
>> +        -:    7:
>> +        1:    8:  if (a && b)
>> +condition outcomes covered 1/4
>> +condition  0 not covered (true false)
>> +condition  1 not covered (true)
>> +    #####:    9:    printf ("Success!\n");
>> +        -:   10:  else
>> +        1:   11:    printf ("Failure!\n");
>> +        -:   12:@}
>> +@end smallexample
>> +
>>   The execution counts are cumulative.  If the example program were
>>   executed again without removing the @file{.gcda} file, the count for the
>>   number of times each line in the source was executed would be added to
>> -- 
>> 2.39.2
>>


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 3/3] Use the term MC/DC in help for gcov --conditions
  2024-06-25 10:25   ` Jan Hubicka
  2024-06-25 10:42     ` Jørgen Kvalsvik
@ 2024-06-26 10:21     ` Jørgen Kvalsvik
  1 sibling, 0 replies; 13+ messages in thread
From: Jørgen Kvalsvik @ 2024-06-26 10:21 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches

On 6/25/24 12:25, Jan Hubicka wrote:
>> Without key terms like "masking" and "MC/DC" it is not at all obvious
>> what --conditions actually reports on, and there is no easy path for the
>> user to figure out. By at least including the two key terms MC/DC and
>> masking users have something to search for.
>>
>> gcc/ChangeLog:
>>
>>          * gcov.cc (print_usage): Reference masking MC/DC.
> 
> So the main purpose is to turn users into masking MC/DC description in
> the manual?  Asking google does not seem to do the trick so far, but
> I don't know if better options.
> 
> OK,
> Thanks

Pushed.

Thanks,
Jørgen

>> ---
>>   gcc/gcov.cc | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/gcc/gcov.cc b/gcc/gcov.cc
>> index f6787f0be8f..1e2e193d79d 100644
>> --- a/gcc/gcov.cc
>> +++ b/gcc/gcov.cc
>> @@ -1015,7 +1015,7 @@ print_usage (int error_p)
>>     fnotice (file, "  -c, --branch-counts             Output counts of branches taken\n\
>>                                       rather than percentages\n");
>>     fnotice (file, "  -g, --conditions                Include modified condition/decision\n\
>> -                                    coverage in output\n");
>> +                                    coverage (masking MC/DC) in output\n");
>>     fnotice (file, "  -d, --display-progress          Display progress information\n");
>>     fnotice (file, "  -D, --debug			    Display debugging dumps\n");
>>     fnotice (file, "  -f, --function-summaries        Output summaries for each function\n");
>> -- 
>> 2.39.2
>>


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/3] Release structures on function return
  2024-06-25 10:23   ` Jan Hubicka
  2024-06-25 10:37     ` Jørgen Kvalsvik
  2024-06-26 10:20     ` Jørgen Kvalsvik
@ 2024-06-27  6:26     ` Jørgen Kvalsvik
  2 siblings, 0 replies; 13+ messages in thread
From: Jørgen Kvalsvik @ 2024-06-27  6:26 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches, linaro-toolchain, gcc-regression

I think we need to revert this.

I got this email from linaro/gcc-regressions:

[Linaro-TCWG-CI] gcc-15-1649-g19f630e6ae8d: FAIL: 2 regressions on aarch64

regressions.sum:
		=== gcc tests ===

Running gcc:gcc.misc-tests/gcov.exp ...
FAIL: gcc.misc-tests/gcov-23.c (internal compiler error: in operator[], 
at vec.h:910)
FAIL: gcc.misc-tests/gcov-23.c (test for excess errors)

This did not reproduce on my machine, but I took a quick look at the 
hash-map implementation. hash_map.put calls 
hash_table.find_slot_with_hash, which calls hash_table.expand, which 
does move+destroy. auto_vec is not really move-aware which leads to a 
double-free.

The fix is either to make auto_vec move-aware (and more like C++'s 
std::vector) or revert this patch and apply the original version with an 
explicit release.

OK?

Thanks,
Jørgen

On 6/25/24 12:23, Jan Hubicka wrote:
>> The value vec objects are destroyed on exit, but release still needs to
>> be called explicitly.
>>
>> gcc/ChangeLog:
>>
>> 	* tree-profile.cc (find_conditions): Release vectors before
>> 	  return.
> I wonder if you turn
>      hash_map<int_hash<unsigned, 0>, vec<basic_block>> exprs;
> to
>      hash_map<int_hash<unsigned, 0>, auto_vec<basic_block>> exprs;
> Won't hash_map destructor take care of this by itself?
> 
> Honza
>> ---
>>   gcc/tree-profile.cc | 3 +++
>>   1 file changed, 3 insertions(+)
>>
>> diff --git a/gcc/tree-profile.cc b/gcc/tree-profile.cc
>> index e4bb689cef5..18f48e8d04e 100644
>> --- a/gcc/tree-profile.cc
>> +++ b/gcc/tree-profile.cc
>> @@ -919,6 +919,9 @@ find_conditions (struct function *fn)
>>       if (!have_post_dom)
>>   	free_dominance_info (fn, CDI_POST_DOMINATORS);
>>   
>> +    for (auto expr : exprs)
>> +      expr.second.release ();
>> +
>>       cov->m_masks.safe_grow_cleared (2 * cov->m_index.last ());
>>       const size_t length = cov_length (cov);
>>       for (size_t i = 0; i != length; i++)
>> -- 
>> 2.39.2
>>


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2024-06-27  6:26 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-06-25  8:03 [PATCH 0/3] Condition coverage docs, bugfix Jørgen Kvalsvik
2024-06-25  8:03 ` [PATCH 1/3] Release structures on function return Jørgen Kvalsvik
2024-06-25 10:23   ` Jan Hubicka
2024-06-25 10:37     ` Jørgen Kvalsvik
2024-06-26 10:20     ` Jørgen Kvalsvik
2024-06-27  6:26     ` Jørgen Kvalsvik
2024-06-25  8:03 ` [PATCH 2/3] Add section on MC/DC in gcov manual Jørgen Kvalsvik
2024-06-25 10:23   ` Jan Hubicka
2024-06-26 10:21     ` Jørgen Kvalsvik
2024-06-25  8:03 ` [PATCH 3/3] Use the term MC/DC in help for gcov --conditions Jørgen Kvalsvik
2024-06-25 10:25   ` Jan Hubicka
2024-06-25 10:42     ` Jørgen Kvalsvik
2024-06-26 10:21     ` Jørgen Kvalsvik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).