瀏覽代碼

Implement more CFG->tree functionality

jonathanvdc 8 年之前
父節點
當前提交
a6053705e0
共有 1 個文件被更改,包括 114 次插入5 次删除
  1. 114 5
      kernel/modelverse_jit/cfg_to_tree.py

+ 114 - 5
kernel/modelverse_jit/cfg_to_tree.py

@@ -43,18 +43,74 @@ class SimpleBlock(object):
         self.body = body
         self.next_block = next_block
 
+    def lower(self, state):
+        """Lowers this 'simple' block to a tree."""
+        return tree_ir.create_block(
+            state.lower_block(self.body),
+            self.next_block.lower(state))
+
 class LoopBlock(object):
     """A 'loop' block in the relooper algorithm."""
     def __init__(self, inner, next_block):
         self.inner = inner
         self.next_block = next_block
 
+    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))
+
 class MultipleBlock(object):
-    """A 'multiple' block in the relooper algorithm."""
+    """A 'multiple' block in the relooper algorithm that does _not_ require a loop."""
     def __init__(self, handled_blocks, next_block):
         self.handled_blocks = handled_blocks
         self.next_block = next_block
 
+    def lower_handled_blocks(self, state):
+        """Lowers the handled blocks of this 'multiple' block to a tree."""
+        result = tree_ir.EmptyInstruction()
+        for entry, block in self.handled_blocks:
+            result = tree_ir.SelectInstruction(
+                tree_ir.BinaryInstruction(
+                    state.label_variable,
+                    '==',
+                    tree_ir.LiteralInstruction(state.get_label_value(entry))),
+                block.lower(state),
+                result)
+        return result
+
+    def lower(self, state):
+        """Lowers this 'multiple' block to a tree."""
+        return tree_ir.create_block(
+            self.lower_handled_blocks(state),
+            self.next_block.lower(state))
+
+class MultipleLoopBlock(MultipleBlock):
+    """A 'multiple' block in the relooper algorithm."""
+    def __init__(self, handled_blocks, next_block):
+        MultipleBlock.__init__(self, handled_blocks, next_block)
+
+    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))
+
 class ContinueFlow(cfg_ir.FlowInstruction):
     """Represents a control flow instruction which continues to the next loop iteration."""
     def __init__(self, loop):
@@ -95,6 +151,9 @@ def solipsize(graph_component, loop, entry_blocks, next_blocks):
     all_blocks = set()
     reachable_from_inner = set()
     for block in graph_component.blocks:
+        if block in next_blocks:
+            continue
+
         all_blocks.add(block)
         for branch in block.flow.branches():
             if branch.block in entry_blocks:
@@ -137,10 +196,8 @@ def to_relooper_loop(graph_component):
         else:
             next_blocks.append(block)
 
-    inner_component = FlowGraphComponent(
-        entry_blocks, inner_blocks, graph_component.reachable)
     reachable_from_inner, inner_component = solipsize(
-        inner_component, result, entry_blocks, next_blocks)
+        graph_component, result, entry_blocks, next_blocks)
     result.inner = reloop(inner_component)
 
     next_component = FlowGraphComponent(
@@ -188,7 +245,7 @@ def to_relooper_multiple_or_loop(graph_component):
 
     next_entries.difference_update(exclusive_entries.keys())
 
-    result = MultipleBlock({}, None)
+    result = MultipleLoopBlock({}, None)
     for entry, exclusive_blocks in exclusive_entries.items():
         other_blocks = set(graph_component.blocks)
         other_blocks.difference_update(exclusive_blocks)
@@ -216,3 +273,55 @@ def reloop(graph_component):
         return to_relooper_loop(graph_component)
     else:
         return to_relooper_multiple_or_loop(graph_component)
+
+class LoweringState(object):
+    """Stores information related to the relooper->tree conversion."""
+    def __init__(self, jit):
+        self.jit = jit
+        self.label_variable = tree_ir.VariableName('__label')
+        self.label_map = {}
+        self.definition_loads = {}
+
+    def get_label_value(self, block):
+        """Gets the label value for the given block."""
+        if block in self.label_map:
+            return self.label_map[block]
+        else:
+            result = len(self.label_map)
+            self.label_map[block] = result
+            return result
+
+    def load_definition(self, definition):
+        """Loads the given definition's variable."""
+        if definition in self.definition_loads:
+            return self.definition_loads[definition]
+
+        if definition.instruction.has_value():
+            raise NotImplementedError()
+        else:
+            raise NotImplementedError()
+
+    def lower_block(self, block):
+        """Lowers the given (relooped) block to a tree."""
+        statements = []
+        for definition in block.definitions:
+            statements.append(self.lower_definition(definition))
+        statements.append(self.lower_flow(block.flow))
+        return tree_ir.create_block(statements)
+
+    def lower_definition(self, definition):
+        """Lowers the given definition to a tree."""
+        instruction = definition.value
+        tree_instruction = self.lower_instruction(instruction)
+        if instruction.has_value():
+            return self.load_definition(definition).create_store(tree_instruction)
+        else:
+            return tree_instruction
+
+    def lower_instruction(self, instruction):
+        """Lowers the given instruction to a tree."""
+        raise NotImplementedError()
+
+    def lower_flow(self, flow):
+        """Lowers the given (relooped) flow instruction to a tree."""
+        raise NotImplementedError()