ソースを参照

Make dict_in, dict_in_node CFG JIT intrinsics

jonathanvdc 8 年 前
コミット
88a822eb45

+ 22 - 0
kernel/modelverse_jit/cfg_ir.py

@@ -510,6 +510,12 @@ NOP_MACRO_NAME = 'nop'
 READ_DICT_KEYS_MACRO_NAME = 'read_dict_keys'
 """The name of the macro that reads all keys from a dictionary."""
 
+READ_DICT_VALUE_MACRO_NAME = "read_dict_value"
+"""The name of the macro that reads the value for a given key from a dictionary."""
+
+READ_DICT_NODE_MACRO_NAME = "read_dict_node"
+"""The name of the macro that reads the node for a given key from a dictionary."""
+
 READ_OUTGOING_EDGES_MACRO_NAME = 'read_outgoing_edges'
 """The name of the macro that reads a node's outgoing edges as a list."""
 
@@ -950,6 +956,22 @@ def create_read_outgoing_edges(source_node):
         calling_convention=MACRO_POSITIONAL_CALLING_CONVENTION,
         has_value=True, has_side_effects=False)
 
+def create_read_dict_value(dict_node, key):
+    """Creates a call that reads the value with the given key in the specified dictionary."""
+    return DirectFunctionCall(
+        READ_DICT_VALUE_MACRO_NAME,
+        [('dict', dict_node), ('key', key)],
+        calling_convention=MACRO_POSITIONAL_CALLING_CONVENTION,
+        has_value=True, has_side_effects=False)
+
+def create_read_dict_node(dict_node, key):
+    """Creates a call that reads the node with the given key in the specified dictionary."""
+    return DirectFunctionCall(
+        READ_DICT_NODE_MACRO_NAME,
+        [('dict', dict_node), ('key', key)],
+        calling_convention=MACRO_POSITIONAL_CALLING_CONVENTION,
+        has_value=True, has_side_effects=False)
+
 def create_gc_protect(protected_value, root):
     """Creates a value that protects the first from the GC by drawing an
        edge between it and the given root."""

+ 2 - 0
kernel/modelverse_jit/cfg_to_tree.py

@@ -998,6 +998,8 @@ class LoweringState(object):
         cfg_ir.PRINT_MACRO_NAME: tree_ir.PrintInstruction,
         cfg_ir.READ_OUTGOING_EDGES_MACRO_NAME: tree_ir.ReadOutgoingEdgesInstruction,
         cfg_ir.READ_DICT_KEYS_MACRO_NAME: tree_ir.ReadDictionaryKeysInstruction,
+        cfg_ir.READ_DICT_VALUE_MACRO_NAME: tree_ir.ReadDictionaryValueInstruction,
+        cfg_ir.READ_DICT_NODE_MACRO_NAME: tree_ir.ReadDictionaryNodeInstruction,
         cfg_ir.INDEX_MACRO_NAME: tree_ir.LoadIndexInstruction,
         cfg_ir.REVERSE_LIST_MACRO_NAME:
         lambda seq:

+ 38 - 0
kernel/modelverse_jit/intrinsics.py

@@ -308,6 +308,42 @@ def __read_nr_out_cfg(original_def, a):
                     original_def.insert_before(
                         cfg_ir.create_read_outgoing_edges(a))))))
 
+def __dict_in_cfg(original_def, a, b):
+    # Original definition:
+    #
+    # def dict_in(a, b, **remainder):
+    #     b_value, = yield [("RV", [b])]
+    #     value, = yield [("RD", [a, b_value])]
+    #     is_in = value is not None
+    #     result, = yield [("CNV", [is_in])]
+    #     raise PrimitiveFinished(result)
+
+    original_def.redefine(
+        cfg_ir.CreateNode(
+            original_def.insert_before(
+                cfg_ir.Binary(
+                    original_def.insert_before(
+                        cfg_ir.create_read_dict_value(
+                            a, original_def.insert_before(cfg_ir.Read(b)))),
+                    'is not',
+                    original_def.insert_before(cfg_ir.Literal(None))))))
+
+def __dict_in_node_cfg(original_def, a, b):
+    # Original definition:
+    #
+    # def dict_in_node(a, b, **remainder):
+    #     value, = yield [("RDN", [a, b])]
+    #     result, = yield [("CNV", [value is not None])]
+    #     raise PrimitiveFinished(result)
+
+    original_def.redefine(
+        cfg_ir.CreateNode(
+            original_def.insert_before(
+                cfg_ir.Binary(
+                    original_def.insert_before(cfg_ir.create_read_dict_node(a, b)),
+                    'is not',
+                    original_def.insert_before(cfg_ir.Literal(None))))))
+
 MISC_CFG_INTRINSICS = {
     # Reference equality
     'element_eq' :
@@ -383,6 +419,8 @@ MISC_CFG_INTRINSICS = {
 
     # Dictionary operations
     'dict_len' : __read_nr_out_cfg,
+    'dict_in' : __dict_in_cfg,
+    'dict_in_node' : __dict_in_node_cfg,
 
     # List operations
     'list_len' : __read_nr_out_cfg

+ 15 - 0
kernel/modelverse_jit/tree_ir.py

@@ -1405,6 +1405,21 @@ class ReadDictionaryValueInstruction(StateInstruction):
         """Gets this state instruction's argument list."""
         return [self.node_id, self.key]
 
+class ReadDictionaryNodeInstruction(StateInstruction):
+    """An instruction that reads a dictionary node."""
+    def __init__(self, node_id, key):
+        StateInstruction.__init__(self)
+        self.node_id = node_id
+        self.key = key
+
+    def get_opcode(self):
+        """Gets the opcode for this state instruction."""
+        return "RDN"
+
+    def get_arguments(self):
+        """Gets this state instruction's argument list."""
+        return [self.node_id, self.key]
+
 class ReadDictionaryEdgeInstruction(StateInstruction):
     """An instruction that reads a dictionary edge."""
     def __init__(self, node_id, key):