about summary refs log tree commit diff homepage
path: root/scripts/IStatsSum.py
blob: ce680c7b078fd8913b46ebbfa8373affba33f0f4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#!/usr/bin/python

from __future__ import division

import sys, os

def getSummary(input):
    inputs = [[None,iter(open(input))]]
    def getLine(elt):
        la,i = elt
        if la is None:
            try:
                ln = i.next()
            except StopIteration:
                ln = None
            except:
                raise ValueError("unexpected IO error")
            return ln
        else:
            elt[0] = None
            return la
    def getLines():
        return map(getLine,inputs)
    def putback(ln,elt):
        assert elt[0] is None
        elt[0] = ln
        
    events = None
    
    # read header (up to ob=)
    while 1:
        lns = getLines()
        ln = lns[0]
        if ln.startswith('ob='):
            break
        else:
            if ln.startswith('positions:'):
                if ln!='positions: instr line\n':
                    raise ValueError("unexpected 'positions' directive")
            elif ln.startswith('events:'):
                events = ln[len('events: '):].strip().split(' ')

    if events is None:
        raise ValueError('missing events directive')
    boolTypes = set(['Icov','Iuncov'])
    numEvents = len(events)
    eventTypes = [e in boolTypes for e in events]

    def readCalls():
        results = {}
        for elt in inputs:
            while 1:
                ln = getLine(elt)
                if ln is not None and (ln.startswith('cfl=') or ln.startswith('cfn=')):
                    if ln.startswith('cfl='):
                        cfl = ln
                        cfn = getLine(elt)
                        if not cfn.startswith('cfn='):
                            raise ValueError("unexpected cfl directive without function")
                    else:
                        cfl = None
                        cfn = ln
                    target = getLine(elt)
                    if not target.startswith('calls='):
                        raise ValueError("unexpected cfn directive with calls")
                    stat = map(int,getLine(elt).strip().split(' '))
                    key = target
                    existing = results.get(target)
                    if existing is None:
                        results[key] = [cfl,cfn,target,stat]
                    else:
                        if existing[0]!=cfl or existing[1]!=cfn:
                            raise ValueError("multiple call descriptions for a single target")
                        existing[3] = mergeStats([existing[3],stat])
                else:
                    putback(ln, elt)
                    break
        return results

    summed = [0]*len(events)
    
    # read statistics
    while 1:
        lns = getLines()
        ln = lns[0]
        if ln is None:
            break
        elif ln.startswith('fn') or ln.startswith('fl'):
            pass
        elif ln.strip():
            # an actual statistic
            data = [map(int,ln.strip().split(' ')) for ln in lns][0]
            summed = map(lambda a,b: a+b, data[2:], summed)

            # read any associated calls
            for cfl,cfn,calls,stat in readCalls().values():
                pass

    return events,summed
    
def main(args):
    from optparse import OptionParser
    op = OptionParser("usage: %prog [options] file")
    opts,args = op.parse_args()

    total = {}
    for i in args:
        events,summed = getSummary(i)
        for e,s in zip(events,summed):
            total[e] = total.get(e,[0,0])
            total[e][0] += s
            total[e][1] += 1
        print '-- %s --'%(i,)
        items = zip(events,summed)
        items.sort()
        for e,s in items:
            print '%s: %s'%(e,s)

    print '-- totals --'
    items = total.items()
    table = []    
    for e,(s,N) in items:
        table.append((str(e),str(s),str(N),str(s//N)))
    w = map(lambda l: max(map(len,l)), zip(*table))
    for (a,b,c,d) in table:
        print '%-*s: %*s (in %*s files, avg: %*s)'%(w[0],a,w[1],b,w[2],c,w[3],d)

if __name__=='__main__':
    main(sys.argv)