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

#!/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)