github/workflows/pycopy-test: Upgrade Pycopy to 3.6.1.
[ScratchABlock.git] / dce.py
blob82674a685889d826abddff87f2445193a050563f
1 import logging
2 from core import *
5 _log = logging.getLogger(__file__)
8 def make_dead(insts, idx):
9 org_inst = insts[idx]
10 if org_inst.op == "DEAD":
11 return
12 if org_inst.side_effect():
13 org_inst.dest = None
14 else:
15 dead = Inst(None, "DEAD", [])
16 dead.addr = org_inst.addr
17 insts[idx] = dead
18 insts[idx].comments["org_inst"] = org_inst
21 def dead_code_elimination_forward(bblock):
22 """Try to perform eliminations using forward flow. This is reverse
23 to the natural direction, and requires multiple passing over
24 bblock to stabilize. Don't use it, here only for comparison."""
26 vars = bblock.defs()
27 for v in vars:
28 last = None
29 for i, inst in enumerate(bblock.items):
30 if v in inst.args:
31 last = None
32 if inst.dest == v:
33 if last is not None:
34 make_dead(bblock.items, last)
35 last = i
36 node = bblock.cfg[bblock.addr]
37 live_out = node.get("live_out")
38 if last is not None and live_out is not None:
39 if v not in live_out:
40 make_dead(bblock.items, last)
43 def dead_code_elimination_backward(bblock):
44 node = bblock.cfg[bblock.addr]
45 live = node.get("live_out")
46 if live is None:
47 _log.warn("BBlock %s: No live_out set, conservatively assuming all defined vars are live", bblock.addr)
48 live = bblock.defs()
49 live = live.copy()
51 changes = False
52 for i in range(len(bblock.items) - 1, -1, -1):
53 inst = bblock.items[i]
54 if isinstance(inst.dest, REG):
55 if inst.dest in live:
56 live.remove(inst.dest)
57 else:
58 make_dead(bblock.items, i)
59 changes = True
60 inst = bblock.items[i]
61 live |= inst.uses()
63 return changes
66 dead_code_elimination = dead_code_elimination_backward