thautwarm / restrain-jit

The first and yet the only CPython compatible Python JIT, over the world.(julia backend: https://github.com/thautwarm/RestrainJIT.jl)
MIT License
107 stars 6 forks source link

Cython backend & the phi node analysis #15

Closed thautwarm closed 5 years ago

thautwarm commented 5 years ago

The use of stack machine is removed now for the Cython back end(does not support Python's exception handling instructions yet).

from restrain_jit.becy.phi_node_analysis import PhiNodeAnalysis
from restrain_jit.becy.stack_vm_instructions import *
from restrain_jit.becy.tools import show_instrs

instrs = [
    A(None, Label(label=0)),
    A(None, Push(Reg("x0"))),
    A(None, JmpIfPush(2, Reg("x0"), Reg("x0"))),
    A(None, Label(label=1)),
    A(None, Push(Reg("x1"))),
    A(None, Label(label=2)),
    A("c", Pop()),
    A(None, Return(Reg("c")))
]

show_instrs(list(PhiNodeAnalysis(instrs).main()))

produces

label 0:
JmpIf(label=2, cond=Reg(n='x0'))
label 1:
label 2:
   from 0
        drawback2-1 = Reg(n='x0')
   from 1
        drawback2-1 = Reg(n='x1')
Ass(reg=Reg(n='c'), val=Reg(n='drawback2-1'))
Return(val=Reg(n='c'))

Now NO push or pop instructions here, and the weird jump instructions of Python like JUMP_IF_TRUE_OR_POP are translated into JmpIf and Phi, instead of using the magic of stack machine.

When there is no exception handling, only 10 instructions are sufficient to express Python virtual machine:

data App(Instr) f:Repr args:t.List[Repr];
data Ass(Instr) reg:Reg val:Repr;
data Load(Instr) reg:Reg;
data Store(Instr) reg:Reg val:Repr;
data JmpIf(Instr) label:object cond:Repr;
data Jmp(Instr) label:object;
data Label(Instr) label:object phi:t.Dict[object,t.Dict[Reg, Repr]];
data Return(Instr) val:Repr;
data PyGlob(Instr) qual:str name:str;
data CyGlob(Instr) qual:str name:str;