a concise introduction for dynjit
-
@awaredecoratorimport jit @jit.aware def f(x): return ... -
specifying optimizable global variables via
__fix__.so far due to the restriction of python runtime, an embedded jit compiler cannot easily aware the change of global variables and trigger recompilation. To make the problem simpler, we request users to fill constant global variables.
__fix__ = ['f1', 'f2'] @jit.aware def f1(x): return x + x @jit.aware def f2(x): if x < 3: y = x * 10 else: y = f1("aaa") return y + yIf
f1is not provided in__fix__, we cannot assumef2is referencing the function objectf1visually defined withdef f1. That is because it's possible to changef1later in python. Beside of providing__fix__, users should maintain the constant property of all variables in__fix__. -
the capability of dynjit compiler.
-
method lookup specialisation.
code like
a = []; a.append(1)will be at least more performant thana = []; $(list.append)(a, 1),$is not a real language construct, it means the splicing of constants, hence we don't need tricks likea = []; append = a.append; # use append laterany more. -
Union split(supercompiler). The overhead of functions that returns a value of union type is only a single runtime type check.
a = f(...) # if a can be int or float or str return a + a # by dynjit, '+' operator here # is not the generic one, but the specialised one -
Bool split(supercompiler).
Every boolean value will be specialised to
TrueorFalseand help to specialise control flows. -
Control flow specialisation.
if expression: # if expression can be partially evaluated to True(False), # then statically choose the first(second) arm ...- eliminate use of shallow data structures.
a = ... return a[1]If
apartially evaluated to a static value(1, 2, 3), then the code is identical toreturn 2This is much more powerful than the usual constant propagation due to our online partial evaluation. For termination guarantee, we cannot optimize use of nested/mutable data structures like
[1, 2, 3]and((1, 2, 3), ()). P.S: after getting dynjit ir we can emit LLVM IR code or C code to gain more kinds of optimizations. dynjit compiler itself is used for handling dynamisms of runtime. -
need to update.