Prechádzať zdrojové kódy

Support the 'input' instruction in the JIT

jonathanvdc 8 rokov pred
rodič
commit
143ad1a6be

+ 59 - 8
kernel/modelverse_jit/jit.py

@@ -242,7 +242,6 @@ class AnalysisState(object):
 
     def analyze_output(self, instruction_id):
         """Tries to analyze the given 'output' instruction."""
-
         # The plan is to basically generate this tree:
         #
         # value = <some tree>
@@ -268,12 +267,7 @@ class AnalysisState(object):
         except primitive_functions.PrimitiveFinished as ex:
             value_local = tree_ir.StoreLocalInstruction('value', ex.result)
 
-        store_user_root = tree_ir.StoreLocalInstruction(
-            'user_root',
-            tree_ir.LoadIndexInstruction(
-                tree_ir.LoadLocalInstruction(KWARGS_PARAMETER_NAME),
-                tree_ir.LiteralInstruction('user_root')))
-
+        store_user_root = self.retrieve_user_root()
         last_output = tree_ir.StoreLocalInstruction(
             'last_output',
             tree_ir.ReadDictionaryValueInstruction(
@@ -313,6 +307,62 @@ class AnalysisState(object):
 
         raise primitive_functions.PrimitiveFinished(result)
 
+    def analyze_input(self, _):
+        """Tries to analyze the given 'input' instruction."""
+        # The plan is to generate this tree:
+        #
+        #     value = None
+        #     while True:
+        #         if value is None:
+        #             yield None # nop
+        #         else:
+        #             break
+        #
+        #         _input = yield [("RD", [user_root, "input"])]
+        #         value = yield [("RD", [_input, "value"])]
+        #
+        #     _next = yield [("RD", [_input, "next"])]
+        #     yield [("CD", [user_root, "input", _next])]
+        #     yield [("DN", [_input])]
+
+        user_root = self.retrieve_user_root()
+        _input = tree_ir.StoreLocalInstruction(
+            '_input',
+            tree_ir.ReadDictionaryValueInstruction(
+                user_root.create_load(),
+                tree_ir.LiteralInstruction('input')))
+
+        value = tree_ir.StoreLocalInstruction(
+            'value',
+            tree_ir.ReadDictionaryValueInstruction(
+                _input.create_load(),
+                tree_ir.LiteralInstruction('value')))
+
+        raise primitive_functions.PrimitiveFinished(
+            tree_ir.CompoundInstruction(
+                tree_ir.create_block(
+                    user_root,
+                    value.create_store(tree_ir.LiteralInstruction(None)),
+                    tree_ir.LoopInstruction(
+                        tree_ir.create_block(
+                            tree_ir.SelectInstruction(
+                                tree_ir.BinaryInstruction(
+                                    value.create_load(),
+                                    'is',
+                                    tree_ir.LiteralInstruction(None)),
+                                tree_ir.NopInstruction(),
+                                tree_ir.BreakInstruction()),
+                            _input,
+                            value)),
+                    tree_ir.CreateDictionaryEdgeInstruction(
+                        user_root.create_load(),
+                        tree_ir.LiteralInstruction('input'),
+                        tree_ir.ReadDictionaryValueInstruction(
+                            _input.create_load(),
+                            tree_ir.LiteralInstruction('next'))),
+                    tree_ir.DeleteNodeInstruction(_input.create_load())),
+                value.create_load()))
+
     def analyze_resolve(self, instruction_id):
         """Tries to analyze the given 'resolve' instruction."""
         var_id, = yield [("RD", [instruction_id, "var"])]
@@ -508,6 +558,7 @@ class AnalysisState(object):
         'global' : analyze_global,
         'assign' : analyze_assign,
         'access' : analyze_access,
-        'output' : analyze_output
+        'output' : analyze_output,
+        'input' : analyze_input
     }
 

+ 23 - 0
kernel/modelverse_jit/tree_ir.py

@@ -637,6 +637,29 @@ class CreateDictionaryEdgeInstruction(StateInstruction):
         """Gets this state instruction's argument list."""
         return [self.source_id, self.key, self.target_id]
 
+class DeleteNodeInstruction(StateInstruction):
+    """An instruction that deletes a node."""
+
+    def __init__(self, node_id):
+        StateInstruction.__init__(self)
+        self.node_id = node_id
+
+    def simplify(self):
+        """Applies basic simplification to this instruction and its children."""
+        return DeleteNodeInstruction(self.node_id.simplify())
+
+    def has_result(self):
+        """Tells if this instruction computes a result."""
+        return False
+
+    def get_opcode(self):
+        """Gets the opcode for this state instruction."""
+        return "DN"
+
+    def get_arguments(self):
+        """Gets this state instruction's argument list."""
+        return [self.node_id]
+
 class DeleteEdgeInstruction(StateInstruction):
     """An instruction that deletes an edge."""