-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathdce.py
66 lines (53 loc) · 1.87 KB
/
dce.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
import logging
from core import *
_log = logging.getLogger(__file__)
def make_dead(insts, idx):
org_inst = insts[idx]
if org_inst.op == "DEAD":
return
if org_inst.side_effect():
org_inst.dest = None
else:
dead = Inst(None, "DEAD", [])
dead.addr = org_inst.addr
insts[idx] = dead
insts[idx].comments["org_inst"] = org_inst
def dead_code_elimination_forward(bblock):
"""Try to perform eliminations using forward flow. This is reverse
to the natural direction, and requires multiple passing over
bblock to stabilize. Don't use it, here only for comparison."""
vars = bblock.defs()
for v in vars:
last = None
for i, inst in enumerate(bblock.items):
if v in inst.args:
last = None
if inst.dest == v:
if last is not None:
make_dead(bblock.items, last)
last = i
node = bblock.cfg[bblock.addr]
live_out = node.get("live_out")
if last is not None and live_out is not None:
if v not in live_out:
make_dead(bblock.items, last)
def dead_code_elimination_backward(bblock):
node = bblock.cfg[bblock.addr]
live = node.get("live_out")
if live is None:
_log.warn("BBlock %s: No live_out set, conservatively assuming all defined vars are live", bblock.addr)
live = bblock.defs()
live = live.copy()
changes = False
for i in range(len(bblock.items) - 1, -1, -1):
inst = bblock.items[i]
if isinstance(inst.dest, REG):
if inst.dest in live:
live.remove(inst.dest)
else:
make_dead(bblock.items, i)
changes = True
inst = bblock.items[i]
live |= inst.uses()
return changes
dead_code_elimination = dead_code_elimination_backward