فهرست منبع

Expand indirect definitions before CFG->tree lowering

jonathanvdc 8 سال پیش
والد
کامیت
f7ffb9394d
2فایلهای تغییر یافته به همراه35 افزوده شده و 24 حذف شده
  1. 34 14
      kernel/modelverse_jit/cfg_optimization.py
  2. 1 10
      kernel/modelverse_jit/cfg_to_tree.py

+ 34 - 14
kernel/modelverse_jit/cfg_optimization.py

@@ -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)

+ 1 - 10
kernel/modelverse_jit/cfg_to_tree.py

@@ -514,15 +514,6 @@ class DefinitionScheduler(object):
                 definition_value = definition.value
                 if cfg_ir.is_value_def(definition_value, LoweringState.inline_value_types):
                     pass
-                elif isinstance(definition_value, cfg_ir.Definition):
-                    value_use = self.use(definition_value)
-                    if definition_value.has_value():
-                        if store_and_forget:
-                            def_load = self.lowering_state.create_definition_load(definition)
-                            statements.append(
-                                tree_ir.IgnoreInstruction(def_load.create_store(value_use)))
-                        else:
-                            statements.append(value_use)
                 elif (not store_and_forget
                       and definition in self.lowering_state.inlinable_definitions):
                     statements.append(self.lowering_state.lower_value(definition_value))
@@ -554,7 +545,7 @@ class DefinitionScheduler(object):
             dependent_tree = self.schedule(dependent, True)
             statements.append(dependent_tree)
 
-        statements.reverse()
+        # statements.reverse()
         statements = self.__schedule_definition(definition, store_and_forget) + statements
 
         result = tree_ir.create_block(*statements)