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