-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdominance_with_worklist.py
61 lines (52 loc) · 1.45 KB
/
dominance_with_worklist.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
import copy
def worklist_algo(cfg, merge_func, transfer_func, printer=None):
"""The worklist algorithm
- cfg: a dictionary of blocks
"""
# ins and outs are dicts: {str : set()}
# initialize
ins = dict()
outs = dict()
for label, _ in cfg.items():
ins[label] = set()
outs[label] = set()
worklist = copy.deepcopy(cfg)
while len(worklist) > 0:
# pick any block from worklist
# I'll just pick the first one
label = list(worklist.keys())[0]
bb = worklist.pop(label)
bb_ins = [outs[label] for label in bb.pred]
bb_ins_merged = merge_func(bb_ins)
ins[label] = bb_ins_merged
bb_outs = transfer_func(bb, bb_ins_merged)
if len(bb_outs) != len(outs[label]):
outs[label] = bb_outs
for succ in bb.succ:
worklist[succ] = cfg[succ]
if printer is not None:
printer(ins, outs)
return outs
def merge(ins):
"""
- ins: a list of sets
- return: a set
"""
res = set()
if len(ins) > 0:
res.update(ins[0])
for i in ins:
if len(i) == 0: continue
res = res.intersection(i)
return res
def transfer(bb, ins):
"""
- bb: BasicBlock
- ins: a set of dominator
- return: a set dominators
"""
label = bb.instrs[0]['label']
ins.add(label)
return ins
def find_dominator_worklist(cfg):
return worklist_algo(cfg, merge, transfer)