mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
GH-113464: Add a JIT backend for tier 2 (GH-113465)
Add an option (--enable-experimental-jit for configure-based builds or --experimental-jit for PCbuild-based ones) to build an *experimental* just-in-time compiler, based on copy-and-patch (https://fredrikbk.com/publications/copy-and-patch.pdf). See Tools/jit/README.md for more information on how to install the required build-time tooling.
This commit is contained in:
parent
f7c05d7ad3
commit
f6d9e5926b
29 changed files with 1738 additions and 5 deletions
95
Tools/jit/_writer.py
Normal file
95
Tools/jit/_writer.py
Normal file
|
@ -0,0 +1,95 @@
|
|||
"""Utilities for writing StencilGroups out to a C header file."""
|
||||
import typing
|
||||
|
||||
import _schema
|
||||
import _stencils
|
||||
|
||||
|
||||
def _dump_header() -> typing.Iterator[str]:
|
||||
yield "typedef enum {"
|
||||
for kind in typing.get_args(_schema.HoleKind):
|
||||
yield f" HoleKind_{kind},"
|
||||
yield "} HoleKind;"
|
||||
yield ""
|
||||
yield "typedef enum {"
|
||||
for value in _stencils.HoleValue:
|
||||
yield f" HoleValue_{value.name},"
|
||||
yield "} HoleValue;"
|
||||
yield ""
|
||||
yield "typedef struct {"
|
||||
yield " const uint64_t offset;"
|
||||
yield " const HoleKind kind;"
|
||||
yield " const HoleValue value;"
|
||||
yield " const void *symbol;"
|
||||
yield " const uint64_t addend;"
|
||||
yield "} Hole;"
|
||||
yield ""
|
||||
yield "typedef struct {"
|
||||
yield " const size_t body_size;"
|
||||
yield " const unsigned char * const body;"
|
||||
yield " const size_t holes_size;"
|
||||
yield " const Hole * const holes;"
|
||||
yield "} Stencil;"
|
||||
yield ""
|
||||
yield "typedef struct {"
|
||||
yield " const Stencil code;"
|
||||
yield " const Stencil data;"
|
||||
yield "} StencilGroup;"
|
||||
yield ""
|
||||
|
||||
|
||||
def _dump_footer(opnames: typing.Iterable[str]) -> typing.Iterator[str]:
|
||||
yield "#define INIT_STENCIL(STENCIL) { \\"
|
||||
yield " .body_size = Py_ARRAY_LENGTH(STENCIL##_body) - 1, \\"
|
||||
yield " .body = STENCIL##_body, \\"
|
||||
yield " .holes_size = Py_ARRAY_LENGTH(STENCIL##_holes) - 1, \\"
|
||||
yield " .holes = STENCIL##_holes, \\"
|
||||
yield "}"
|
||||
yield ""
|
||||
yield "#define INIT_STENCIL_GROUP(OP) { \\"
|
||||
yield " .code = INIT_STENCIL(OP##_code), \\"
|
||||
yield " .data = INIT_STENCIL(OP##_data), \\"
|
||||
yield "}"
|
||||
yield ""
|
||||
yield "static const StencilGroup stencil_groups[512] = {"
|
||||
for opname in opnames:
|
||||
yield f" [{opname}] = INIT_STENCIL_GROUP({opname}),"
|
||||
yield "};"
|
||||
yield ""
|
||||
yield "#define GET_PATCHES() { \\"
|
||||
for value in _stencils.HoleValue:
|
||||
yield f" [HoleValue_{value.name}] = (uint64_t)0xBADBADBADBADBADB, \\"
|
||||
yield "}"
|
||||
|
||||
|
||||
def _dump_stencil(opname: str, group: _stencils.StencilGroup) -> typing.Iterator[str]:
|
||||
yield f"// {opname}"
|
||||
for part, stencil in [("code", group.code), ("data", group.data)]:
|
||||
for line in stencil.disassembly:
|
||||
yield f"// {line}"
|
||||
if stencil.body:
|
||||
size = len(stencil.body) + 1
|
||||
yield f"static const unsigned char {opname}_{part}_body[{size}] = {{"
|
||||
for i in range(0, len(stencil.body), 8):
|
||||
row = " ".join(f"{byte:#04x}," for byte in stencil.body[i : i + 8])
|
||||
yield f" {row}"
|
||||
yield "};"
|
||||
else:
|
||||
yield f"static const unsigned char {opname}_{part}_body[1];"
|
||||
if stencil.holes:
|
||||
size = len(stencil.holes) + 1
|
||||
yield f"static const Hole {opname}_{part}_holes[{size}] = {{"
|
||||
for hole in stencil.holes:
|
||||
yield f" {hole.as_c()},"
|
||||
yield "};"
|
||||
else:
|
||||
yield f"static const Hole {opname}_{part}_holes[1];"
|
||||
yield ""
|
||||
|
||||
|
||||
def dump(groups: dict[str, _stencils.StencilGroup]) -> typing.Iterator[str]:
|
||||
"""Yield a JIT compiler line-by-line as a C header file."""
|
||||
yield from _dump_header()
|
||||
for opname, group in groups.items():
|
||||
yield from _dump_stencil(opname, group)
|
||||
yield from _dump_footer(groups)
|
Loading…
Add table
Add a link
Reference in a new issue