소스 검색

Define CFG JIT intrinsics for common string operations

jonathanvdc 8 년 전
부모
커밋
270990122b
4개의 변경된 파일68개의 추가작업 그리고 4개의 파일을 삭제
  1. 20 0
      kernel/modelverse_jit/cfg_ir.py
  2. 1 0
      kernel/modelverse_jit/cfg_to_tree.py
  3. 45 0
      kernel/modelverse_jit/intrinsics.py
  4. 2 4
      kernel/modelverse_jit/jit.py

+ 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'
 REVERSE_LIST_MACRO_NAME = 'reverse_list'
 """The name of the list reversal macro."""
 """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'
 GC_PROTECT_MACRO_NAME = 'gc_protect'
 """The name of the macro that unconditionally protects its first argument from the GC by
 """The name of the macro that unconditionally protects its first argument from the GC by
    drawing an edge between it and the second argument."""
    drawing an edge between it and the second argument."""
@@ -919,6 +922,23 @@ def create_nop():
         calling_convention=MACRO_IO_CALLING_CONVENTION,
         calling_convention=MACRO_IO_CALLING_CONVENTION,
         has_value=False)
         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):
 def create_gc_protect(protected_value, root):
     """Creates a value that protects the first from the GC by drawing an
     """Creates a value that protects the first from the GC by drawing an
        edge between it and the given root."""
        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 = {
     macro_lowerings = {
         cfg_ir.PRINT_MACRO_NAME: tree_ir.PrintInstruction,
         cfg_ir.PRINT_MACRO_NAME: tree_ir.PrintInstruction,
         cfg_ir.READ_DICT_KEYS_MACRO_NAME: tree_ir.ReadDictionaryKeysInstruction,
         cfg_ir.READ_DICT_KEYS_MACRO_NAME: tree_ir.ReadDictionaryKeysInstruction,
+        cfg_ir.INDEX_MACRO_NAME: tree_ir.LoadIndexInstruction,
         cfg_ir.REVERSE_LIST_MACRO_NAME:
         cfg_ir.REVERSE_LIST_MACRO_NAME:
         lambda seq:
         lambda seq:
         tree_ir.ListSliceInstruction(seq, None, None, tree_ir.LiteralInstruction(-1)),
         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(
                 original_def.insert_before(
                     cfg_ir.Binary(a, '!=', b)))),
                     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
     # State creation
     'create_node' :
     'create_node' :
         lambda original_def:
         lambda original_def:

+ 2 - 4
kernel/modelverse_jit/jit.py

@@ -415,11 +415,9 @@ class ModelverseJit(object):
             original_def.redefine(
             original_def.redefine(
                 cfg_ir.CreateNode(
                 cfg_ir.CreateNode(
                     original_def.insert_before(
                     original_def.insert_before(
-                        cfg_ir.DirectFunctionCall(
+                        cfg_ir.create_pure_simple_call(
                             target_type.__name__,
                             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):
     def jit_signature(self, body_id):
         """Acquires the signature for the given body id node, which consists of the
         """Acquires the signature for the given body id node, which consists of the