xref: /llvm-project/llvm/utils/llvm-gisel-cov.py (revision b71edfaa4ec3c998aadb35255ce2f60bba2940b0)
1#!/usr/bin/env python
2"""
3Summarize the information in the given coverage files.
4
5Emits the number of rules covered or the percentage of rules covered depending
6on whether --num-rules has been used to specify the total number of rules.
7"""
8from __future__ import print_function
9
10import argparse
11import struct
12
13
14class FileFormatError(Exception):
15    pass
16
17
18def backend_int_pair(s):
19    backend, sep, value = s.partition("=")
20    if sep is None:
21        raise argparse.ArgumentTypeError("'=' missing, expected name=value")
22    if not backend:
23        raise argparse.ArgumentTypeError("Expected name=value")
24    if not value:
25        raise argparse.ArgumentTypeError("Expected name=value")
26    return backend, int(value)
27
28
29def main():
30    parser = argparse.ArgumentParser(description=__doc__)
31    parser.add_argument("input", nargs="+")
32    parser.add_argument(
33        "--num-rules",
34        type=backend_int_pair,
35        action="append",
36        metavar="BACKEND=NUM",
37        help="Specify the number of rules for a backend",
38    )
39    args = parser.parse_args()
40
41    covered_rules = {}
42
43    for input_filename in args.input:
44        with open(input_filename, "rb") as input_fh:
45            data = input_fh.read()
46            pos = 0
47            while data:
48                backend, _, data = data.partition("\0")
49                pos += len(backend)
50                pos += 1
51
52                if len(backend) == 0:
53                    raise FileFormatError()
54                (backend,) = struct.unpack("%ds" % len(backend), backend)
55
56                while data:
57                    if len(data) < 8:
58                        raise FileFormatError()
59                    (rule_id,) = struct.unpack("Q", data[:8])
60                    pos += 8
61                    data = data[8:]
62                    if rule_id == (2**64) - 1:
63                        break
64                    covered_rules[backend] = covered_rules.get(backend, {})
65                    covered_rules[backend][rule_id] = (
66                        covered_rules[backend].get(rule_id, 0) + 1
67                    )
68
69    num_rules = dict(args.num_rules)
70    for backend, rules_for_backend in covered_rules.items():
71        if backend in num_rules:
72            print(
73                "%s: %3.2f%% of rules covered"
74                % (backend, float(len(rules_for_backend)) / num_rules[backend])
75                * 100
76            )
77        else:
78            print("%s: %d rules covered" % (backend, len(rules_for_backend)))
79
80
81if __name__ == "__main__":
82    main()
83