gh-104584: Support most jumping instructions#106393
Conversation
|
FWIW the Tier 2 interpreter now supports 109 bytecodes and 12 uops (the Tier 1 interpreter supports 202 bytecodes). DetailsCases in Python/executor_cases.c.h: |
Sorry, something went wrong.
It looks like if we can manage to arrange that a |
Sorry, something went wrong.
markshannon
left a comment
There was a problem hiding this comment.
We want to support specialized instructions, like LOAD_ATTR_INSTANCE_VALUE, and simple instructions like LOAD_FAST, but we specifically do not want to support unspecialized instructions like LOAD_ATTR.
If those instructions show up, either we are projecting the superblock too early or, more likely, need better specialization.
Regarding jumps:
- Unconditional jumps should be nops, simply relying on
SAVE_IPto update the externally visible state - Conditional jumps should be converted to conditional exits and unconditional jumps.
Sorry, something went wrong.
gvanrossum
left a comment
There was a problem hiding this comment.
Thanks, this gave me food for thought.
Sorry, something went wrong.
markshannon
left a comment
There was a problem hiding this comment.
Handling branches is a bit tricky, so it's OK to take a bit of time to get this right.
Sorry, something went wrong.
|
Drat, the super-instruction refactor is broken. But 1868f91 works great! I'll debug later. |
Sorry, something went wrong.
|
I think it might be worth breaking up this PR into 3:
The handling of jumps has some subtleties, so we might as well get the other changes in while we refine the design of jump handling. |
Sorry, something went wrong.
I might do that, though I suspect there are mute lurking bugs that we will only find by attempting to implement jumps. Also, jumps will be an iterative design anyway. And where do you see handling EXTENDED_ARG fitting in? |
Sorry, something went wrong.
In another PR as well. I much prefer lots of small PRs. Large, draft PRs tend to block other progress. |
Sorry, something went wrong.
Will do. I wonder though -- is a draft PR more of a problem than a private branch? If you'd rather have me do more of the latter I'm fine with that, but draft PRs have the advantage that they run CI. |
Sorry, something went wrong.
When `_PyOptimizer_BackEdge` returns `NULL`, we should restore `next_instr` (and `stack_pointer`). To accomplish this we should jump to `resume_with_error` instead of just `error`. The problem this causes is subtle -- the only repro I have is in PR gh-106393, at commit d7df54b. But the fix is real (as shown later in that PR). While we're at it, also improve the debug output: the offsets at which traces are identified are now measured in bytes, and always show the start offset. This makes it easier to correlate executor calls with optimizer calls, and either with `dis` output. <!-- gh-issue-number: gh-104584 --> * Issue: gh-104584 <!-- /gh-issue-number -->
|
I pushed a leaner version, but without any of the significant changes to the branch strategy, so it's still a draft. Everything else has been split out or is being split out. |
Sorry, something went wrong.
8d07517 to
c87f9d6
Compare
July 7, 2023 04:07
Introduce a new macro, JUMP_POP_DISPATCH(x, n). This does JUMPBY(x), STACK_SHRINK(n), DISPATCH(). Most JUMP opcodes can use this. The exceptions are SEND, JUMP_BACKWARD, and JUMP_BACKWARD_NO_INTERRUPT. For JUMP_BACKWARD, I have to research whether CHECK_EVAL_BREAKER() and JUMPBY() commute. I think I'll just punt on SEND (it's too complex anyways).
This involves some subtle rearrangement of code in JUMP_BACKWARD.
This may destroy the symmetry or slow things down, but (for now) it's needed so that the executor can at least avoid bailing when the jump is not taken. (The original code was doing a jump 0 in that case.)
If JUMP_BACKWARD jumps to the start of the trace, add this. It contains an eval breaker check.
|
Okay, I'll close this. I'll create a new issue describing how I think branches could be handled. |
Sorry, something went wrong.
SENDFOR_ITERand its specializations, exceptFOR_ITER_GENENTER_EXECUTORPOP_JUMP_IF_TRUE/FALSEto only jump when neededJUMP_BACKWARDto top of trace becomes a specialJUMP_TO_TOPuopA big weakness (?) is that this always assumes that branches are rarely taken. Any time a branch or jump (other than to the top of the trace) is taken, we leave the trace.