You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
144 lines
3.9 KiB
144 lines
3.9 KiB
#!/usr/bin/env python
|
|
# -*- python -*-
|
|
|
|
# Grab the BLOCKCOUNT and MAPPADDR lines from the mix-mt output and
|
|
# attach that to a copy of the program. Run mix-mt with the -mapaddr
|
|
# pin took knob. And compile your program with -g
|
|
|
|
import os,sys,re
|
|
pcmap={}
|
|
|
|
class stat_t(object):
|
|
def __init__(self, filename='unknown', line=0, pc=None):
|
|
self.filename=filename
|
|
self.line = int(line)
|
|
self.count = 0
|
|
self.pc = pc
|
|
self.rank = 0
|
|
|
|
def stat_sorter(a,b):
|
|
if a.count > b.count:
|
|
return -1
|
|
if a.count < b.count:
|
|
return 1
|
|
return 0
|
|
|
|
def stat_sorter_line(a,b):
|
|
if a.line > b.line:
|
|
return 1
|
|
if a.line < b.line:
|
|
return -1
|
|
return 0
|
|
|
|
def combine_by_file_and_line(lines):
|
|
"""Even though the PC might be different"""
|
|
tmap = {}
|
|
for f in lines:
|
|
key = "%s-%s" % (f.line, f.filename)
|
|
if key not in tmap:
|
|
tmap[key]=f
|
|
else:
|
|
tmap[key].count += f.count
|
|
tmap['0-unknown'].pc = 'various'
|
|
return list(tmap.values())
|
|
|
|
|
|
def summarize():
|
|
global pcmap
|
|
|
|
#for k,f in pcmap.iteritems():
|
|
# print "%9s %8s %s:%s" % ( f.count, k, f.filename, f.line)
|
|
lines = list(pcmap.values())
|
|
# remove the zero entries
|
|
lines = [x for x in lines if x.count != 0]
|
|
# merge things with the same file and line
|
|
lines = combine_by_file_and_line(lines)
|
|
lines.sort(cmp=stat_sorter)
|
|
for i,f in enumerate(lines):
|
|
f.rank = i
|
|
print("AA%05d: %9s %8s %s:%d" % ( i, f.count, f.pc, f.filename, f.line))
|
|
return lines
|
|
|
|
def store_mapaddr(p):
|
|
global pcmap
|
|
(dummy, pc, line, filename) = p
|
|
#print "setting pc %s to %s : %s" % (pc, filename,line)
|
|
if pc in pcmap:
|
|
pcmap[pc].filename = filename
|
|
pcmap[pc].line = int(line)
|
|
pcmap[pc].pc=pc
|
|
else:
|
|
pcmap[pc]=stat_t(filename,line,pc)
|
|
|
|
def store_blockcount(p):
|
|
global pcmap
|
|
(dummy, pc, count) = p
|
|
if pc in pcmap:
|
|
pcmap[pc].count += int(count)
|
|
else:
|
|
t = stat_t()
|
|
t.pc = pc
|
|
t.count = int(count)
|
|
pcmap[pc] = t
|
|
|
|
|
|
def make_decorated_file(ifn,flines):
|
|
"""Emit a copy of f with the counts specified in the sorted list of stat_t's"""
|
|
fnew = "%s.pcov" % (ifn)
|
|
if os.path.exists(fnew):
|
|
sys.stderr.write("The file %s already exists. Please remove it if you want the new profile\n" % (fnew))
|
|
return
|
|
try:
|
|
f = open(fnew,"w")
|
|
except:
|
|
sys.stderr.write("Could not write %s -- skipping\n" % (fnew))
|
|
return
|
|
sys.stderr.write("Writing [%s]\n" % (fnew))
|
|
nline = 1
|
|
for x in file(ifn).readlines():
|
|
decorated = False
|
|
while len(flines) > 0 and flines[0].line == nline:
|
|
if decorated:
|
|
f.write("+")
|
|
else:
|
|
f.write("AA%05d " % (flines[0].rank))
|
|
f.write("%9d" % (flines[0].count))
|
|
flines.pop(0)
|
|
decorated = True
|
|
if not decorated:
|
|
f.write("%7s %9s" % ('', '')) # pad the line equivalently
|
|
f.write(" ")
|
|
f.write(x)
|
|
nline += 1
|
|
f.close()
|
|
|
|
def main(input_fn):
|
|
mapaddr = re.compile("^MAPADDR ")
|
|
blockcount = re.compile("^BLOCKCOUNT ")
|
|
lines = file(input_fn).readlines()
|
|
for line in lines:
|
|
m = mapaddr.match(line)
|
|
if m:
|
|
store_mapaddr(line.strip().split())
|
|
b = blockcount.match(line)
|
|
if b:
|
|
store_blockcount(line.strip().split())
|
|
lines = summarize()
|
|
|
|
filenames = {}
|
|
for f in lines:
|
|
if f.filename not in filenames and f.filename != 'unknown':
|
|
filenames[f.filename]=1
|
|
|
|
for f in list(filenames.keys()):
|
|
flines = [x for x in lines if x.filename == f]
|
|
flines.sort(cmp=stat_sorter_line)
|
|
make_decorated_file(f,flines)
|
|
|
|
if len(sys.argv) != 2:
|
|
sys.stderr.write("Need an input file\n")
|
|
sys.exit(1)
|
|
input_fn = sys.argv[1]
|
|
print("Input file %s" % (input_fn))
|
|
main(input_fn)
|