Browse Source

Print lowered CFG when the code log is activated

jonathanvdc 8 years ago
parent
commit
e8b059d885
2 changed files with 40 additions and 14 deletions
  1. 32 12
      kernel/modelverse_jit/cfg_to_tree.py
  2. 8 2
      kernel/modelverse_jit/jit.py

+ 32 - 12
kernel/modelverse_jit/cfg_to_tree.py

@@ -39,6 +39,11 @@ class FlowGraphComponent(object):
         result.blocks = result.get_entry_reachable_blocks()
         return result
 
+def create_graph_component(entry_point):
+    """Creates a flow graph component from the given entry point."""
+    reachable = cfg_optimization.get_all_reachable_blocks(entry_point)
+    return FlowGraphComponent([entry_point], reachable[entry_point], reachable)
+
 class SimpleBlock(object):
     """A 'simple' block in the relooper algorithm."""
     def __init__(self, body, next_block):
@@ -51,6 +56,12 @@ class SimpleBlock(object):
             state.lower_block(self.body),
             self.next_block.lower(state))
 
+class EmptyBlock(object):
+    """An empty relooper block."""
+    def lower(self, _):
+        """Lowers this empty block to a tree."""
+        return tree_ir.EmptyInstruction()
+
 class LoopBlock(object):
     """A 'loop' block in the relooper algorithm."""
     def __init__(self, inner, next_block):
@@ -59,13 +70,10 @@ class LoopBlock(object):
 
     def lower(self, state):
         """Lowers this 'loop' block to a tree."""
-        old_loop = state.current_loop
-        state.current_loop = self
         inner = tree_ir.LoopInstruction(
             tree_ir.create_block(
                 self.inner.lower(state),
                 tree_ir.BreakInstruction()))
-        state.current_loop = old_loop
         return tree_ir.create_block(
             inner,
             self.next_block.lower(state))
@@ -82,7 +90,7 @@ class MultipleBlock(object):
         for entry, block in self.handled_blocks:
             result = tree_ir.SelectInstruction(
                 tree_ir.BinaryInstruction(
-                    state.label_variable,
+                    tree_ir.LoadLocalInstruction(state.label_variable),
                     '==',
                     tree_ir.LiteralInstruction(entry.index)),
                 block.lower(state),
@@ -102,13 +110,10 @@ class MultipleLoopBlock(MultipleBlock):
 
     def lower(self, state):
         """Lowers this 'multiple' block to a tree."""
-        old_loop = state.current_loop
-        state.current_loop = self
         inner = tree_ir.LoopInstruction(
             tree_ir.create_block(
                 self.lower_handled_blocks(state),
                 tree_ir.BreakInstruction()))
-        state.current_loop = old_loop
         return tree_ir.create_block(
             inner,
             self.next_block.lower(state))
@@ -260,8 +265,11 @@ def to_relooper_multiple_or_loop(graph_component):
 
 def reloop(graph_component):
     """Applies the relooper algorithm to the given graph component."""
-    reachable_set = graph_component.get_entry_reachable_blocks()
     entry_blocks = graph_component.entry_blocks
+    if len(entry_blocks) == 0:
+        return EmptyBlock()
+
+    reachable_set = graph_component.get_entry_reachable_blocks()
     if len(entry_blocks) == 1 and entry_blocks[0] not in reachable_set:
         graph_component.blocks.remove(entry_blocks[0])
         return SimpleBlock(
@@ -276,6 +284,17 @@ def reloop(graph_component):
     else:
         return to_relooper_multiple_or_loop(graph_component)
 
+def reloop_trivial(graph_component):
+    """Converts the given control-flow graph to a 'multiple' block that contains only 'simple'
+       blocks."""
+    return MultipleLoopBlock(
+        [(block, SimpleBlock(block, EmptyBlock())) for block in graph_component.blocks],
+        EmptyBlock())
+
+def reloop_function_body(entry_point):
+    """Reloops the control-flow graph defined by the given entry point."""
+    return reloop_trivial(create_graph_component(entry_point))
+
 class LoweringState(object):
     """Stores information related to the relooper->tree conversion."""
     def __init__(self, jit):
@@ -326,7 +345,7 @@ class LoweringState(object):
         for definition in block.definitions:
             statements.append(self.lower_definition(definition))
         statements.append(self.lower_flow(block.flow))
-        return tree_ir.create_block(statements)
+        return tree_ir.create_block(*statements)
 
     def lower_definition(self, definition):
         """Lowers the given definition to a tree."""
@@ -418,7 +437,8 @@ class LoweringState(object):
 
     def lower_free_root_node(self, value):
         """Lowers a 'free-root-node' value."""
-        return tree_ir.DeleteEdgeInstruction(self.__get_root_edge_name(value.root_node))
+        return tree_ir.DeleteEdgeInstruction(
+            tree_ir.LoadLocalInstruction(self.__get_root_edge_name(value.root_node)))
 
     def lower_load_pointer(self, value):
         """Lowers a 'load' value."""
@@ -442,7 +462,7 @@ class LoweringState(object):
 
     def lower_output(self, value):
         """Lowers an 'output' value."""
-        return bytecode_to_tree.create_output(self.load_definition(value.output_value))
+        return bytecode_to_tree.create_output(self.load_definition(value.value))
 
     def lower_direct_call(self, value):
         """Lowers a direct function call."""
@@ -522,7 +542,7 @@ class LoweringState(object):
 
     def lower_throw(self, flow):
         """Lowers the given 'throw' flow instruction to a tree."""
-        return tree_ir.RaiseInstruction(self.load_definition(flow.value))
+        return tree_ir.RaiseInstruction(self.load_definition(flow.exception))
 
     def lower_unreachable(self, _):
         """Lowers the given 'unreachable' flow instruction to a tree."""

+ 8 - 2
kernel/modelverse_jit/jit.py

@@ -1,12 +1,12 @@
+import keyword
 import modelverse_kernel.primitives as primitive_functions
-import modelverse_jit.bytecode_ir as bytecode_ir
 import modelverse_jit.bytecode_parser as bytecode_parser
 import modelverse_jit.bytecode_to_tree as bytecode_to_tree
 import modelverse_jit.bytecode_to_cfg as bytecode_to_cfg
 import modelverse_jit.cfg_optimization as cfg_optimization
+import modelverse_jit.cfg_to_tree as cfg_to_tree
 import modelverse_jit.tree_ir as tree_ir
 import modelverse_jit.runtime as jit_runtime
-import keyword
 
 # Import JitCompilationFailedException because it used to be defined
 # in this module.
@@ -448,6 +448,12 @@ class ModelverseJit(object):
                             str,
                             cfg_optimization.get_all_reachable_blocks(
                                 bytecode_analyzer.entry_point)))))
+            cfg_lowerer = cfg_to_tree.LoweringState(self)
+            lowered_body = cfg_to_tree.reloop_function_body(
+                bytecode_analyzer.entry_point).lower(cfg_lowerer)
+            self.jit_code_log_function(
+                "Lowered CFG for function '%s' at '%d':\n%s" % (
+                    function_name, body_id, lowered_body))
 
         yield [("END_TRY", [])]
         del self.compilation_dependencies[body_id]