-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdom.py
executable file
·137 lines (104 loc) · 3.96 KB
/
dom.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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/usr/bin/python3
import sys
import json
from brilpy import *
from functools import reduce
class Dominators:
def __init__(self, func):
g = CFG(func)
# First compute dominators
# IMPORTANT: This computes, for each block, the set of blocks that dominate
# it, not the other way around
self.doms = []
self.doms.append(set([0])) # Entry block is special, it's its own dominator
for i in range(1,g.n):
self.doms.append(set(range(g.n)))
order = g.rpo()
changed = True
while changed:
changed = False
for i in order[1:]: # no one can dominate 0 except 0
d = {i}
if g.preds[i]:
d |= reduce(set.intersection, [self.doms[p] for p in g.preds[i]], set(range(g.n)))
if d != self.doms[i]:
changed = True
self.doms[i] = d
# Compute the "other way around" (from above), that is, for each block, the
# set of blocks this block dominates
self.dom_by = []
for i in range(g.n):
self.dom_by.append(set())
for i,d in enumerate(self.doms):
for mbr in d:
self.dom_by[mbr].add(i)
# Compute the dominance tree
dt_parent = [None]
for i in range(1, g.n):
for j in self.doms[i]:
if i != j: # j strictly dominates i
immed_dom = True
for k in range(g.n):
if k != j and k != i and j in self.doms[k] and k in self.doms[i]:
immed_dom = False
break
if immed_dom:
dt_parent.append(j)
break
self.dom_tree = {}
for i,p in enumerate(dt_parent):
if p in self.dom_tree:
self.dom_tree[p].append(i)
else:
self.dom_tree[p] = [i]
# Compute dominance frontier
self.frontier = []
for i in range(g.n):
self.frontier.append(set())
for i,d in enumerate(self.doms):
# Union of dominators for this node's preds
pre_doms = reduce(set.union, [self.doms[p] for p in g.preds[i]], set())
# Subtract out strict dominators for this node
pre_doms = pre_doms.difference(self.doms[i].difference(set([i])))
# This node is in the frontier for the remaining nodes:
for p in pre_doms:
self.frontier[p].add(i)
def main():
prog = json.load(sys.stdin)
for func in prog['functions']:
print("**Function: {}".format(func['name']))
g = CFG(func)
f = open("graphs/" + func['name'] + "-cfg.dot", 'w')
f.write(g.to_dot())
f.close()
print(g.to_dot())
g.print_names()
print(" edges: {}".format(g.edges))
print(" preds: {}".format(g.preds))
d = dominators(func)
print("\n\n doms:\n{}\n".format(d.doms))
for k,v in enumerate(doms):
print(" {}: ".format(g.names[k]), end="")
for mbr in v:
print("{} ".format(g.names[mbr]), end="")
print("")
# print("dom tree:\ndigraph g {")
print(" domtree:")
f = open("graphs/" + func['name'] + "-dt.dot", 'w')
print("digraph g {")
f.write("digraph g {\n")
for k,v in d.dom_tree.items():
for mbr in v:
print("{} -> {};".format(g.names[k], g.names[mbr]))
f.write("{} -> {};\n".format(g.names[k], g.names[mbr]))
print("}")
f.write("}\n")
f.close()
print("\n\n dominance frontier:")
for k,v in enumerate(d.frontier):
print(" {}: ".format(g.names[k]), end="")
for mbr in v:
print("{} ".format(g.names[mbr]), end="")
print("")
if __name__ == '__main__':
main()