Browse Source

Define CFG JIT intrinsics for common string operations

jonathanvdc 8 years ago
parent
commit
270990122b

+ 20 - 0
kernel/modelverse_jit/cfg_ir.py

@@ -513,6 +513,9 @@ READ_DICT_KEYS_MACRO_NAME = 'read_dict_keys'
 REVERSE_LIST_MACRO_NAME = 'reverse_list'
 """The name of the list reversal macro."""
 
+INDEX_MACRO_NAME = 'index'
+"""The name of the macro that indexes a collection with a key."""
+
 GC_PROTECT_MACRO_NAME = 'gc_protect'
 """The name of the macro that unconditionally protects its first argument from the GC by
    drawing an edge between it and the second argument."""
@@ -919,6 +922,23 @@ def create_nop():
         calling_convention=MACRO_IO_CALLING_CONVENTION,
         has_value=False)
 
+def create_index(collection, key):
+    """Creates a value that loads the element with the specified key in the given collection."""
+    return DirectFunctionCall(
+        INDEX_MACRO_NAME,
+        [('collection', collection),
+         ('key', key)],
+        calling_convention=MACRO_POSITIONAL_CALLING_CONVENTION,
+        has_value=True, has_side_effects=False)
+
+def create_pure_simple_call(target_name, argument):
+    """Creates a pure, simple positional call to the function with the given name."""
+    return DirectFunctionCall(
+        target_name,
+        [('argument', argument)],
+        calling_convention=SIMPLE_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."""

+ 1 - 0
kernel/modelverse_jit/cfg_to_tree.py

@@ -997,6 +997,7 @@ class LoweringState(object):
     macro_lowerings = {
         cfg_ir.PRINT_MACRO_NAME: tree_ir.PrintInstruction,
         cfg_ir.READ_DICT_KEYS_MACRO_NAME: tree_ir.ReadDictionaryKeysInstruction,
+        cfg_ir.INDEX_MACRO_NAME: tree_ir.LoadIndexInstruction,
         cfg_ir.REVERSE_LIST_MACRO_NAME:
         lambda seq:
         tree_ir.ListSliceInstruction(seq, None, None, tree_ir.LiteralInstruction(-1)),

+ 45 - 0
kernel/modelverse_jit/intrinsics.py

@@ -296,6 +296,51 @@ MISC_CFG_INTRINSICS = {
                 original_def.insert_before(
                     cfg_ir.Binary(a, '!=', b)))),
 
+
+    # String operations
+    'string_get' :
+        lambda original_def, a, b:
+        original_def.redefine(
+            cfg_ir.CreateNode(
+                original_def.insert_before(
+                    cfg_ir.create_index(
+                        original_def.insert_before(cfg_ir.Read(a)),
+                        original_def.insert_before(cfg_ir.Read(b)))))),
+    'string_len' :
+        lambda original_def, a:
+        original_def.redefine(
+            cfg_ir.CreateNode(
+                original_def.insert_before(
+                    cfg_ir.create_pure_simple_call(
+                        'len',
+                        original_def.insert_before(cfg_ir.Read(a)))))),
+    'string_join' :
+        lambda original_def, a, b:
+        original_def.redefine(
+            cfg_ir.CreateNode(
+                original_def.insert_before(
+                    cfg_ir.Binary(
+                        original_def.insert_before(
+                            cfg_ir.create_pure_simple_call(
+                                'str',
+                                original_def.insert_before(cfg_ir.Read(a)))),
+                        '+',
+                        original_def.insert_before(
+                            cfg_ir.create_pure_simple_call(
+                                'str',
+                                original_def.insert_before(cfg_ir.Read(b)))))))),
+    'string_startswith' :
+        lambda original_def, a, b:
+        original_def.redefine(
+            cfg_ir.CreateNode(
+                original_def.insert_before(
+                    cfg_ir.DirectFunctionCall(
+                        'startswith',
+                        [('self', original_def.insert_before(cfg_ir.Read(a))),
+                         ('substring', original_def.insert_before(cfg_ir.Read(b)))],
+                        calling_convention=cfg_ir.SELF_POSITIONAL_CALLING_CONVENTION,
+                        has_value=True, has_side_effects=False)))),
+
     # State creation
     'create_node' :
         lambda original_def:

+ 2 - 4
kernel/modelverse_jit/jit.py

@@ -415,11 +415,9 @@ class ModelverseJit(object):
             original_def.redefine(
                 cfg_ir.CreateNode(
                     original_def.insert_before(
-                        cfg_ir.DirectFunctionCall(
+                        cfg_ir.create_pure_simple_call(
                             target_type.__name__,
-                            [('value', original_def.insert_before(cfg_ir.Read(a)))],
-                            calling_convention=cfg_ir.SIMPLE_POSITIONAL_CALLING_CONVENTION,
-                            has_value=True, has_side_effects=False)))))
+                            original_def.insert_before(cfg_ir.Read(a)))))))
 
     def jit_signature(self, body_id):
         """Acquires the signature for the given body id node, which consists of the