-
-
Notifications
You must be signed in to change notification settings - Fork 32k
GH-105848: Get rid of KW_NAMES
#105849
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
GH-105848: Get rid of KW_NAMES
#105849
Conversation
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.
Code LGTM. Definitely happy to see KW_NAMES
and its side-channel local variable go away.
It's not clear to me that it wouldn't be simpler to just do the conditional version with oparg flag right away in this PR (you've added a lot of PUSH_NULL
that are going to be removed shortly, and I wouldn't want this intermediate state to persist without measuring the code size and perf impact), but since you've already done it this way, seems OK.
Doc/library/dis.rst
Outdated
@@ -1387,6 +1390,10 @@ iterations of the loop. | |||
|
|||
.. versionadded:: 3.11 | |||
|
|||
.. versionchanged:: 3.12 |
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.
I doubt this is really a candidate for 3.12 backport?
.. versionchanged:: 3.12 | |
.. versionchanged:: 3.13 |
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.
Heh, typo.
Python/bytecodes.c
Outdated
Py_DECREF(callable); | ||
GO_TO_INSTRUCTION(CALL_PY_EXACT_ARGS); | ||
} | ||
|
||
inst(CALL_PY_EXACT_ARGS, (unused/1, func_version/2, method, callable, args[oparg] -- unused)) { | ||
inst(CALL_PY_EXACT_ARGS, (unused/1, func_version/2, method, callable, args[oparg], kwnames -- unused)) { | ||
assert(kwnames == NULL); |
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.
Is this assert is worth having kwnames
instead of unused
in the instruction signature? I'm guessing compilers will be smart enough to eliminate the unused load from stack when asserts are not enabled...
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.
You're right, probably not worth keeping around. The new assert can just check the oparg flag instead.
Python/bytecodes.c
Outdated
SKIP_OVER(INLINE_CACHE_ENTRIES_CALL); | ||
frame->return_offset = 0; | ||
DISPATCH_INLINED(new_frame); | ||
} | ||
|
||
inst(CALL_PY_WITH_DEFAULTS, (unused/1, func_version/2, method, callable, args[oparg] -- unused)) { | ||
inst(CALL_PY_WITH_DEFAULTS, (unused/1, func_version/2, method, callable, args[oparg], kwnames -- unused)) { | ||
assert(kwnames == NULL); |
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.
same question as above, and several more places below as well
I originally benchmarked this and it was "0% faster", but I re-ran the benchmarks after merging in main and it came back 1% slower. So while it's probably in the noise, I agree it's probably just cleaner to do the oparg flag here since that is our end goal anyways, and it should make the perf impact less iffy. I'll have some new commits with the flag up later today. |
Rerunning the benchmarks... |
Hm... still 1% slower. Maybe because of the new branches and bitwise operations calls have now? |
Given the disappointing performance results, I'm going to close this. It's probably still worth exploring in the future, but isn't really blocking anything we have in the pipeline right now. |
Not having this is holding back converting some Tier 1 CALL specializations to Tier 2, because the Tier 2 interpreter doesn't have access to the |
(Reopening as a reminder.) |
Given that we hold a strong reference to the code object, we can safely use a borrowed reference to the kwnames tuple. |
I have a feeling it would be easier to start over than to attempt to merge main into this PR. @brandtbucher Your thoughts? This is the next frontier in translating remaining CALL specializations to Tier 2. |
My plan is to start over (I can start on this today). Do we have a preference between extra |
Re: borrowed references, that seems like something we could bolt onto this after (with a new |
Excellent. I'd vote for extra PUSH_NULLs -- in Tier 2 that'd lead to less work (no need to check a bit in oparg and shift to get arg count). |
Closing in favor of #108496 (updated version). |
Instead, optionally push tuple of keyword names before every
CALL
(using the low bit of the oparg as a flag to indicate their presence).CALL
sequence #105848📚 Documentation preview 📚: https://cpython-previews--105849.org.readthedocs.build/