|
@@ -60,6 +60,17 @@ def optimize_flow(block):
|
|
|
block.flow = block.flow.branch.block.flow
|
|
|
changed = True
|
|
|
|
|
|
+ # Branches to blocks which contain nothing but a jump can be replaced by branches
|
|
|
+ # to the jump's target.
|
|
|
+ for branch in block.flow.branches():
|
|
|
+ if (is_empty_block(branch.block)
|
|
|
+ and branch.block is not block
|
|
|
+ and isinstance(branch.block.flow, cfg_ir.JumpFlow)):
|
|
|
+ new_branch = branch.block.flow.branch
|
|
|
+ branch.block = new_branch.block
|
|
|
+ branch.arguments = new_branch.arguments
|
|
|
+ changed = True
|
|
|
+
|
|
|
def get_all_blocks(entry_point):
|
|
|
"""Gets all basic blocks in the control-flow graph defined by the given entry point."""
|
|
|
yield entry_point
|
|
@@ -102,8 +113,44 @@ def elide_local_checks(entry_point):
|
|
|
# Check cannot be reached from any definition. Replace it by a 'False' literal.
|
|
|
check.redefine(cfg_ir.Literal(False))
|
|
|
|
|
|
+def eliminate_unused_definitions(entry_point):
|
|
|
+ """Tries to eliminate unused definitions in the control-flow graphb defined by the
|
|
|
+ given entry point."""
|
|
|
+ def_dependencies = {}
|
|
|
+ root_defs = set()
|
|
|
+ for block in get_all_blocks(entry_point):
|
|
|
+ for definition in block.definitions:
|
|
|
+ def_dependencies[definition] = set(
|
|
|
+ [dep for dep in definition.get_all_dependencies()
|
|
|
+ if isinstance(dep, cfg_ir.Definition)])
|
|
|
+ if definition.has_side_effects():
|
|
|
+ root_defs.add(definition)
|
|
|
+
|
|
|
+ for dep in block.flow.get_all_dependencies():
|
|
|
+ if isinstance(dep, cfg_ir.Definition):
|
|
|
+ root_defs.add(dep)
|
|
|
+
|
|
|
+ live_defs = set()
|
|
|
+ def __mark_live(definition):
|
|
|
+ if definition in live_defs:
|
|
|
+ return
|
|
|
+
|
|
|
+ live_defs.add(definition)
|
|
|
+ if definition in def_dependencies:
|
|
|
+ for dep in def_dependencies[definition]:
|
|
|
+ __mark_live(dep)
|
|
|
+
|
|
|
+ for root in root_defs:
|
|
|
+ __mark_live(root)
|
|
|
+
|
|
|
+ dead_defs = set.difference(set(def_dependencies.keys()), live_defs)
|
|
|
+ for dead_def in dead_defs:
|
|
|
+ dead_def.block.remove_definition(dead_def)
|
|
|
+
|
|
|
def optimize(entry_point):
|
|
|
"""Optimizes the control-flow graph defined by the given entry point."""
|
|
|
optimize_graph_flow(entry_point)
|
|
|
elide_local_checks(entry_point)
|
|
|
optimize_graph_flow(entry_point)
|
|
|
+ eliminate_unused_definitions(entry_point)
|
|
|
+ optimize_graph_flow(entry_point)
|