|
|
|
# Introduction
|
|
|
|
|
|
|
|
`gcov` is a tool that counts how often each lines is executed. This is useful
|
|
|
|
to uncover complexity issues.
|
|
|
|
|
|
|
|
# Compilation
|
|
|
|
|
|
|
|
First compile with coverage enabled.
|
|
|
|
|
|
|
|
````
|
|
|
|
mkdir build_c
|
|
|
|
cd build_c
|
|
|
|
cmake -DGCOV=ON .. && make -j10
|
|
|
|
```
|
|
|
|
|
|
|
|
Now remove all reports: after all we are not interested in the results
|
|
|
|
from compiling the preludes. Do this after all programs you tested.
|
|
|
|
|
|
|
|
```
|
|
|
|
find -name \*gcda -exec rm {} \;
|
|
|
|
```
|
|
|
|
|
|
|
|
# Common issues and solutions
|
|
|
|
|
|
|
|
1. Building a linked list with append instead of prepend. This has quadratic
|
|
|
|
behaviour. Consider prepending if the order does not matter (e.g. with
|
|
|
|
variable declarations), or storing the end of your linked list.
|
|
|
|
2. Searching in linked lists, e.g.
|
|
|
|
```
|
|
|
|
node *n = ...;
|
|
|
|
while (!condition(n)) {
|
|
|
|
n = ..._NEXT(n);
|
|
|
|
}
|
|
|
|
return n;
|
|
|
|
```
|
|
|
|
Consider creating a lookup table.
|
|
|
|
|
|
|
|
# Example
|
|
|
|
|
|
|
|
To be safe, we again delete all gcda files
|
|
|
|
|
|
|
|
```
|
|
|
|
find -name \*gcda -exec rm {} \;
|
|
|
|
```
|
|
|
|
|
|
|
|
## Houston we have a problem!
|
|
|
|
|
|
|
|
```
|
|
|
|
gcov $(find -name tree_compound.c.o)
|
|
|
|
vi tree_compound.c.gcov
|
|
|
|
```
|
|
|
|
|
|
|
|
-: 703:node *
|
|
|
|
6309: 704:TCappendArgs (node *arg_chain, node *arg)
|
|
|
|
-: 705:{
|
|
|
|
-: 706: node *ret;
|
|
|
|
-: 707:
|
|
|
|
6309: 708: DBUG_ENTER ();
|
|
|
|
-: 709:
|
|
|
|
6309*: 710: DBUG_ASSERT (((arg_chain == NULL) || (NODE_TYPE (arg_chain) == N_arg)),
|
|
|
|
-: 711: "First argument of TCappendArgs() has wrong node type.");
|
|
|
|
6309*: 712: DBUG_ASSERT (((arg == NULL) || (NODE_TYPE (arg) == N_arg)),
|
|
|
|
-: 713: "Second argument of TCappendArgs() has wrong node type.");
|
|
|
|
-: 714:
|
|
|
|
53555: 715: APPEND (ret, node *, ARG, arg_chain, arg);
|
|
|
|
-: 716:
|
|
|
|
6309: 717: DBUG_RETURN (ret);
|
|
|
|
-: 718:}
|
|
|
|
|
|
|
|
Call `gcov` on all files using `TCappendArgs`.
|
|
|
|
|
|
|
|
```
|
|
|
|
grep -l TCappendArgs -r ../src | xargs -n1 basename | sed 's/$/\.o/g' | xargs -n1 find -name | xargs -n1 gcov
|
|
|
|
```
|
|
|
|
|
|
|
|
Filter out the files where `TCappendArgs` was never executed:
|
|
|
|
|
|
|
|
```
|
|
|
|
grep TCappendArgs *gcov | grep -v \# | grep -v " -"
|
|
|
|
```
|
|
|
|
|
|
|
|
This outputs
|
|
|
|
|
|
|
|
```
|
|
|
|
eliminate_duplicate_fundef_args.c.gcov: 5563: 172: newargs = TCappendArgs (newargs, arg_node);
|
|
|
|
emr_loop_optimisation.c.gcov: 2: 421: = TCappendArgs (INFO_ARGS (arg_info),
|
|
|
|
emr_loop_optimisation.c.gcov: 1: 531: = TCappendArgs (FUNDEF_ARGS (arg_node), INFO_ARGS (arg_info));
|
|
|
|
loop_scalarization.c.gcov: 168: 400: DBUG_RETURN (TCappendArgs (new_args, old_args));
|
|
|
|
tree_compound.c.gcov: 6309: 704:TCappendArgs (node *arg_chain, node *arg)
|
|
|
|
wlpropagation.c.gcov: 465: 239: = TCappendArgs (INFO_NEWLACFUNARGS (arg_info), copy);
|
|
|
|
wlpropagation.c.gcov: 110: 493: = TCappendArgs (INFO_NEWLACFUNARGS (arg_info),
|
|
|
|
```
|
|
|
|
|
|
|
|
We fix the quadratic behaviour (see merge request 325) and end up with
|
|
|
|
|
|
|
|
```
|
|
|
|
-: 703:node *
|
|
|
|
171: 704:TCappendArgs (node *arg_chain, node *arg)
|
|
|
|
-: 705:{
|
|
|
|
-: 706: node *ret;
|
|
|
|
-: 707:
|
|
|
|
171: 708: DBUG_ENTER ();
|
|
|
|
-: 709:
|
|
|
|
171*: 710: DBUG_ASSERT (((arg_chain == NULL) || (NODE_TYPE (arg_chain) == N_arg)),
|
|
|
|
-: 711: "First argument of TCappendArgs() has wrong node type.");
|
|
|
|
171*: 712: DBUG_ASSERT (((arg == NULL) || (NODE_TYPE (arg) == N_arg)),
|
|
|
|
-: 713: "Second argument of TCappendArgs() has wrong node type.");
|
|
|
|
-: 714:
|
|
|
|
313: 715: APPEND (ret, node *, ARG, arg_chain, arg);
|
|
|
|
-: 716:
|
|
|
|
171: 717: DBUG_RETURN (ret);
|
|
|
|
``` |