|
@@ -4,36 +4,6 @@ from collections import defaultdict
|
|
|
import modelverse_jit.cfg_ir as cfg_ir
|
|
|
import modelverse_jit.cfg_dominators as cfg_dominators
|
|
|
|
|
|
-def get_directly_reachable_blocks(block):
|
|
|
- """Gets the set of all blocks that can be reached by taking a single branch from the
|
|
|
- given block."""
|
|
|
- return [branch.block for branch in block.flow.branches()]
|
|
|
-
|
|
|
-def get_reachable_blocks(entry_point):
|
|
|
- """Constructs the set of all reachable vertices from the given block."""
|
|
|
- # This is a simple O(n^2) algorithm. Maybe a faster algorithm is more appropriate here.
|
|
|
- def __add_block_children(block, results):
|
|
|
- for child in get_directly_reachable_blocks(block):
|
|
|
- if child not in results:
|
|
|
- results.add(child)
|
|
|
- __add_block_children(child, results)
|
|
|
-
|
|
|
- return results
|
|
|
-
|
|
|
- return __add_block_children(entry_point, set())
|
|
|
-
|
|
|
-def get_all_reachable_blocks(entry_point):
|
|
|
- """Constructs the set of all reachable vertices, for every block that is
|
|
|
- reachable from the given entry point."""
|
|
|
- # This is a simple O(n^3) algorithm. Maybe a faster algorithm is more appropriate here.
|
|
|
- results = {}
|
|
|
- all_blocks = get_reachable_blocks(entry_point)
|
|
|
- results[entry_point] = all_blocks
|
|
|
- for block in all_blocks:
|
|
|
- if block not in results:
|
|
|
- results[block] = get_reachable_blocks(block)
|
|
|
- return results
|
|
|
-
|
|
|
def is_empty_block(block):
|
|
|
"""Tests if the given block contains no parameters or definitions."""
|
|
|
return len(block.parameters) == 0 and len(block.definitions) == 0
|
|
@@ -71,21 +41,15 @@ def optimize_flow(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
|
|
|
- for block in get_reachable_blocks(entry_point):
|
|
|
- yield block
|
|
|
-
|
|
|
def optimize_graph_flow(entry_point):
|
|
|
"""Optimizes all flow instructions in the graph defined by the given entry point."""
|
|
|
- for block in get_all_blocks(entry_point):
|
|
|
+ for block in cfg_ir.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)
|
|
|
+ predecessor_map = cfg_ir.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):
|
|
@@ -116,7 +80,7 @@ def elide_local_checks(entry_point):
|
|
|
# from a declare-local.
|
|
|
local_checks = defaultdict(set)
|
|
|
local_defs = defaultdict(set)
|
|
|
- for block in get_all_blocks(entry_point):
|
|
|
+ for block in cfg_ir.get_all_blocks(entry_point):
|
|
|
for definition in block.definitions:
|
|
|
if cfg_ir.is_value_def(definition, cfg_ir.CheckLocalExists):
|
|
|
local_checks[cfg_ir.get_def_variable(definition).node_id].add(definition)
|
|
@@ -124,7 +88,7 @@ def elide_local_checks(entry_point):
|
|
|
local_defs[cfg_ir.get_def_variable(definition).node_id].add(definition)
|
|
|
|
|
|
dominator_tree = cfg_dominators.get_dominator_tree(entry_point)
|
|
|
- reachable_blocks = get_all_reachable_blocks(entry_point)
|
|
|
+ reachable_blocks = cfg_ir.get_all_reachable_blocks(entry_point)
|
|
|
for (variable, all_checks) in local_checks.items():
|
|
|
for check in all_checks:
|
|
|
is_reachable = False
|
|
@@ -146,7 +110,7 @@ def eliminate_unused_definitions(entry_point):
|
|
|
given entry point."""
|
|
|
def_dependencies = {}
|
|
|
root_defs = set()
|
|
|
- for block in get_all_blocks(entry_point):
|
|
|
+ for block in cfg_ir.get_all_blocks(entry_point):
|
|
|
for definition in block.definitions:
|
|
|
def_dependencies[definition] = set(
|
|
|
[dep for dep in definition.get_all_dependencies()
|
|
@@ -192,7 +156,7 @@ def eliminate_trivial_phis(entry_point):
|
|
|
"""Eliminates trivial block parameters, i.e., block parameters which are really
|
|
|
aliases."""
|
|
|
phi_values = defaultdict(set)
|
|
|
- all_blocks = list(get_all_blocks(entry_point))
|
|
|
+ all_blocks = list(cfg_ir.get_all_blocks(entry_point))
|
|
|
for block in all_blocks:
|
|
|
for branch in block.flow.branches():
|
|
|
for phi, arg in zip(branch.block.parameters, branch.arguments):
|
|
@@ -217,7 +181,7 @@ def eliminate_trivial_phis(entry_point):
|
|
|
def erase_parameters(entry_point, parameters_to_erase):
|
|
|
"""Erases all arguments for the given set of parameters, and then takes out the
|
|
|
parameters themselves."""
|
|
|
- for block in get_all_blocks(entry_point):
|
|
|
+ for block in cfg_ir.get_all_blocks(entry_point):
|
|
|
for branch in block.flow.branches():
|
|
|
new_arg_list = []
|
|
|
for parameter, arg in zip(branch.block.parameters, branch.arguments):
|
|
@@ -296,7 +260,7 @@ def optimize_calls(entry_point, jit):
|
|
|
given entry point."""
|
|
|
called_globals = set()
|
|
|
global_exists_defs = defaultdict(list)
|
|
|
- all_blocks = list(get_all_blocks(entry_point))
|
|
|
+ all_blocks = list(cfg_ir.get_all_blocks(entry_point))
|
|
|
for block in all_blocks:
|
|
|
for definition in block.definitions:
|
|
|
checked_global = get_checked_global(definition)
|
|
@@ -311,7 +275,7 @@ def optimize_calls(entry_point, jit):
|
|
|
|
|
|
def simplify_values(entry_point):
|
|
|
"""Simplifies values in the control-flow graph defined by the given entry point."""
|
|
|
- for block in get_all_blocks(entry_point):
|
|
|
+ for block in cfg_ir.get_all_blocks(entry_point):
|
|
|
for definition in block.definitions:
|
|
|
def_val = cfg_ir.get_def_value(definition)
|
|
|
if isinstance(def_val, cfg_ir.Read):
|
|
@@ -328,7 +292,7 @@ def simplify_values(entry_point):
|
|
|
|
|
|
def inline_constants(entry_point):
|
|
|
"""Replaces reads of constant nodes by the literals they contain."""
|
|
|
- for block in get_all_blocks(entry_point):
|
|
|
+ for block in cfg_ir.get_all_blocks(entry_point):
|
|
|
for definition in block.definitions:
|
|
|
def_val = cfg_ir.get_def_value(definition)
|
|
|
if isinstance(def_val, cfg_ir.Read):
|