about summary refs log tree commit diff homepage
path: root/scripts/IStatsSum.py
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/IStatsSum.py')
-rwxr-xr-xscripts/IStatsSum.py129
1 files changed, 129 insertions, 0 deletions
diff --git a/scripts/IStatsSum.py b/scripts/IStatsSum.py
new file mode 100755
index 00000000..ce680c7b
--- /dev/null
+++ b/scripts/IStatsSum.py
@@ -0,0 +1,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)