Просмотр исходного кода

Implement CFG flow->tree IR lowering

jonathanvdc 8 лет назад
Родитель
Сommit
b43835ab22
1 измененных файлов с 67 добавлено и 16 удалено
  1. 67 16
      kernel/modelverse_jit/cfg_to_tree.py

+ 67 - 16
kernel/modelverse_jit/cfg_to_tree.py

@@ -3,6 +3,7 @@
 import modelverse_jit.cfg_ir as cfg_ir
 import modelverse_jit.cfg_optimization as cfg_optimization
 import modelverse_jit.tree_ir as tree_ir
+import modelverse_jit.runtime as jit_runtime
 
 # The CFG deconstruction code here is based on the relooper algorithm
 # as detailed in https://github.com/kripken/Relooper/blob/master/paper.pdf
@@ -82,7 +83,7 @@ class MultipleBlock(object):
                 tree_ir.BinaryInstruction(
                     state.label_variable,
                     '==',
-                    tree_ir.LiteralInstruction(state.get_label_value(entry))),
+                    tree_ir.LiteralInstruction(entry.index)),
                 block.lower(state),
                 result)
         return result
@@ -279,27 +280,26 @@ class LoweringState(object):
     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]
+    def __create_value_load(self, value):
+        """Creates a tree that loads the given value."""
+        if value.has_value():
+            if isinstance(value, cfg_ir.Literal):
+                return tree_ir.LiteralInstruction(value.literal)
+            else:
+                return tree_ir.LoadLocalInstruction(None)
         else:
-            result = len(self.label_map)
-            self.label_map[block] = result
-            return result
+            return tree_ir.LiteralInstruction(None)
 
     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()
+        result = self.__create_value_load(definition.value)
+        self.definition_loads[definition] = result
+        return result
 
     def lower_block(self, block):
         """Lowers the given (relooped) block to a tree."""
@@ -313,8 +313,9 @@ class LoweringState(object):
         """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)
+        def_load = self.load_definition(definition)
+        if isinstance(def_load, tree_ir.LocalInstruction):
+            return def_load.create_store(tree_instruction)
         else:
             return tree_instruction
 
@@ -324,4 +325,54 @@ class LoweringState(object):
 
     def lower_flow(self, flow):
         """Lowers the given (relooped) flow instruction to a tree."""
-        raise NotImplementedError()
+        flow_type = type(flow)
+        if flow_type in LoweringState.flow_lowerings:
+            return LoweringState.flow_lowerings[flow_type](self, flow)
+        else:
+            raise jit_runtime.JitCompilationFailedException(
+                "Unknown CFG flow instruction: '%s'" % flow)
+
+    def lower_jump(self, flow):
+        """Lowers the given 'jump' flow instruction to a tree."""
+        return self.lower_branch(flow.branch)
+
+    def lower_select(self, flow):
+        """Lowers the given 'select' flow instruction to a tree."""
+        return tree_ir.SelectInstruction(
+            self.load_definition(flow.condition),
+            self.lower_branch(flow.if_branch),
+            self.lower_branch(flow.else_branch))
+
+    def lower_return(self, flow):
+        """Lowers the given 'return' flow instruction to a tree."""
+        return tree_ir.ReturnInstruction(self.load_definition(flow.value))
+
+    def lower_unreachable(self, _):
+        """Lowers the given 'unreachable' flow instruction to a tree."""
+        return tree_ir.EmptyInstruction()
+
+    def lower_break(self, _):
+        """Lowers the given 'break' flow instruction to a tree."""
+        return tree_ir.BreakInstruction()
+
+    def lower_continue(self, _):
+        """Lowers the given 'continue' flow instruction to a tree."""
+        return tree_ir.ContinueInstruction()
+
+    def lower_branch(self, branch):
+        """Lowers the given (relooped) branch to a tree."""
+        for param, arg in zip(branch.block.parameters, branch.arguments):
+            self.load_definition(param).create_store(self.load_definition(arg))
+
+        return tree_ir.StoreLocalInstruction(
+            self.label_variable,
+            tree_ir.LiteralInstruction(branch.block.index))
+
+    flow_lowerings = {
+        cfg_ir.JumpFlow : lower_jump,
+        cfg_ir.SelectFlow : lower_select,
+        cfg_ir.ReturnFlow : lower_return,
+        cfg_ir.UnreachableFlow : lower_unreachable,
+        BreakFlow : lower_break,
+        ContinueFlow : lower_continue
+    }