public inbox for jit@gcc.gnu.org
 help / color / mirror / Atom feed
* Coconut: an experimental JIT compiler for CPython 3
@ 2014-01-01  0:00 David Malcolm
  0 siblings, 0 replies; only message in thread
From: David Malcolm @ 2014-01-01  0:00 UTC (permalink / raw)
  To: jit

I've been experimenting with the Python bindings for libgccjit, and I've
used them to write a toy JIT compiler for Python itself, specifically,
CPython 3.*, which I'm calling "coconut" (in homage to the "Unladen
Swallow" project from a few years ago):

https://github.com/davidmalcolm/coconut

It's a "method JIT": it can introspect Python functions, getting at
their bytecode, and then converts it to a coconut.bytecode.BytecodeCFG,
where the blocks consist of those seen e.g. within Python's peephole.c
and the ops are bytecodes. These ops "know" what their stack depths are.

This is then compiled (by coconut.compiler) into a lower-level
representation, coconut.ir.IrCFG. The higher-level ops are exploded into
one or more blocks per bytecode op, along with various other blocks for
e.g. exception handling: even a simple BytecodeCFG typically becomes a
fairly complicate IrCFG.

This low-level representation can then be sent via pygccjit into
libgccjit, converting it to a machine code specialization of that
function.

It currently requires a slight patch to CPython itself (see
cpython.patch), to support patching out the main bytecode interpreter on
a function-by-function basis in favor of the injected machine code
(better ways of doing this are welcome).

It's currently a toy: it only implements a subset of the bytecodes, and
there are plenty of optimizations it doesn't do e.g. type inference,
specialization for given types etc), so the performance isn't an
improvement (AIUI we gain a little from eliminating the stack push/pop
activity in favor of direct access to specific memory regions, but we
lose a little since we're thrashing the instruction cache with new code,
vs a single bytecode dispatch loop plus the relatively compact bytecode
format).

That said, it's already been useful for finding bugs and design issues
with libgccjit (and the Python bindings).

The implementation current attempts to faithfully respect the full
dynamic behaviors of the Python interpreter (even the somewhat
pathological ones e.g. where something you call can manipulate your
stack frame and change the types of variables from under you, or a
tp_dealloc hook could toggle whether of not profiling is enabled from
within a Py_DECREF).  Potentially we could relax that to get speed wins
(though arguably people looking for a faster python should look at PyPy,
and we should look at providing a PyPy JIT backend using libgccjit).

Dave

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2014-07-30 14:42 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-01-01  0:00 Coconut: an experimental JIT compiler for CPython 3 David Malcolm

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).