|
@@ -3,6 +3,7 @@
|
|
|
from collections import defaultdict
|
|
|
import modelverse_jit.cfg_ir as cfg_ir
|
|
|
import modelverse_jit.cfg_dominators as cfg_dominators
|
|
|
+import modelverse_jit.cfg_ssa_construction as cfg_ssa_construction
|
|
|
|
|
|
def is_empty_block(block):
|
|
|
"""Tests if the given block contains no parameters or definitions."""
|
|
@@ -139,19 +140,6 @@ def eliminate_unused_definitions(entry_point):
|
|
|
for dead_def in dead_defs:
|
|
|
dead_def.block.remove_definition(dead_def)
|
|
|
|
|
|
-def get_trivial_phi_value(parameter_def, values):
|
|
|
- """Tests if the given parameter definition is an alias for another definition.
|
|
|
- If so, then the other definition is returned; otherwise, None."""
|
|
|
- result = None
|
|
|
- for elem in values:
|
|
|
- if elem is not parameter_def:
|
|
|
- if result is None:
|
|
|
- result = elem
|
|
|
- else:
|
|
|
- return None
|
|
|
-
|
|
|
- return result
|
|
|
-
|
|
|
def eliminate_trivial_phis(entry_point):
|
|
|
"""Eliminates trivial block parameters, i.e., block parameters which are really
|
|
|
aliases."""
|
|
@@ -166,7 +154,7 @@ def eliminate_trivial_phis(entry_point):
|
|
|
for block in all_blocks:
|
|
|
block_parameters = list(block.parameters)
|
|
|
for parameter_def in block_parameters:
|
|
|
- trivial_phi_val = get_trivial_phi_value(
|
|
|
+ trivial_phi_val = cfg_ir.get_trivial_phi_value(
|
|
|
parameter_def, phi_values[parameter_def])
|
|
|
if trivial_phi_val is not None:
|
|
|
replacements.append((parameter_def, trivial_phi_val))
|
|
@@ -301,16 +289,48 @@ def inline_constants(entry_point):
|
|
|
val, = yield [("RV", [read_node.literal])]
|
|
|
definition.redefine(cfg_ir.Literal(val))
|
|
|
|
|
|
+def expand_indirect_definitions(entry_point):
|
|
|
+ """Replaces indirect definitions by the values referred to by those definitions."""
|
|
|
+ def __expand_indirect_defs(value):
|
|
|
+ dependencies = value.get_dependencies()
|
|
|
+ if len(dependencies) == 0:
|
|
|
+ return value
|
|
|
+ else:
|
|
|
+ new_dependencies = []
|
|
|
+ for dep in dependencies:
|
|
|
+ new_dep = dep
|
|
|
+ if isinstance(new_dep, cfg_ir.Definition):
|
|
|
+ while isinstance(new_dep.value, cfg_ir.Definition):
|
|
|
+ new_dep = dep.value
|
|
|
+ else:
|
|
|
+ new_dep = __expand_indirect_defs(new_dep)
|
|
|
+
|
|
|
+ new_dependencies.append(new_dep)
|
|
|
+ return value.create(new_dependencies)
|
|
|
+
|
|
|
+ for block in cfg_ir.get_all_blocks(entry_point):
|
|
|
+ block_definitions = list(block.definitions)
|
|
|
+ for definition in block_definitions:
|
|
|
+ if isinstance(definition.value, cfg_ir.Definition):
|
|
|
+ block.remove_definition(definition)
|
|
|
+ else:
|
|
|
+ definition.redefine(
|
|
|
+ __expand_indirect_defs(definition.value))
|
|
|
+
|
|
|
+ block.flow = __expand_indirect_defs(block.flow)
|
|
|
+
|
|
|
def optimize(entry_point, jit):
|
|
|
"""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_trivial_phis(entry_point)
|
|
|
+ # cfg_ssa_construction.construct_ssa_form(entry_point)
|
|
|
optimize_calls(entry_point, jit)
|
|
|
yield [("CALL_ARGS", [inline_constants, (entry_point,)])]
|
|
|
simplify_values(entry_point)
|
|
|
eliminate_unused_definitions(entry_point)
|
|
|
optimize_graph_flow(entry_point)
|
|
|
merge_blocks(entry_point)
|
|
|
+ expand_indirect_definitions(entry_point)
|
|
|
eliminate_unused_definitions(entry_point)
|