Browse Source

Support primitive calls to constants in the JIT

jonathanvdc 8 years ago
parent
commit
46621cc480
1 changed files with 19 additions and 2 deletions
  1. 19 2
      kernel/modelverse_jit/jit.py

+ 19 - 2
kernel/modelverse_jit/jit.py

@@ -120,7 +120,9 @@ class ModelverseJit(object):
     def lookup_compiled_function(self, name):
         """Looks up a compiled function by name. Returns a matching function,
            or None if no function was found."""
-        if name in self.jit_globals:
+        if name is None:
+            return None
+        elif name in self.jit_globals:
             return self.jit_globals[name]
         elif self.compiled_function_lookup is not None:
             return self.compiled_function_lookup(name)
@@ -790,6 +792,13 @@ class AnalysisState(object):
             # Get the callee's name.
             compiled_func_name = self.jit.get_compiled_name(body_id)
 
+            # This handles the corner case where a constant node is called, like
+            # 'call(constant(9), ...)'. In this case, `callee_name` is `None`
+            # because 'constant(9)' doesn't give us a name. However, we can look up
+            # the name of the function at a specific node. If that turns out to be
+            # an intrinsic, then we still want to pick the intrinsic over a call.
+            intrinsic = self.jit.get_intrinsic(compiled_func_name)
+
         # Analyze the argument dictionary.
         try:
             gen = self.analyze_arguments(first_parameter_id)
@@ -867,7 +876,7 @@ class AnalysisState(object):
         # Figure out what the 'func' instruction's type is.
         func_instruction_op, = yield [("RV", [func_id])]
         if func_instruction_op['value'] == 'access':
-            # Calls to 'access(resolve(var))' instructions are translated to direct calls.
+            # 'access(resolve(var))' instructions are translated to direct calls.
             access_value_id, = yield [("RD", [func_id, "var"])]
             access_value_op, = yield [("RV", [access_value_id])]
             if access_value_op['value'] == 'resolve':
@@ -886,6 +895,14 @@ class AnalysisState(object):
                     while True:
                         inp = yield gen.send(inp)
                     # PrimitiveFinished exception will bubble up from here.
+        elif func_instruction_op['value'] == 'constant':
+            # 'const(func_id)' instructions are also translated to direct calls.
+            function_val_id, = yield [("RD", [func_id, "node"])]
+            gen = self.analyze_direct_call(
+                function_val_id, None, first_param_id)
+            inp = None
+            while True:
+                inp = yield gen.send(inp)
 
         raise JitCompilationFailedException(
             "Cannot JIT function calls that target an unknown value as direct calls.")