-
Notifications
You must be signed in to change notification settings - Fork 23
/
cfgutils.py
82 lines (62 loc) · 2.06 KB
/
cfgutils.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
from core import BBlock, CFGPrinter
def dump(cfg):
CFGPrinter(cfg).print()
def save_cfg(cfg, suffix):
with open(cfg.filename + suffix, "w") as out:
p = CFGPrinter(cfg, out)
p.print()
def swap_if_branches(cfg, node):
"Assuming `node` is 'if' node, swap its branches and invert condition."
succ = cfg.sorted_succ(node)
print(succ, cfg[node, succ[0]])
cond = cfg[node, succ[0]]["cond"]
cfg[node, succ[0]]["cond"] = None
cfg[node, succ[1]]["cond"] = cond.neg()
def detach_node(cfg, n):
din = cfg.degree_in(n)
dout = cfg.degree_out(n)
assert din == 1 or dout == 1
if din == 1:
pred = cfg.pred(n)[0]
cfg.move_succ(n, pred)
else:
succ = cfg.succ(n)[0]
cfg.move_pred(n, succ)
cfg.remove_node(n)
def foreach_node(cfg, func):
"""Call function for each node of graph, passing node's properties.
"""
for addr, info in cfg.iter_sorted_nodes():
func(info)
def foreach_bblock(cfg, func, join_func=lambda a, b: a or b, **kwargs):
"""Apply basic-block level transformation to each block in CFG.
Return cumulative status (OR of each block's status).
"""
res = Ellipsis
for addr, info in cfg.iter_sorted_nodes():
bblock = info["val"]
r = func(bblock, **kwargs)
if res is Ellipsis:
res = r
else:
res = join_func(res, r)
return res
def foreach_bblock_and_subblock(cfg, func):
def apply(bblock, func):
if type(bblock) is BBlock:
func(bblock)
else:
for sub in bblock.subblocks():
apply(sub, func)
for addr, info in cfg.iter_sorted_nodes():
bblock = info["val"]
apply(bblock, func)
def foreach_inst(cfg, func, **kwargs):
def inst_handler(bblock):
for inst in bblock.items:
func(inst, **kwargs)
foreach_bblock_and_subblock(cfg, inst_handler)
def copy_bblocks_props(cfg_from, cfg_to):
def copy(bblock):
cfg_to[bblock.addr]["val"].props = bblock.props.copy()
foreach_bblock(cfg_from, copy)