-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvisualizer.py
95 lines (82 loc) · 2.61 KB
/
visualizer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
from graphviz import Digraph
# Text format pretty-printer.
def type_to_str(type):
if isinstance(type, dict):
assert len(type) == 1
key, value = next(iter(type.items()))
return '{}<{}>'.format(key, type_to_str(value))
else:
return type
def instr_to_string(instr):
if instr['op'] == 'const':
tyann = ': {}'.format(type_to_str(instr['type'])) \
if 'type' in instr else ''
return '{}{} = const {}'.format(
instr['dest'],
tyann,
str(instr['value']).lower(),
)
else:
rhs = instr['op']
if instr.get('funcs'):
rhs += ' {}'.format(' '.join(
'@{}'.format(f) for f in instr['funcs']
))
if instr.get('args'):
rhs += ' {}'.format(' '.join(instr['args']))
if instr.get('labels'):
rhs += ' {}'.format(' '.join(
'.{}'.format(f) for f in instr['labels']
))
if 'dest' in instr:
tyann = ': {}'.format(type_to_str(instr['type'])) \
if 'type' in instr else ''
return '{}{} = {}'.format(
instr['dest'],
tyann,
rhs,
)
else:
return rhs
def print_instr(instr):
return ' {};'.format(instr_to_string(instr))
class CFGVisualizer(object):
"""
- cfg: dict(str, BasicBlock)
"""
def __init__(self, cfg, name) -> None:
self.cfg = cfg
self.dot = Digraph(name, node_attr={'shape': 'rectangle'})
self.build()
def build(self):
# build nodes
for label, bb in self.cfg.items():
instr_str = '.' + label + ":\l"
for instr in bb.instrs:
if 'op' not in instr: continue
instr_str += " " + print_instr(instr) + "\l"
self.dot.node(label, instr_str)
# build edges
for label, bb in self.cfg.items():
for succ in bb.succ:
self.dot.edge(label, succ)
def show(self):
self.dot.render(view=True)
class DomTreeVisualizer(object):
"""
- domtree: dict(str, Node)
"""
def __init__(self, dom_tree, name):
self.dom_tree = dom_tree
self.dot = Digraph(name)
self.build()
def build(self):
# build nodes
for vertex in self.dom_tree.keys():
self.dot.node(vertex, vertex)
# build edges
for vertex, node in self.dom_tree.items():
for succ in node.succs:
self.dot.edge(vertex, succ)
def show(self):
self.dot.render(view=True)