|
@@ -82,6 +82,33 @@ def optimize_graph_flow(entry_point):
|
|
|
for block in get_all_blocks(entry_point):
|
|
|
optimize_flow(block)
|
|
|
|
|
|
+def merge_blocks(entry_point):
|
|
|
+ """Merges blocks which have exactly one predecessor with said predecessor, if the
|
|
|
+ predecessor has a jump flow instruction."""
|
|
|
+ predecessor_map = cfg_dominators.get_all_predecessor_blocks(entry_point)
|
|
|
+ queue = list(predecessor_map.keys())
|
|
|
+ def __do_merge(source, target):
|
|
|
+ for target_param, branch_arg in zip(target.parameters, source.flow.branch.arguments):
|
|
|
+ source.append_definition(target_param)
|
|
|
+ target_param.redefine(branch_arg)
|
|
|
+
|
|
|
+ for target_def in target.definitions:
|
|
|
+ source.append_definition(target_def)
|
|
|
+
|
|
|
+ source.flow = target.flow
|
|
|
+ for pred_set in predecessor_map.values():
|
|
|
+ if target in pred_set:
|
|
|
+ pred_set.remove(target)
|
|
|
+ pred_set.add(source)
|
|
|
+
|
|
|
+ while len(queue) > 0:
|
|
|
+ block = queue.pop()
|
|
|
+ preds = predecessor_map[block]
|
|
|
+ if len(preds) == 1:
|
|
|
+ single_pred = next(iter(preds))
|
|
|
+ if isinstance(single_pred.flow, cfg_ir.JumpFlow):
|
|
|
+ __do_merge(single_pred, block)
|
|
|
+
|
|
|
def elide_local_checks(entry_point):
|
|
|
"""Tries to elide redundant checks on local variables."""
|
|
|
# The plan here is to replace all check-local-exists defs by literals if
|
|
@@ -154,3 +181,4 @@ def optimize(entry_point):
|
|
|
optimize_graph_flow(entry_point)
|
|
|
eliminate_unused_definitions(entry_point)
|
|
|
optimize_graph_flow(entry_point)
|
|
|
+ merge_blocks(entry_point)
|