Files
BFM-decomp/tools/alloc_table.py
T

39 lines
2.7 KiB
Python

#!/usr/bin/env python3
"""alloc_table.py <tag> [fn] [dump_root]: from <dump_root>/dumps_<tag>/ (tools/cc1_dumps_tu.sh output) print the function's
pseudos with refs / live length / block / hard reg / priority (global.c allocno_compare: floor(log2 refs)*refs/live*1e4).
P32 T4c (S85): the instrument that read the callee-saved bank order (the target's $s0..$fp = priority order). dump_root defaults
to .run/P32/t4e."""
import re, sys, math
tag=sys.argv[1]; fn=sys.argv[2] if len(sys.argv)>2 else 'func_80039308'
d=f"{sys.argv[3] if len(sys.argv)>3 else '.run/P32/t4e'}/dumps_{tag}"
def section(path):
s=open(path).read()
i=s.find(f';; Function {fn}\n')
if i<0: i=s.find(f'Function {fn}\n')
j=s.find(';; Function ', i+20)
return s[i:j if j>0 else None]
lreg=section(f'{d}/{tag}.i.lreg'); greg=section(f'{d}/{tag}.i.greg'); flow=section(f'{d}/{tag}.i.flow')
regs={}
for m in re.finditer(r'Register (\d+) used (\d+) times across (\d+) insns(?: in block (-?\d+))?([^\n]*)', lreg):
n=int(m.group(1)); regs[n]=dict(refs=int(m.group(2)),live=int(m.group(3)),block=m.group(4),extra=m.group(5).strip())
hard={}
for m in re.finditer(r'Register (\d+) in (\d+)\.', greg): hard[int(m.group(1))]=int(m.group(2))
for m in re.finditer(r'Register (\d+) in (\d+)\.', lreg): hard.setdefault(int(m.group(1)),int(m.group(2)))
# label some pseudos from the flow-dump insns
labels={}
for m in re.finditer(r'\(set \(reg/?v?:SI (\d+)\)\s*\(ashift:SI \(reg[^ ]* (\d+)\)\s*\(const_int 8\)\)', flow): labels[int(m.group(1))]=f'ashift8(r{m.group(2)})'
for m in re.finditer(r'\(set \(reg/?v?:SI (\d+)\)\s*\(const_int (\d+)\)\)', flow): labels.setdefault(int(m.group(1)),f'const {m.group(2)}')
for m in re.finditer(r'\(set \(reg/?v?:SI (\d+)\)\s*\(zero_extend:SI \(mem:QI \(reg[^ ]* (\d+)\)', flow): labels.setdefault(int(m.group(1)),f'lbu(r{m.group(2)})')
for m in re.finditer(r'\(set \(reg/?v?:SI (\d+)\)\s*\(reg/?v?:SI (\d+)\)\)', flow): labels.setdefault(int(m.group(1)),f'copy(r{m.group(2)})')
names={16:'s0',17:'s1',18:'s2',19:'s3',20:'s4',21:'s5',22:'s6',23:'s7',30:'fp',8:'t0',9:'t1',10:'t2',11:'t3',12:'t4',13:'t5',14:'t6',15:'t7',24:'t8',25:'t9',2:'v0',3:'v1',4:'a0',5:'a1',6:'a2',7:'a3'}
rows=[]
for n,r in regs.items():
pri = (math.floor(math.log2(r['refs']))*r['refs']/r['live'])*10000 if r['refs']>0 and r['live']>0 else 0
rows.append((pri,n,r,hard.get(n),labels.get(n,'')))
rows.sort(key=lambda x:(-x[0],x[1]))
print(f'{tag}: {len(regs)} pseudos; callee-saved holders:')
for pri,n,r,h,l in rows:
if h is not None and h in (16,17,18,19,20,21,22,23,30):
print(f' r{n:<4} -> {names.get(h,h):<3} pri={pri:8.1f} refs={r["refs"]:<3} live={r["live"]:<4} blk={r["block"]} {l} {r["extra"][:40]}')
print('unallocated (no hard reg):', [n for pri,n,r,h,l in rows if h is None][:20])