فهرست منبع

Apply CFG JIT intrinsics to function calls

jonathanvdc 8 سال پیش
والد
کامیت
585d8a49b6
2فایلهای تغییر یافته به همراه44 افزوده شده و 11 حذف شده
  1. 26 0
      kernel/modelverse_jit/cfg_ir.py
  2. 18 11
      kernel/modelverse_jit/cfg_optimization.py

+ 26 - 0
kernel/modelverse_jit/cfg_ir.py

@@ -43,6 +43,23 @@ class BasicBlock(object):
         self.renumber_definitions()
         return result
 
+    def insert_definition_before(self, anchor, value):
+        """Inserts the second definition or value before the first definition."""
+        index = None
+        for i, definition in enumerate(self.definitions):
+            if definition.definition_index == anchor.definition_index:
+                index = i
+
+        if index is None:
+            raise ValueError(
+                'Cannot insert a definition because the anchor '
+                'is not defined in this block.')
+
+        result = self.create_definition(value)
+        self.definitions.insert(index, result)
+        self.renumber_definitions()
+        return result
+
     def append_definition(self, value):
         """Defines the given value in this basic block."""
         result = self.create_definition(value)
@@ -110,6 +127,14 @@ class Definition(object):
         """Tests if this definition produces any side-effects."""
         return self.value.has_side_effects()
 
+    def has_value(self):
+        """Tells if this definition produces a result that is not None."""
+        return self.value.has_value()
+
+    def insert_before(self, value):
+        """Inserts the given value or definition before this definition."""
+        return self.block.insert_definition_before(self, value)
+
     def ref_str(self):
         """Gets a string that represents a reference to this definition."""
         return '$%d' % self.index
@@ -627,3 +652,4 @@ def get_literal_value(value):
 def get_literal_def_value(def_or_value):
     """Gets the value of the given literal value or definition with an underlying literal."""
     return apply_to_value(get_literal_value, def_or_value)
+

+ 18 - 11
kernel/modelverse_jit/cfg_optimization.py

@@ -228,6 +228,12 @@ def erase_parameters(entry_point, parameters_to_erase):
     for parameter_def in parameters_to_erase:
         parameter_def.block.remove_parameter(parameter_def)
 
+def apply_cfg_intrinsic(intrinsic_function, original_definition, named_args):
+    """Applies the given intrinsic to the given sequence of named arguments."""
+    kwargs = dict(named_args)
+    kwargs['original_def'] = original_definition
+    return intrinsic_function(**kwargs)
+
 def try_redefine_as_direct_call(definition, jit, called_globals):
     """Tries to redefine the given indirect call definition as a direct call."""
     call = cfg_ir.get_def_value(definition)
@@ -239,18 +245,19 @@ def try_redefine_as_direct_call(definition, jit, called_globals):
         loaded_ptr = cfg_ir.get_def_value(target.pointer)
         if isinstance(loaded_ptr, cfg_ir.ResolveGlobal):
             resolved_var_name = loaded_ptr.variable.name
-
-            # # Try to resolve the callee as an intrinsic.
-            # intrinsic = jit.get_intrinsic(resolved_var_name)
-            # if intrinsic is not None:
-            #     return redefine_as_intrinsic(definition, intrinsic, call.argument_list)
-
-            # Otherwise, build a thunk.
-            thunk_name = jit.jit_thunk_global(resolved_var_name)
-            definition.redefine(
-                cfg_ir.DirectFunctionCall(
-                    thunk_name, call.argument_list, cfg_ir.JIT_CALLING_CONVENTION))
             called_globals.add(loaded_ptr)
+
+            # Try to resolve the callee as an intrinsic.
+            intrinsic = jit.get_cfg_intrinsic(resolved_var_name)
+            if intrinsic is not None:
+                apply_cfg_intrinsic(intrinsic, definition, call.argument_list)
+            else:
+                # Otherwise, build a thunk.
+                thunk_name = jit.jit_thunk_global(resolved_var_name)
+                definition.redefine(
+                    cfg_ir.DirectFunctionCall(
+                        thunk_name, call.argument_list, cfg_ir.JIT_CALLING_CONVENTION))
+                called_globals.add(loaded_ptr)
     elif isinstance(target, cfg_ir.Literal):
         node_id = target.literal
         thunk_name = jit.jit_thunk_constant(node_id)