GeezerVison is showing github.com — GH-140479: Update JIT builds to use LLVM 21 by savannahostrowski · Pull Request #140973 · python/cpython
Conversation
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Fidget-Spinner, Sacul0457, and v-fox reacted with rocket emoji
Uh oh!
There was an error while loading. Please reload this page.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
diegorusso reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Provided #141002 gets merged before, this can go in as well. Thanks for splitting them up.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
savannahostrowski reacted with heart emoji
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks simple enough, let's do this!
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
savannahostrowski reacted with heart emoji
pablogsal
commented
Nov 9, 2025
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
|
I have tried to rebase https://github.com/pablogsal/cpython-unwind to check the unwinding. Looks like the function to test now needs to be more complicated beause the JIT refuses to call functions if there are branches now and requires tons of iterations to start jitting. I would love if someone can take a look at run.py. With the code we can validate all unwinding methods
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
The main branch's JIT doesn't seem to want to compile the example due to trace stack underflow. So I reduced the side exit count on my tracing JIT example and tried. Seems like LLVM 21 doesn't fix the problem :(
PYTHON_JIT=0
-----------
Testing various unwinding methods on the same deep call stack...
[GNU backtrace]
Total frames: 27
Showing first 10 frames:
# 0 /home/ken/Documents/GitHub/cpython-unwind/stackunwind.cpython-315-x86_64-linux-gnu.so(+0x280a) [0x78674f7a580a]
# 1 ../cpython/python(PyObject_Vectorcall+0x33) [0x58c0e08d2303]
# 2 ../cpython/python(_PyEval_EvalFrameDefault+0xf7a1) [0x58c0e086b141]
# 3 ../cpython/python(+0x2860aa) [0x58c0e0a430aa]
# 4 ../cpython/python(PyObject_Vectorcall+0x33) [0x58c0e08d2303]
# 5 ../cpython/python(_PyEval_EvalFrameDefault+0x3fb3) [0x58c0e085f953]
# 6 ../cpython/python(+0x2860aa) [0x58c0e0a430aa]
# 7 ../cpython/python(PyObject_Vectorcall+0x33) [0x58c0e08d2303]
# 8 ../cpython/python(_PyEval_EvalFrameDefault+0x3fb3) [0x58c0e085f953]
# 9 ../cpython/python(+0x2860aa) [0x58c0e0a430aa]
... (17 more frames)
[libunwind]
Total frames: 26
Showing first 10 frames:
# 0 PyObject_Vectorcall+0x33
# 1 _PyEval_EvalFrameDefault+0xf7a1
# 2 _PyEval_Vector+0x21a
# 3 PyObject_Vectorcall+0x33
# 4 _PyEval_EvalFrameDefault+0x3fb3
# 5 _PyEval_Vector+0x21a
# 6 PyObject_Vectorcall+0x33
# 7 _PyEval_EvalFrameDefault+0x3fb3
# 8 _PyEval_Vector+0x21a
# 9 PyObject_Vectorcall+0x33
... (16 more frames)
[libdw (DWARF)]
Total frames: 26
Showing first 10 frames:
# 0 PyObject_Vectorcall
# 1 _PyEval_EvalFrameDefault
# 2 _PyEval_Vector
# 3 PyObject_Vectorcall
# 4 _PyEval_EvalFrameDefault
# 5 _PyEval_Vector
# 6 PyObject_Vectorcall
# 7 _PyEval_EvalFrameDefault
# 8 _PyEval_Vector
# 9 PyObject_Vectorcall
... (16 more frames)
[Manual frame pointers]
Total frames: 4
Showing first 4 frames:
# 0 0x58c0e08d2303
# 1 0x2
# 2 0x58c0e0dbb7e0
# 3 0x2
PYTHON_JIT=1
------------
[GNU backtrace]
Total frames: 6
Showing first 6 frames:
# 0 /home/ken/Documents/GitHub/cpython-unwind/stackunwind.cpython-315-x86_64-linux-gnu.so(+0x280a) [0x7a0a357d080a]
# 1 ../cpython/python(PyObject_Vectorcall+0x33) [0x57385e3d3303]
# 2 ../cpython/python(_PyEval_EvalFrameDefault+0xf7a1) [0x57385e36c141]
# 3 ../cpython/python(+0x2860aa) [0x57385e5440aa]
# 4 ../cpython/python(PyObject_Vectorcall+0x33) [0x57385e3d3303]
# 5 [0x7a0a3398d4fb]
[libunwind]
Total frames: 5
Showing first 5 frames:
# 0 PyObject_Vectorcall+0x33
# 1 _PyEval_EvalFrameDefault+0xf7a1
# 2 _PyEval_Vector+0x21a
# 3 PyObject_Vectorcall+0x33
# 4 <unknown>
[libdw (DWARF)]
Total frames: 5
Showing first 5 frames:
# 0 PyObject_Vectorcall
# 1 _PyEval_EvalFrameDefault
# 2 _PyEval_Vector
# 3 PyObject_Vectorcall
# 4 <unknown>
[Manual frame pointers]
Total frames: 4
Showing first 4 frames:
# 0 0x57385e3d3303
# 1 0x(nil)
# 2 0x57385e8bc7e0
# 3 0x(nil)
Notice the missing frames!
However, I have made a very interesting discovery --- compiling the interpreter with a recent enough clang version (tested with clang-20/21) to the JIT restores the frames!!!
[GNU backtrace]
Total frames: 29
Showing first 10 frames:
# 0 /home/ken/Documents/GitHub/cpython-unwind/stackunwind.cpython-315-x86_64-linux-gnu.so(+0x280a) [0x797cf3f7c80a]
# 1 ../cpython/python(PyObject_Vectorcall+0x43) [0x64be6334e693]
# 2 ../cpython/python(_PyEval_EvalFrameDefault+0x5d3e) [0x64be6347f63e]
# 3 ../cpython/python(+0x217706) [0x64be63479706]
# 4 ../cpython/python(PyObject_Vectorcall+0x43) [0x64be6334e693]
# 5 ../cpython/python(_PyEval_EvalFrameDefault+0x3768) [0x64be6347d068]
# 6 ../cpython/python(+0x217706) [0x64be63479706]
# 7 ../cpython/python(PyObject_Vectorcall+0x43) [0x64be6334e693]
# 8 ../cpython/python(_PyEval_EvalFrameDefault+0x3768) [0x64be6347d068]
# 9 ../cpython/python(+0x217706) [0x64be63479706]
... (19 more frames)
[libunwind]
Total frames: 28
Showing first 10 frames:
# 0 PyObject_Vectorcall+0x43
# 1 _PyEval_EvalFrameDefault+0x5d3e
# 2 _PyEval_Vector+0x266
# 3 PyObject_Vectorcall+0x43
# 4 _PyEval_EvalFrameDefault+0x3768
# 5 _PyEval_Vector+0x266
# 6 PyObject_Vectorcall+0x43
# 7 _PyEval_EvalFrameDefault+0x3768
# 8 _PyEval_Vector+0x266
# 9 PyObject_Vectorcall+0x43
... (18 more frames)
[libdw (DWARF)]
Total frames: 28
Showing first 10 frames:
# 0 PyObject_Vectorcall
# 1 _PyEval_EvalFrameDefault
# 2 _PyEval_Vector
# 3 PyObject_Vectorcall
# 4 _PyEval_EvalFrameDefault
# 5 _PyEval_Vector
# 6 PyObject_Vectorcall
# 7 _PyEval_EvalFrameDefault
# 8 _PyEval_Vector
# 9 PyObject_Vectorcall
... (18 more frames)
[Manual frame pointers]
Total frames: 16
Showing first 10 frames:
# 0 0x64be6334e693
# 1 0x2
# 2 0x64be63479706
# 3 0x2
# 4 0x64be63479706
# 5 0x2
# 6 0x64be63479706
# 7 0x(nil)
# 8 0x64be63479706
# 9 0x(nil)
... (6 more frames)
So the solution to the stack unwinding seems to be to mandate compiilng CPython with the same clang as the JIT!
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
So the solution to the stack unwinding seems to be to mandate compiilng CPython with the same clang as the JIT!
We need to understand what the hell it's going on here because otherwise the risk it's that this breaks randomly in the future
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Another data point: old GCC (11) compiled with frame pointers with JIT also allows us to see the frames.
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Just to be clear, merely upgrading to LLVM 21 isn’t sufficient to get unwinding. We also need to do the reserved frame pointer thing, which isn’t in this branch.
|
savannahostrowski and Fidget-Spinner reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Yeah, was chatting with Brandt earlier this weekend about this and will probably go investigate the unwinding piece after this gets merged.
|
Fidget-Spinner reacted with thumbs up emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
I think it would be good to merge this soon. The meta benchmarking runners don't have JIT results this week because they don't have LLVM 20. It would be a little bit of churn to request they upgrade twice (once for LLVM 20, once for LLVM 21), so I was thinking if I could ask them nicely to just upgrade to LLVM 21 once :).
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
|
Discussed in our weekly sync, merging 🚀 !
|
hugovk and Fidget-Spinner reacted with rocket emoji
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Assignees
No one assigned
Labels
build
The build process and cross-build
dependencies
Pull requests that update a dependency file
infra
CI, GitHub Actions, buildbots, Dependabot, etc.
topic-JIT
Milestone
No milestone
Development
Successfully merging this pull request may close these issues.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
|