xref: /netbsd-src/external/gpl3/gcc.old/dist/contrib/jit-coverage-report.py (revision 1debfc3d3fad8af6f31804271c18e67f77b4d718)
1*1debfc3dSmrg#! /usr/bin/python
2*1debfc3dSmrg#
3*1debfc3dSmrg# Print a report on which libgccjit.so symbols are used in which test
4*1debfc3dSmrg# cases, and which lack test coverage.  Tested with Python 2.7 and 3.2
5*1debfc3dSmrg# To be run from the root directory of the source tree.
6*1debfc3dSmrg#
7*1debfc3dSmrg# Copyright (C) 2014 Free Software Foundation, Inc.
8*1debfc3dSmrg# Written by David Malcolm <dmalcolm@redhat.com>.
9*1debfc3dSmrg#
10*1debfc3dSmrg# This script is Free Software, and it can be copied, distributed and
11*1debfc3dSmrg# modified as defined in the GNU General Public License.  A copy of
12*1debfc3dSmrg# its license can be downloaded from http://www.gnu.org/copyleft/gpl.html
13*1debfc3dSmrg
14*1debfc3dSmrgfrom collections import Counter
15*1debfc3dSmrgimport glob
16*1debfc3dSmrgimport re
17*1debfc3dSmrgimport sys
18*1debfc3dSmrg
19*1debfc3dSmrgdef parse_map_file(path):
20*1debfc3dSmrg    """
21*1debfc3dSmrg    Parse libgccjit.map, returning the symbols in the API as a list of str.
22*1debfc3dSmrg    """
23*1debfc3dSmrg    syms = []
24*1debfc3dSmrg    with open(path) as f:
25*1debfc3dSmrg        for line in f:
26*1debfc3dSmrg            m = re.match('^\s+([a-z_]+);$', line)
27*1debfc3dSmrg            if m:
28*1debfc3dSmrg                syms.append(m.group(1))
29*1debfc3dSmrg    return syms
30*1debfc3dSmrg
31*1debfc3dSmrgdef parse_test_case(path):
32*1debfc3dSmrg    """
33*1debfc3dSmrg    Locate all symbol-like things in a C test case, yielding
34*1debfc3dSmrg    them as a sequence of str.
35*1debfc3dSmrg    """
36*1debfc3dSmrg    with open(path) as f:
37*1debfc3dSmrg        for line in f:
38*1debfc3dSmrg            for m in re.finditer('([_A-Za-z][_A-Za-z0-9]*)', line):
39*1debfc3dSmrg                yield m.group(1)
40*1debfc3dSmrg
41*1debfc3dSmrgdef find_test_cases():
42*1debfc3dSmrg    for path in glob.glob('gcc/testsuite/jit.dg/*.[ch]'):
43*1debfc3dSmrg        yield path
44*1debfc3dSmrg
45*1debfc3dSmrgapi_syms = parse_map_file('gcc/jit/libgccjit.map')
46*1debfc3dSmrg
47*1debfc3dSmrgsyms_in_test_cases = {}
48*1debfc3dSmrgfor path in find_test_cases():
49*1debfc3dSmrg    syms_in_test_cases[path] = list(parse_test_case(path))
50*1debfc3dSmrg
51*1debfc3dSmrguses = Counter()
52*1debfc3dSmrgfor sym in sorted(api_syms):
53*1debfc3dSmrg    print('symbol: %s' % sym)
54*1debfc3dSmrg    uses[sym] = 0
55*1debfc3dSmrg    for path in syms_in_test_cases:
56*1debfc3dSmrg        count = syms_in_test_cases[path].count(sym)
57*1debfc3dSmrg        uses[sym] += count
58*1debfc3dSmrg        if count:
59*1debfc3dSmrg            print('  uses in %s: %i' % (path, count))
60*1debfc3dSmrg    if uses[sym] == 0:
61*1debfc3dSmrg        print('  NEVER USED')
62*1debfc3dSmrg    sys.stdout.write('\n')
63*1debfc3dSmrg
64*1debfc3dSmrglayout = '%40s  %5s  %s'
65*1debfc3dSmrgprint(layout % ('SYMBOL', 'USES', 'HISTOGRAM'))
66*1debfc3dSmrgfor sym, count in uses.most_common():
67*1debfc3dSmrg    print(layout % (sym, count, '*' * count if count else 'UNUSED'))
68