github/workflows/pycopy-test: Upgrade Pycopy to 3.6.1.
[ScratchABlock.git] / cfgutils.py
blob42d96fd994935a7c61f9b40259a075e338fa3433
1 from core import BBlock, CFGPrinter
4 def dump(cfg):
5 CFGPrinter(cfg).print()
8 def save_cfg(cfg, suffix):
9 with open(cfg.filename + suffix, "w") as out:
10 p = CFGPrinter(cfg, out)
11 p.print()
14 def swap_if_branches(cfg, node):
15 "Assuming `node` is 'if' node, swap its branches and invert condition."
16 succ = cfg.sorted_succ(node)
17 print(succ, cfg[node, succ[0]])
18 cond = cfg[node, succ[0]]["cond"]
19 cfg[node, succ[0]]["cond"] = None
20 cfg[node, succ[1]]["cond"] = cond.neg()
23 def detach_node(cfg, n):
24 din = cfg.degree_in(n)
25 dout = cfg.degree_out(n)
26 assert din == 1 or dout == 1
27 if din == 1:
28 pred = cfg.pred(n)[0]
29 cfg.move_succ(n, pred)
30 else:
31 succ = cfg.succ(n)[0]
32 cfg.move_pred(n, succ)
33 cfg.remove_node(n)
36 def foreach_node(cfg, func):
37 """Call function for each node of graph, passing node's properties.
38 """
39 for addr, info in cfg.iter_sorted_nodes():
40 func(info)
43 def foreach_bblock(cfg, func, join_func=lambda a, b: a or b, **kwargs):
44 """Apply basic-block level transformation to each block in CFG.
45 Return cumulative status (OR of each block's status).
46 """
47 res = Ellipsis
48 for addr, info in cfg.iter_sorted_nodes():
49 bblock = info["val"]
50 r = func(bblock, **kwargs)
51 if res is Ellipsis:
52 res = r
53 else:
54 res = join_func(res, r)
55 return res
58 def foreach_bblock_and_subblock(cfg, func):
59 def apply(bblock, func):
60 if type(bblock) is BBlock:
61 func(bblock)
62 else:
63 for sub in bblock.subblocks():
64 apply(sub, func)
66 for addr, info in cfg.iter_sorted_nodes():
67 bblock = info["val"]
68 apply(bblock, func)
71 def foreach_inst(cfg, func, **kwargs):
72 def inst_handler(bblock):
73 for inst in bblock.items:
74 func(inst, **kwargs)
75 foreach_bblock_and_subblock(cfg, inst_handler)
78 def copy_bblocks_props(cfg_from, cfg_to):
79 def copy(bblock):
80 cfg_to[bblock.addr]["val"].props = bblock.props.copy()
82 foreach_bblock(cfg_from, copy)