summaryrefslogtreecommitdiffstats
path: root/Tools/jit/_targets.py
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/jit/_targets.py')
-rw-r--r--Tools/jit/_targets.py67
1 files changed, 15 insertions, 52 deletions
diff --git a/Tools/jit/_targets.py b/Tools/jit/_targets.py
index 5eb316e..634208d 100644
--- a/Tools/jit/_targets.py
+++ b/Tools/jit/_targets.py
@@ -26,7 +26,6 @@ CPYTHON = TOOLS.parent
PYTHON_EXECUTOR_CASES_C_H = CPYTHON / "Python" / "executor_cases.c.h"
TOOLS_JIT_TEMPLATE_C = TOOLS_JIT / "template.c"
-
_S = typing.TypeVar("_S", _schema.COFFSection, _schema.ELFSection, _schema.MachOSection)
_R = typing.TypeVar(
"_R", _schema.COFFRelocation, _schema.ELFRelocation, _schema.MachORelocation
@@ -39,7 +38,6 @@ class _Target(typing.Generic[_S, _R]):
_: dataclasses.KW_ONLY
alignment: int = 1
args: typing.Sequence[str] = ()
- ghccc: bool = False
prefix: str = ""
stable: bool = False
debug: bool = False
@@ -88,11 +86,7 @@ class _Target(typing.Generic[_S, _R]):
sections: list[dict[typing.Literal["Section"], _S]] = json.loads(output)
for wrapped_section in sections:
self._handle_section(wrapped_section["Section"], group)
- # The trampoline's entry point is just named "_ENTRY", since on some
- # platforms we later assume that any function starting with "_JIT_" uses
- # the GHC calling convention:
- entry_symbol = "_JIT_ENTRY" if "_JIT_ENTRY" in group.symbols else "_ENTRY"
- assert group.symbols[entry_symbol] == (_stencils.HoleValue.CODE, 0)
+ assert group.symbols["_JIT_ENTRY"] == (_stencils.HoleValue.CODE, 0)
if group.data.body:
line = f"0: {str(bytes(group.data.body)).removeprefix('b')}"
group.data.disassembly.append(line)
@@ -112,9 +106,6 @@ class _Target(typing.Generic[_S, _R]):
async def _compile(
self, opname: str, c: pathlib.Path, tempdir: pathlib.Path
) -> _stencils.StencilGroup:
- # "Compile" the trampoline to an empty stencil group if it's not needed:
- if opname == "trampoline" and not self.ghccc:
- return _stencils.StencilGroup()
o = tempdir / f"{opname}.o"
args = [
f"--target={self.triple}",
@@ -128,6 +119,7 @@ class _Target(typing.Generic[_S, _R]):
f"-I{CPYTHON / 'Include' / 'internal'}",
f"-I{CPYTHON / 'Include' / 'internal' / 'mimalloc'}",
f"-I{CPYTHON / 'Python'}",
+ f"-I{CPYTHON / 'Tools' / 'jit'}",
"-O3",
"-c",
# This debug info isn't necessary, and bloats out the JIT'ed code.
@@ -143,44 +135,12 @@ class _Target(typing.Generic[_S, _R]):
# Don't call stack-smashing canaries that we can't find or patch:
"-fno-stack-protector",
"-std=c11",
+ "-o",
+ f"{o}",
+ f"{c}",
*self.args,
]
- if self.ghccc:
- # This is a bit of an ugly workaround, but it makes the code much
- # smaller and faster, so it's worth it. We want to use the GHC
- # calling convention, but Clang doesn't support it. So, we *first*
- # compile the code to LLVM IR, perform some text replacements on the
- # IR to change the calling convention(!), and then compile *that*.
- # Once we have access to Clang 19, we can get rid of this and use
- # __attribute__((preserve_none)) directly in the C code instead:
- ll = tempdir / f"{opname}.ll"
- args_ll = args + [
- # -fomit-frame-pointer is necessary because the GHC calling
- # convention uses RBP to pass arguments:
- "-S",
- "-emit-llvm",
- "-fomit-frame-pointer",
- "-o",
- f"{ll}",
- f"{c}",
- ]
- await _llvm.run("clang", args_ll, echo=self.verbose)
- ir = ll.read_text()
- # This handles declarations, definitions, and calls to named symbols
- # starting with "_JIT_":
- ir = re.sub(
- r"(((noalias|nonnull|noundef) )*ptr @_JIT_\w+\()", r"ghccc \1", ir
- )
- # This handles calls to anonymous callees, since anything with
- # "musttail" needs to use the same calling convention:
- ir = ir.replace("musttail call", "musttail call ghccc")
- # Sometimes *both* replacements happen at the same site, so fix it:
- ir = ir.replace("ghccc ghccc", "ghccc")
- ll.write_text(ir)
- args_o = args + ["-Wno-unused-command-line-argument", "-o", f"{o}", f"{ll}"]
- else:
- args_o = args + ["-o", f"{o}", f"{c}"]
- await _llvm.run("clang", args_o, echo=self.verbose)
+ await _llvm.run("clang", args, echo=self.verbose)
return await self._parse(o)
async def _build_stencils(self) -> dict[str, _stencils.StencilGroup]:
@@ -519,7 +479,6 @@ class _MachO(
def get_target(host: str) -> _COFF | _ELF | _MachO:
"""Build a _Target for the given host "triple" and options."""
- # ghccc currently crashes Clang when combined with musttail on aarch64. :(
target: _COFF | _ELF | _MachO
if re.fullmatch(r"aarch64-apple-darwin.*", host):
target = _MachO(host, alignment=8, prefix="_")
@@ -535,16 +494,20 @@ def get_target(host: str) -> _COFF | _ELF | _MachO:
]
target = _ELF(host, alignment=8, args=args)
elif re.fullmatch(r"i686-pc-windows-msvc", host):
- args = ["-DPy_NO_ENABLE_SHARED"]
- target = _COFF(host, args=args, ghccc=True, prefix="_")
+ args = [
+ "-DPy_NO_ENABLE_SHARED",
+ # __attribute__((preserve_none)) is not supported
+ "-Wno-ignored-attributes",
+ ]
+ target = _COFF(host, args=args, prefix="_")
elif re.fullmatch(r"x86_64-apple-darwin.*", host):
- target = _MachO(host, ghccc=True, prefix="_")
+ target = _MachO(host, prefix="_")
elif re.fullmatch(r"x86_64-pc-windows-msvc", host):
args = ["-fms-runtime-lib=dll"]
- target = _COFF(host, args=args, ghccc=True)
+ target = _COFF(host, args=args)
elif re.fullmatch(r"x86_64-.*-linux-gnu", host):
args = ["-fpic"]
- target = _ELF(host, args=args, ghccc=True)
+ target = _ELF(host, args=args)
else:
raise ValueError(host)
return target