Created
October 16, 2019 18:44
-
-
Save jdoerfert/c0abef910a66a680ce1f0625c4a264e6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Run grep -E 'class|struct AA|public AA|private AA|getAAFor|AAReturnedFromReturnedValues|AACallSiteReturnedFromReturned|MustBeExecutedContext|AAArgumentFromCallSiteArguments' llvm/lib/Transforms/IPO/Attributor.cpp &>! /tmp/dep_graph_inp | |
# Filter the first lines untill you hit AANoUnwind and the onies after AAMemoryBehaviorCallSite manually or put two comments in the source like: "// AA HERE" | |
# Filter the two occurences of getAAFor in front of AANonNull that are otherwise associated with AANoFree | |
# run the python scrip like: | |
# python dep_Graph.py /tmp/dep_graph_inp /tmp/dep_graph.dot | |
import sys | |
import re | |
import os | |
full = 'full' in sys.argv | |
get_re = re.compile('getAAFor<([^>]*)>') | |
aa_rv_re = re.compile('(AA\w+).*?:.*AA\w*From\w*<(AA[a-zA-Z]*)') | |
aa_re = re.compile('(AA\w+).*?:.*?(AA\w*)') | |
inh = {} | |
dep = {'AAReturnedValues':set(), 'AAIsDead':set()} | |
with open(sys.argv[1], 'r') as fd: | |
last_class = None | |
lines = fd.readlines() | |
erase = True | |
for i, line in enumerate(lines): | |
if 'HERE' in line: | |
erase = not erase | |
lines[i] = None | |
continue | |
if erase: | |
lines[i] = None | |
continue | |
if line.strip().startswith(':'): | |
if lines[i-1]: | |
if line[:-1].endswith('AACallSiteReturnedFromReturnedAndMustBeExecutedContext<'): | |
aaidx = lines[i-1].index('AA') | |
line = line[:-1] + lines[i-1][aaidx:aaidx+(lines[i-1][aaidx:].index(' '))-16] + "," | |
lines[i-1] = lines[i-1][:-1] + line | |
lines[i] = None | |
if 'getAAFor' in line: | |
continue | |
if 'using' in line or '//' in line or 'Base' in line or 'Tracker' in line or 'InfoCache' in line or '=' in line or ';' in line: | |
lines[i] = None | |
for line in lines: | |
if not line: | |
continue | |
print(line[:-1]) | |
qm_match = get_re.search(line) | |
aa_rv_match = aa_rv_re.search(line) | |
aa_match = aa_re.search(line) | |
if qm_match: | |
cl = qm_match.group(1) | |
if not cl in dep: | |
dep[cl] = set() | |
dep[cl].add(last_class) | |
elif aa_rv_match: | |
new_class = aa_rv_match.group(1) | |
new_parent = aa_rv_match.group(2) | |
print(new_class, new_parent) | |
inh[new_class] = new_parent | |
if not last_class or last_class not in new_parent: | |
last_class = new_class | |
if 'AAReturnedValues' in line: | |
dep['AAReturnedValues'].add(last_class) | |
elif aa_match: | |
new_class = aa_match.group(1) | |
new_parent = aa_match.group(2) | |
print(new_class, new_parent) | |
inh[new_class] = new_parent | |
if not last_class or last_class not in new_parent: | |
last_class = new_class | |
else: | |
print('unknown', line) | |
print() | |
if full: | |
with open(sys.argv[2], 'w') as fd: | |
fd.write(f'digraph {os.path.basename(sys.argv[1])} {{{os.linesep}compound=true;{os.linesep}') | |
rev_inh = {} | |
for c,p in inh.items(): | |
rev_inh[p] = c | |
if p not in inh: | |
fd.write(f'subgraph cluster_{p} {{{os.linesep}style=filled;{os.linesep}color=lightgrey;{os.linesep}node [style=filled,color=white];{os.linesep}') | |
for cl2, _ in inh.items(): | |
if p in cl2: | |
fd.write(f' "{cl2}"') | |
fd.write(f'{os.linesep}label = "{p}";{os.linesep}}}{os.linesep}') | |
for cl, srcs in dep.items(): | |
for src in srcs: | |
srcp = src | |
while srcp in inh: | |
if srcp == inh[srcp]: | |
print(srcp) | |
assert False | |
srcp = inh[srcp] | |
if srcp != cl: | |
fd.write(f' "{src}" -> "{rev_inh[cl]}" [ltail=cluster_{srcp},lhead=cluster_{cl}];{os.linesep}') | |
if cl in inh: | |
if inh[cl] in inh: | |
fd.write(f' "{inh[cl]}" -> "{cl}" [style=dotted];{os.linesep}') | |
elif cl is not 'AAIsDead': | |
fd.write(f' "{rev_inh[cl]}" -> "AAIsDeadFloating" [ltail=cluster_{cl},lhead=cluster_AAIsDead];{os.linesep}') | |
fd.write(f'}}{os.linesep}') | |
else: | |
with open(sys.argv[2], 'w') as fd: | |
fd.write(f'digraph {os.path.basename(sys.argv[1])} {{{os.linesep}') | |
for cl, srcs in dep.items(): | |
for src in srcs: | |
fd.write(f' "{src}" -> "{cl}";{os.linesep}') | |
fd.write(f'}}{os.linesep}') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment