-
-
Notifications
You must be signed in to change notification settings - Fork 32.5k
GH-132532: Add new DSL macros to better declare semantics of exits at ends of instructions/uops. #137098
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
base: main
Are you sure you want to change the base?
Conversation
…ics of exits at ends of instructions/uops.
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.
Seems correct. My only issue is with all of the new names... naming is hard.
I feel like the chosen names are a bit hard to parse and reason about, and suggested some alternatives. But they're just suggestions, nothing blocking.
_Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY(); | ||
QSBR_QUIESCENT_STATE(tstate); | ||
if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) { | ||
int err = _Py_HandlePending(tstate); | ||
ERROR_IF(err != 0); | ||
} |
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.
This logic is now repeated 3 times, and two of them are in identical opcode implementations. Maybe it should be broken out into a static inline helper function?
@@ -5189,32 +5198,28 @@ dummy_func( | |||
op (_GUARD_IS_TRUE_POP, (flag -- )) { | |||
int is_true = PyStackRef_IsTrue(flag); | |||
DEAD(flag); | |||
SYNC_SP(); | |||
EXIT_IF(!is_true); | |||
EXIT_IF_AFTER(!is_true); |
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.
The wording makes this a bit hard to parse: "exit if after not is true"? Maybe use "at end" for consistency with _CHECK_PERIODIC_AT_END
, if they mean the same thing? AT_END_EXIT_IF
, maybe?
@@ -5380,6 +5385,11 @@ dummy_func( | |||
GOTO_TIER_ONE(_PyFrame_GetBytecode(frame) + CURRENT_TARGET()); | |||
} | |||
|
|||
tier2 op(_PERIODIC, (--)) { |
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 get that this is "check periodic without the check", but maybe we could find a better name here? _HANDLE_PENDING_AND_DEOPT
?
@@ -5391,11 +5401,11 @@ dummy_func( | |||
* ENTER_EXECUTOR will not re-enter tier 2 with the eval breaker set. */ | |||
tier2 op(_TIER2_RESUME_CHECK, (--)) { | |||
#if defined(__EMSCRIPTEN__) | |||
DEOPT_IF(_Py_emscripten_signal_clock == 0); | |||
PERIODIC_IF(_Py_emscripten_signal_clock == 0); |
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 here... Maybe HANDLE_PENDING_AND_DEOPT_IF
?
This PR changes adds the ability to de-opt at the end an instruction.
Exits from tier 2 jump to the next instruction in tier 1.
In the case of deopting due to the eval breaker being set,
_Py_HandlePending
is called before resuming tier 1.I am taking this approach instead of checking the eval breaker before each call, as this does not cause any observable behavior change. For comparison see https://github.com/python/cpython/compare/main...faster-cpython:cpython:check-periodic-before-call?expand=1, noting the necessary changes to tests and threading module.
Although this approach adds a bit more complexity to the optimizer, it doesn't need any changes to the library or tests.