forked from ethanchewy/PythonBuddy
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathliveness.py
More file actions
79 lines (66 loc) · 2.72 KB
/
liveness.py
File metadata and controls
79 lines (66 loc) · 2.72 KB
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
from rpython.jit.codewriter.flatten import Register, ListOfKind, Label, TLabel
from rpython.jit.codewriter.jitcode import SwitchDictDescr
# Some instructions require liveness information (the ones that can end up
# in generate_guard() in pyjitpl.py). This is done by putting special
# space operations called '-live-' in the graph. They turn into '-live-'
# operation in the ssarepr. Then the present module expands the arguments
# of the '-live-' operations to also include all values that are alive at
# this point (written to before, and read afterwards). You can also force
# extra variables to be alive by putting them as args of the '-live-'
# operation in the first place.
# For this to work properly, a special operation called '---' must be
# used to mark unreachable places (e.g. just after a 'goto').
# ____________________________________________________________
def compute_liveness(ssarepr):
label2alive = {}
while _compute_liveness_must_continue(ssarepr, label2alive):
pass
def _compute_liveness_must_continue(ssarepr, label2alive):
alive = set()
must_continue = False
def follow_label(lbl):
alive_at_point = label2alive.get(lbl.name, ())
alive.update(alive_at_point)
for i in range(len(ssarepr.insns)-1, -1, -1):
insn = ssarepr.insns[i]
if isinstance(insn[0], Label):
alive_at_point = label2alive.setdefault(insn[0].name, set())
prevlength = len(alive_at_point)
alive_at_point.update(alive)
if prevlength != len(alive_at_point):
must_continue = True
continue
if insn[0] == '-live-':
labels = []
for x in insn[1:]:
if isinstance(x, Register):
alive.add(x)
elif isinstance(x, TLabel):
follow_label(x)
labels.append(x)
ssarepr.insns[i] = insn[:1] + tuple(alive) + tuple(labels)
continue
if insn[0] == '---':
alive = set()
continue
args = insn[1:]
#
if len(args) >= 2 and args[-2] == '->':
reg = args[-1]
assert isinstance(reg, Register)
alive.discard(reg)
args = args[:-2]
#
for x in args:
if isinstance(x, Register):
alive.add(x)
elif isinstance(x, ListOfKind):
for y in x:
if isinstance(y, Register):
alive.add(y)
elif isinstance(x, TLabel):
follow_label(x)
elif isinstance(x, SwitchDictDescr):
for key, label in x._labels:
follow_label(label)
return must_continue