8000 Support non-matching args in the JIT · Fidget-Spinner/cpython@c546631 · GitHub
[go: up one dir, main page]

Skip to content

Commit c546631

Browse files
Support non-matching args in the JIT
1 parent 84914ad commit c546631

File tree

3 files changed

+43
-13
lines changed

3 files changed

+43
-13
lines changed

Tools/jit/_targets.py

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -114,23 +114,30 @@ def _handle_relocation(
114114
) -> _stencils.Hole:
115115
raise NotImplementedError(type(self))
116116

117+
def _substitute_in_preserve_none_and_add_musttail(self, ll_file: pathlib.Path):
118+
all = ll_file.read_text()
119+
# Replace tail calls with musttail and correct calling convetion.
120+
all = all.replace("tail call preserve_allcc", "musttail call preserve_nonecc")
121+
all = all.replace("call preserve_allcc", "musttail call preserve_nonecc")
122+
# Swap sentinel calling conv with the real one.
123+
all = all.replace("preserve_allcc", "preserve_nonecc")
124+
125+
ll_file.write_text(all)
126+
# with open("/home/ken/Documents/GitHub/cpython/hi.txt", "w") as sys.stdout:
127+
# print(all)
128+
117129
async def _compile(
118130
self, opname: str, c: pathlib.Path, tempdir: pathlib.Path
119131
) -> _stencils.StencilGroup:
120132
o = tempdir / f"{opname}.o"
121-
args = [
133+
ll = tempdir / f"{opname}.ll"
134+
common_args = [
122135
f"--target={self.triple}",
123136
"-DPy_BUILD_CORE_MODULE",
124137
"-D_DEBUG" if self.debug else "-DNDEBUG",
125138
f"-D_JIT_OPCODE={opname}",
126139
"-D_PyJIT_ACTIVE",
127140
"-D_Py_JIT",
128-
"-I.",
129-
f"-I{CPYTHON / 'Include'}",
130-
f"-I{CPYTHON / 'Include' / 'internal'}",
131-
f"-I{CPYTHON / 'Include' / 'internal' / 'mimalloc'}",
132-
f"-I{CPYTHON / 'Python'}",
133-
f"-I{CPYTHON / 'Tools' / 'jit'}",
134141
"-O3",
135142
"-c",
136143
# Shorten full absolute file paths in the generated code (like the
@@ -151,11 +158,30 @@ async def _compile(
151158
"-fno-stack-protector",
152159
"-std=c11",
153160
"-o",
154-
f"{o}",
161+
]
162+
ll_args = [
163+
"-I.",
164+
f"-I{CPYTHON / 'Include'}",
165+
f"-I{CPYTHON / 'Include' / 'internal'}",
166+
f"-I{CPYTHON / 'Include' / 'internal' / 'mimalloc'}",
167+
f"-I{CPYTHON / 'Python'}",
168+
f"-I{CPYTHON / 'Tools' / 'jit'}",
169+
*common_args,
170+
f"{ll}",
155171
f"{c}",
172+
"-emit-llvm",
173+
"-S",
174+
*self.args,
175+
]
176+
o_args = [
177+
*common_args,
178+
f"{o}",
179+
f"{ll}",
156180
*self.args,
157181
]
158-
await _llvm.run("clang", args, echo=self.verbose)
182+
await _llvm.run("clang", ll_args, echo=self.verbose)
183+
self._substitute_in_preserve_none_and_add_musttail(ll)
184+
await _llvm.run("clang", o_args, echo=self.verbose)
159185
return await self._parse(o)
160186

161187
async def _build_stencils(self) -> dict[str, _stencils.StencilGroup]:

Tools/jit/jit.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// To use preserve_none in JIT builds, we need to declare a separate function
22
// pointer with __attribute__((preserve_none)), since this attribute may not be
33
// supported by the compiler used to build the rest of the interpreter.
4-
typedef jit_func __attribute__((preserve_none)) jit_func_preserve_none;
4+
// We don't actually use preserve_all. This is just a sentinel which get
5+
// substituted out with a preserve_none later.
6+
typedef jit_func __attribute__((preserve_all)) jit_func_preserve_none;
57

68
#define PATCH_VALUE(TYPE, NAME, ALIAS) \
79
PyAPI_DATA(void) ALIAS; \

Tools/jit/template.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ do { \
5353
_PyExecutorObject *_executor = (EXECUTOR); \
5454
tstate->current_executor = (PyObject *)_executor; \
5555
jit_func_preserve_none jitted = _executor->jit_side_entry; \
56-
__attribute__((musttail)) return jitted(frame, stack_pointer, tstate); \
56+
return jitted(frame, stack_pointer, tstate); \
5757
} while (0)
5858

5959
#undef GOTO_TIER_ONE
@@ -77,7 +77,7 @@ do { \
7777
#define PATCH_JUMP(ALIAS) \
7878
do { \
7979
PATCH_VALUE(jit_func_preserve_none, jump, ALIAS); \
80-
__attribute__((musttail)) return jump(frame, stack_pointer, tstate); \
80+
return jump(frame, stack_pointer, tstate); \
8181
} while (0)
8282

8383
#undef JUMP_TO_JUMP_TARGET
@@ -88,7 +88,9 @@ do { \
8888

8989
#define TIER_TWO 2
9090

91-
__attribute__((preserve_none)) _Py_CODEUNIT *
91+
// This preserve_all calling convention isn't actually used, it's just a
92+
// sentinel for our compiler to swap out with the right calling convention.
93+
__attribute__((preserve_all)) _Py_CODEUNIT *
9294
_JIT_ENTRY(_PyInterpreterFrame *frame, _PyStackRef *stack_pointer, PyThreadState *tstate)
9395
{
9496
// Locals that the instruction implementations expect to exist:

0 commit comments

Comments
 (0)
0