You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Specialization of some instructions does not conform to PEP 659, and prevents PEP 669 #100982
As written, PEP 659 says that individual specializations are restricted to a single instruction.
PEP 669 relies on this, as it also wants to replace instructions at runtime, and it would break if specialization occurs across multiple instructions.
Currently there are a two places where we break this design by specializing pairs of instructions together:
COMPARE_OPPOP_JUMP_IF_ pairs are specialized together
FOR_ITERSTORE_FAST are specialized together
The second will go away with the register VM, and doesn't seem to be an issue in practice.
It is the COMPARE_OPPOP_JUMP_IF_ specialization that is problematic, as PEP 669 wants to instrument branches.
Instrumenting the POP_JUMP_IF_ doesn't work if the COMPARE_OP specialization jumps over it.
The solution is to replace the COMPARE_OPPOP_JUMP_IF_ pair with a single COMPARE_AND_BRANCH instruction that can be specialized or instrumented atomically.
changed the title [-]Specialization of `COMPARE_OP` does not conform to PEP 659, and prevents PEP 669[/-][+]Specialization of some instructions does not conform to PEP 659, and prevents PEP 669[/+]on Jan 27, 2023
Although BINARY_OP_INPLACE_ADD_UNICODE and CALL_NO_KW_LIST_APPEND don't cross boundaries they may cross lines which interferes with instrumentation for LINE events.
The instruction that is skipped in CALL_NO_KW_LIST_APPEND is always a POP_TOP. We can fix this by making sure that the POP_TOP following a call has no location. It probably should anyway.
The compiler already gives POP_TOPNO_LOCATION so nothing to do here
BINARY_OP_INPLACE_ADD_UNICODE is still a problem. It is rare, so the extra cost of de-specializing it during instrumentation and preventing that specialization if instrumentation is present would probably be OK.
Note:
This is only an issue for instrumentation of LINE events. INSTRUCTION events prevent all specialization, so there cannot be a conflict.
An alternative to fixing BINARY_OP_INPLACE_ADD_UNICODE is to restore the old behavior of BINARY_ADD to special case adding strings, and make sure that BINARY_OP specialization is so good that the performance of plain BINARY_ADD is irrelevant.
Which leaves FOR_ITER_RANGE. I'm hoping that improvements to freelists and integer representation will make the cost of creating the temporary int tolerable.
The second will go away with the register VM, and doesn't seem to be an issue in practice.
Since there is no register VM (and probably won't be one, or not for a long time), what should we do about this? Ignore it because it "doesn't seem to be an issue in practice"?
OTOH maybe this issue can be closed, since it appears we do have PEP 669 after all? @markshannon
Activity
markshannon commentedon Jan 12, 2023
Superinstructions are also a problem for PEP 669, but are simpler to handle, and will also go away with the register VM.
GH-100982: Add `COMPARE_AND_BRANCH` instruction (GH-100983)
brandtbucher commentedon Jan 18, 2023
BINARY_OP_INPLACE_ADD_UNICODEandCALL_NO_KW_LIST_APPENDare two more examples of "adaptive superinstructions".Like
FOR_ITER, though, they don't cross a branch and will probably disappear when we get a register VM.markshannon commentedon Jan 27, 2023
https://github.com/python/cpython/pull/100983[)](https://github.com/python/cpython/commit/7b14c2ef194b6eed79670aa9d7e29ab8e2256a56) fixed the
COMPARE_OPissue, so I'm retitling this issue.[-]Specialization of `COMPARE_OP` does not conform to PEP 659, and prevents PEP 669[/-][+]Specialization of some instructions does not conform to PEP 659, and prevents PEP 669[/+]markshannon commentedon Jan 27, 2023
Although
BINARY_OP_INPLACE_ADD_UNICODEandCALL_NO_KW_LIST_APPENDdon't cross boundaries they may cross lines which interferes with instrumentation forLINEevents.markshannon commentedon Jan 27, 2023
The instruction that is skipped in
CALL_NO_KW_LIST_APPENDis always aPOP_TOP.We can fix this by making sure that thePOP_TOPfollowing a call has no location. It probably should anyway.The compiler already gives
POP_TOPNO_LOCATIONso nothing to do hereBINARY_OP_INPLACE_ADD_UNICODEis still a problem. It is rare, so the extra cost of de-specializing it during instrumentation and preventing that specialization if instrumentation is present would probably be OK.Note:
This is only an issue for instrumentation of
LINEevents.INSTRUCTIONevents prevent all specialization, so there cannot be a conflict.markshannon commentedon Jan 27, 2023
An alternative to fixing
BINARY_OP_INPLACE_ADD_UNICODEis to restore the old behavior ofBINARY_ADDto special case adding strings, and make sure thatBINARY_OPspecialization is so good that the performance of plainBINARY_ADDis irrelevant.markshannon commentedon Jan 27, 2023
Which leaves
FOR_ITER_RANGE. I'm hoping that improvements to freelists and integer representation will make the cost of creating the temporary int tolerable.GH-100982: Restrict `FOR_ITER_RANGE` to a single instruction to allow…
Merge branch 'main' into lockfreecp
GH-100982: Break up COMPARE_AND_BRANCH (GH-102801)
pythonGH-100982: Break up COMPARE_AND_BRANCH (pythonGH-102801)
pythonGH-100982: Break up COMPARE_AND_BRANCH (pythonGH-102801)
gvanrossum commentedon May 17, 2023
Since there is no register VM (and probably won't be one, or not for a long time), what should we do about this? Ignore it because it "doesn't seem to be an issue in practice"?
OTOH maybe this issue can be closed, since it appears we do have PEP 669 after all? @markshannon
markshannon commentedon Jun 2, 2023
FOR_ITERandSTORE_FASTare no longer specialized together (specifically for PEP 669): #101985So, yes this can be closed.
markshannon commentedon Jun 19, 2023
It looks like we never fixed up
BINARY_OP_INPLACE_ADD_UNICODEpythonGH-100982: Restrict `FOR_ITER_RANGE` to a single instruction to…