@@ -79,6 +79,11 @@ def to_string(self, gvn: InstrId) -> str:
7979 return type (self ).__name__
8080
8181
82+ @dataclasses .dataclass (eq = False )
83+ class Nop (Instr ):
84+ pass
85+
86+
8287@dataclasses .dataclass (eq = False )
8388class Const (Instr ):
8489 value : Object
@@ -378,6 +383,8 @@ def to_string(self, fn: IRFunction, gvn: InstrId) -> str:
378383 result += f" { block .name ()} {{\n "
379384 for instr in block .instrs :
380385 instr = instr .find ()
386+ if isinstance (instr , Nop ):
387+ continue
381388 if isinstance (instr , Control ):
382389 result += f" { instr .to_string (gvn )} \n "
383390 else :
@@ -540,7 +547,10 @@ def op(idx: int) -> str:
540547 def _to_c (self , f : io .StringIO , block : Block , gvn : InstrId ) -> None :
541548 f .write (f"{ block .name ()} :;\n " )
542549 for instr in block .instrs :
543- f .write (self ._instr_to_c (instr .find (), gvn ))
550+ instr = instr .find ()
551+ if isinstance (instr , Nop ):
552+ continue
553+ f .write (self ._instr_to_c (instr , gvn ))
544554
545555
546556class Compiler :
@@ -995,6 +1005,45 @@ def remove_unreachable_blocks(self) -> bool:
9951005 return len (self .fn .cfg .blocks ) != num_blocks
9961006
9971007
1008+ @dataclasses .dataclass
1009+ class DeadCodeElimination :
1010+ fn : IRFunction
1011+
1012+ def is_critical (self , instr : Instr ) -> bool :
1013+ if isinstance (instr , Const ):
1014+ return False
1015+ if isinstance (instr , IntAdd ):
1016+ return False
1017+ # TODO(max): Add more. Track heap effects?
1018+ return True
1019+
1020+ def run (self ) -> None :
1021+ worklist : list [Instr ] = []
1022+ marked : set [Instr ] = set ()
1023+ blocks = self .fn .cfg .rpo ()
1024+ # Mark
1025+ for block in blocks :
1026+ for instr in block .instrs :
1027+ instr = instr .find ()
1028+ if self .is_critical (instr ):
1029+ marked .add (instr )
1030+ worklist .append (instr )
1031+ while worklist :
1032+ instr = worklist .pop (0 ).find ()
1033+ if isinstance (instr , HasOperands ):
1034+ for op in instr .operands :
1035+ op = op .find ()
1036+ if op not in marked :
1037+ marked .add (op )
1038+ worklist .append (op )
1039+ # Sweep
1040+ for block in blocks :
1041+ for instr in block .instrs :
1042+ instr = instr .find ()
1043+ if instr not in marked :
1044+ instr .make_equal_to (Nop ())
1045+
1046+
9981047def _parse (source : str ) -> Object :
9991048 return parse (tokenize (source ))
10001049
@@ -2144,6 +2193,46 @@ def test_const_list(self) -> None:
21442193 self .assertEqual (analysis .instr_type [returned ], CList ())
21452194
21462195
2196+ class DeadCodeEliminationTests (unittest .TestCase ):
2197+ def test_remove_const (self ) -> None :
2198+ compiler = Compiler ()
2199+ compiler .emit (Const (1 ))
2200+ compiler .emit (Const (2 ))
2201+ compiler .emit (Const (3 ))
2202+ four = compiler .emit (Const (4 ))
2203+ compiler .emit (Return (four ))
2204+ DeadCodeElimination (compiler .fn ).run ()
2205+ self .assertEqual (
2206+ compiler .fn .to_string (InstrId ()),
2207+ """\
2208+ fn0 {
2209+ bb0 {
2210+ v0 = Const<4>
2211+ Return v0
2212+ }
2213+ }""" ,
2214+ )
2215+
2216+ def test_remove_int_add (self ) -> None :
2217+ compiler = Compiler ()
2218+ one = compiler .emit (Const (1 ))
2219+ two = compiler .emit (Const (2 ))
2220+ compiler .emit (IntAdd (one , two ))
2221+ four = compiler .emit (Const (4 ))
2222+ compiler .emit (Return (four ))
2223+ DeadCodeElimination (compiler .fn ).run ()
2224+ self .assertEqual (
2225+ compiler .fn .to_string (InstrId ()),
2226+ """\
2227+ fn0 {
2228+ bb0 {
2229+ v0 = Const<4>
2230+ Return v0
2231+ }
2232+ }""" ,
2233+ )
2234+
2235+
21472236def opt (fn : IRFunction ) -> None :
21482237 CleanCFG (fn ).run ()
21492238 instr_type = SCCP (fn ).run ()
@@ -2152,6 +2241,7 @@ def opt(fn: IRFunction) -> None:
21522241 match instr_type [instr ]:
21532242 case CInt (int (i )):
21542243 instr .make_equal_to (Const (Int (i )))
2244+ DeadCodeElimination (fn ).run ()
21552245
21562246
21572247class OptTests (unittest .TestCase ):
@@ -2164,12 +2254,8 @@ def test_int_add(self) -> None:
21642254 """\
21652255 fn0 {
21662256 bb0 {
2167- v0 = Const<1>
2168- v1 = Const<2>
2169- v2 = Const<3>
2170- v3 = Const<5>
2171- v4 = Const<6>
2172- Return v4
2257+ v0 = Const<6>
2258+ Return v0
21732259 }
21742260}""" ,
21752261 )
0 commit comments