diff --git a/artiq/compiler/transforms/dead_code_eliminator.py b/artiq/compiler/transforms/dead_code_eliminator.py index dfe5ccf6c..9c5a54bb0 100644 --- a/artiq/compiler/transforms/dead_code_eliminator.py +++ b/artiq/compiler/transforms/dead_code_eliminator.py @@ -14,12 +14,24 @@ class DeadCodeEliminator: self.process_function(func) def process_function(self, func): - for block in list(func.basic_blocks): - if not any(block.predecessors()) and block != func.entry(): - for use in set(block.uses): - if isinstance(use, ir.SetLocal): - use.erase() - self.remove_block(block) + modified = True + while modified: + modified = False + for block in list(func.basic_blocks): + if not any(block.predecessors()) and block != func.entry(): + self.remove_block(block) + modified = True + + modified = True + while modified: + modified = False + for insn in func.instructions(): + if isinstance(insn, (ir.Phi, ir.Alloc, ir.GetLocal, ir.GetConstructor, + ir.GetAttr, ir.GetElem, ir.Coerce, ir.Arith, + ir.Compare, ir.Closure, ir.Select, ir.Quote)) \ + and not any(insn.uses): + insn.erase() + modified = True def remove_block(self, block): # block.uses are updated while iterating @@ -28,6 +40,9 @@ class DeadCodeEliminator: use.remove_incoming_block(block) if not any(use.operands): self.remove_instruction(use) + elif isinstance(use, ir.SetLocal): + # setlocal %env, %block is only used for lowering finally + use.erase() else: assert False @@ -39,5 +54,7 @@ class DeadCodeEliminator: use.remove_incoming_value(insn) if not any(use.operands): self.remove_instruction(use) + else: + assert False insn.erase()