All pastes #231117 Raw Edit

Unnamed

public text v1 · immutable
#231117 ·published 2006-10-31 17:07 UTC
rendered paste body
# by snikim

from __future__ import division
import sys, os
import re

prefix = sys.argv[1]
disinp = open(prefix + '.dis')
profinp = open(prefix + '.out')

pat_prof = re.compile('^0x([0-9a-f]{4,6}) ([0-9]+) ([0-9.]+)$')
pat_dis = re.compile('^ +([0-9a-f]{4,6}):[ \t]+[0-9a-f]+[ \t]+([a-zA-Z0-9_-]+)[ \t]+(.*)$')

CANONICALINSTRS = {
}

CONDITIONALS = ('eq', 'ne', 'cs', 'hs', 'cc', 'lo', 'mi', 'pl', 'vs',
                'vc', 'hi', 'ls', 'ge', 'lt', 'gt', 'le', 'al')
CONDITIONAL_INSTRS = (
    'adc', 'adc_s', 'add', 'add_s', 'and', 'b', 'bl', 'bic', 'blx', 'bx', 'cdp', 'clz',
    'cmn', 'cmp', 'eor', 'ldc', 'ldm', 'ldm_ia', 'ldm_db', 'ldr', 'ldr_b', 'ldr_bt',
    'ldr_h', 'ldr_sb', 'ldr_sh', 'ldr_t', 'mcr', 'mla', 'mla_s', 'mov', 'mov_s',
    'mrc', 'mrs', 'msr', 'mul', 'mul_s', 'mvn', 'mvn_s', 'orr', 'orr_s', 'rsb',
    'rsb_s', 'rsc', 'rsc_s', 'sbc', 'sbc_s', 'smlal', 'smlal_s', 'smull', 'smull_s',
    'stc', 'stc_l', 'stm', 'stm_p' ,'stm_u', 'stm_db', 'stm_w', 'str', 'str_b',
    'str_bt', 'str_h', 'str_t', 'sub', 'sub_s', 'swi', 'swp', 'swp_b', 'teq', 'tst',
    'umlal', 'umlal_s', 'umull', 'umull_s',
)

for cond in CONDITIONALS:
    for instr in CONDITIONAL_INSTRS:
        if '_' in instr:
            pfx = instr.split('_')[0]
            CANONICALINSTRS[instr.replace('_', '')] = pfx
            CANONICALINSTRS[instr.replace('_', cond)] = pfx
        else:
            CANONICALINSTRS[instr + cond] = instr
CANONICALINSTRS.update({
    'bics': 'bic',
})

addrprofs = {}

for l in profinp:
    l = l[:-1]
    match = pat_prof.match(l)
    if match is not None:
        addr, count, percent = match.groups()
        addr = int(addr, 16)
        addrprofs[addr] = {'count': int(count)}

unused = 0
for l in disinp:
    l = l[:-1]
    match = pat_dis.match(l)
    if match is not None:
        addr, instr, operands = match.groups()
        addr = int(addr, 16)
        if addr not in addrprofs:
            addrprofs[addr] = {'count': 0}
            unused += 1
        addrprofs[addr]['instr'] = instr
        addrprofs[addr]['operands'] = operands

profs = addrprofs.items()
profs.sort(key=lambda (k, v): (v['count'], k), reverse=True)
totalcalls = sum(v['count'] for k, v in profs)

print "==== basic statistics ===="
print " Total calls:\t\t\t%12d" % totalcalls
print " Total lines of the code:\t%12d" % len(profs)
print " Unused code:\t\t\t%12d (%6.2f%%)" % (unused, unused / len(profs) * 100)
print

perinstr = {}
for addr, info in profs:
    instr = CANONICALINSTRS.get(info['instr'], info['instr'])
    if instr not in perinstr:
        perinstr[instr] = 0
    perinstr[instr] += info['count']
perinstr = perinstr.items()
perinstr.sort(key=lambda (k, v): (v, k), reverse=True)

print "==== frequent instructions ===="
accum = 0
for instr, freq in perinstr[:20]:
    accum += freq
    print "%s\t%10d\t%6.2f%%\t%6.2f%%" % (instr, freq, freq/totalcalls*100,
                                         accum/totalcalls*100)
print

print "==== per-code statistics ===="
accumcalls = 0
for i, (addr, info) in enumerate(profs):
    accumcalls += info['count']
    print '%6d\t%6.2f%%\t%12d\t%6.2f%%\t%12d\t0x%08x\t%s\t%s' % (
        i, i / len(profs) * 100.0,
        accumcalls, accumcalls / totalcalls * 100.0,
        info['count'],
        addr, info['instr'], info['operands'],
    )

# ex: ts=8 sts=4 sw=4 et