Skip to content

Allow enabling the JIT on aarch64 macOS #544

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions cpython-unix/build-cpython.sh
Original file line number Diff line number Diff line change
Expand Up @@ -455,12 +455,21 @@ if [ -n "${CPYTHON_OPTIMIZED}" ]; then
# Allow users to enable the experimental JIT on 3.13+
if [[ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_13}" ]]; then

# The JIT build is failing on macOS due to compiler errors
# Only enable on Linux / 3.13 until that's fixed upstream
if [[ "${PYBUILD_PLATFORM}" != "macos" ]]; then
# Do not enable on x86-64 macOS because the JIT requires macOS 11+ and we are currently
# using 10.15 as a miniumum version.
if [ "${TARGET_TRIPLE}" != "x86_64-apple-darwin" ]; then
CONFIGURE_FLAGS="${CONFIGURE_FLAGS} --enable-experimental-jit=yes-off"
fi

# Respect CFLAGS during JIT compilation.
# Backports https://github.com/python/cpython/pull/134276
if [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_14}" ]; then
patch -p1 -i ${ROOT}/patch-jit-cflags-314.patch
elif [ -n "${PYTHON_MEETS_MINIMUM_VERSION_3_13}" ]; then
patch -p1 -i ${ROOT}/patch-jit-cflags-313.patch
fi


if [[ -n "${PYTHON_MEETS_MAXIMUM_VERSION_3_13}" ]]; then
# On 3.13, LLVM 18 is hard-coded into the configure script. Override it to our toolchain
# version.
Expand Down
80 changes: 80 additions & 0 deletions cpython-unix/patch-jit-cflags-313.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
diff --git a/Tools/jit/_targets.py b/Tools/jit/_targets.py
index 50b5d923a35..4a71476026f 100644
--- a/Tools/jit/_targets.py
+++ b/Tools/jit/_targets.py
@@ -10,6 +10,7 @@
import sys
import tempfile
import typing
+import shlex

import _llvm
import _schema
@@ -44,6 +45,17 @@ class _Target(typing.Generic[_S, _R]):
stable: bool = False
debug: bool = False
verbose: bool = False
+ cflags: str = ""
+ known_symbols: dict[str, int] = dataclasses.field(default_factory=dict)
+
+ def _get_nop(self) -> bytes:
+ if re.fullmatch(r"aarch64-.*", self.triple):
+ nop = b"\x1f\x20\x03\xD5"
+ elif re.fullmatch(r"x86_64-.*|i686.*", self.triple):
+ nop = b"\x90"
+ else:
+ raise ValueError(f"NOP not defined for {self.triple}")
+ return nop

def _compute_digest(self, out: pathlib.Path) -> str:
hasher = hashlib.sha256()
@@ -114,6 +126,7 @@ async def _compile(
return _stencils.StencilGroup()
o = tempdir / f"{opname}.o"
args = [
+ *shlex.split(self.cflags),
f"--target={self.triple}",
"-DPy_BUILD_CORE_MODULE",
"-D_DEBUG" if self.debug else "-DNDEBUG",
diff --git a/Tools/jit/build.py b/Tools/jit/build.py
index 4a23c6f0afa..618b53804db 100644
--- a/Tools/jit/build.py
+++ b/Tools/jit/build.py
@@ -22,7 +22,11 @@
parser.add_argument(
"-v", "--verbose", action="store_true", help="echo commands as they are run"
)
+ parser.add_argument(
+ "--with-cflags", help="additional flags to pass to the compiler", default=""
+ )
args = parser.parse_args()
args.target.debug = args.debug
args.target.verbose = args.verbose
+ args.target.cflags = args.with_cflags
args.target.build(pathlib.Path.cwd(), comment=comment, force=args.force)
diff --git a/configure b/configure
index 1cd1f690f7b..7fb6c4adfea 100755
--- a/configure
+++ b/configure
@@ -8326,7 +8326,7 @@ then :

else $as_nop
as_fn_append CFLAGS_NODIST " $jit_flags"
- REGEN_JIT_COMMAND="\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py $host"
+ REGEN_JIT_COMMAND="\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py $host --with-cflags=\"\$(CONFIGURE_CFLAGS)\""
JIT_STENCILS_H="jit_stencils.h"
if test "x$Py_DEBUG" = xtrue
then :
diff --git a/configure.ac b/configure.ac
index 3fcb18922c5..616999a96b2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1846,7 +1846,7 @@ AS_VAR_IF([jit_flags],
[],
[AS_VAR_APPEND([CFLAGS_NODIST], [" $jit_flags"])
AS_VAR_SET([REGEN_JIT_COMMAND],
- ["\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py $host"])
+ ["\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py $host --with-cflags=\"\$(CONFIGURE_CFLAGS)\""])
AS_VAR_SET([JIT_STENCILS_H], ["jit_stencils.h"])
AS_VAR_IF([Py_DEBUG],
[true],
70 changes: 70 additions & 0 deletions cpython-unix/patch-jit-cflags-314.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
diff --git a/Tools/jit/_targets.py b/Tools/jit/_targets.py
index b3b065652e0..d361f57382e 100644
--- a/Tools/jit/_targets.py
+++ b/Tools/jit/_targets.py
@@ -10,6 +10,7 @@
import sys
import tempfile
import typing
+import shlex

import _llvm
import _schema
@@ -42,6 +43,7 @@ class _Target(typing.Generic[_S, _R]):
stable: bool = False
debug: bool = False
verbose: bool = False
+ cflags: str = ""
known_symbols: dict[str, int] = dataclasses.field(default_factory=dict)

def _get_nop(self) -> bytes:
@@ -115,6 +117,7 @@ async def _compile(
) -> _stencils.StencilGroup:
o = tempdir / f"{opname}.o"
args = [
+ *shlex.split(self.cflags),
f"--target={self.triple}",
"-DPy_BUILD_CORE_MODULE",
"-D_DEBUG" if self.debug else "-DNDEBUG",
diff --git a/Tools/jit/build.py b/Tools/jit/build.py
index a8cb0f67c36..663874ad439 100644
--- a/Tools/jit/build.py
+++ b/Tools/jit/build.py
@@ -22,7 +22,11 @@
parser.add_argument(
"-v", "--verbose", action="store_true", help="echo commands as they are run"
)
+ parser.add_argument(
+ "--with-cflags", help="additional flags to pass to the compiler", default=""
+ )
args = parser.parse_args()
args.target.debug = args.debug
args.target.verbose = args.verbose
+ args.target.cflags = args.with_cflags
args.target.build(pathlib.Path.cwd(), comment=comment, force=args.force)
diff --git a/configure b/configure
index 1b75ddfa26d..3c9e550b5d3 100755
--- a/configure
+++ b/configure
@@ -8399,7 +8399,7 @@ then :

else case e in #(
e) as_fn_append CFLAGS_NODIST " $jit_flags"
- REGEN_JIT_COMMAND="\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py $host"
+ REGEN_JIT_COMMAND="\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py $host --with-cflags=\"\$(CONFIGURE_CFLAGS)\""
JIT_STENCILS_H="jit_stencils.h"
if test "x$Py_DEBUG" = xtrue
then :
diff --git a/configure.ac b/configure.ac
index c449bb5ebb3..5f9d08a4ee7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1827,7 +1827,7 @@ AS_VAR_IF([jit_flags],
[],
[AS_VAR_APPEND([CFLAGS_NODIST], [" $jit_flags"])
AS_VAR_SET([REGEN_JIT_COMMAND],
- ["\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py $host"])
+ ["\$(PYTHON_FOR_REGEN) \$(srcdir)/Tools/jit/build.py $host --with-cflags=\"\$(CONFIGURE_CFLAGS)\""])
AS_VAR_SET([JIT_STENCILS_H], ["jit_stencils.h"])
AS_VAR_IF([Py_DEBUG],
[true],