Description
There are several code patterns that can cause multiple stores to the same locals index in near succession, without any intervening instructions that can possibly use the stored value. One such code pattern is e.g. a, a, b = x, y, z
. Another (since PEP 709) is a = [_ for a in []]
. There are likely others.
In such cases, all but the final store can be replaced with POP_TOP
. This alone isn't a huge gain, but this can also allow apply_static_swaps
to take effect in these cases (because it can't safely reorder writes to the same location, but it can safely reorder POP_TOPs at will), removing SWAPs, which shrinks code size and reduces runtime overhead.
Not sure how much of a gain this will be in realistic cases, but it's also not hard to implement, so it seems worth doing as a marginal improvement to compiler output.
Note that in order to maintain tracing / debugger compatibility, we can only do this if line number is the same for all the store instructions. And we definitely can't eliminate the final store, even if it also appears to be unused, since it can always be visible to tracers/debuggers/locals()/etc.
Linked PRs
- gh-104635: Eliminate redundant STORE_FAST instructions in the compiler #105040
- gh-104635: Eliminate redundant STORE_FAST instructions in the compiler #105320
- gh-104635: Add NO_EXCEPTION flag to opcode metadata #106394
- gh-104635: Expand optimization for dead store elimination #106571
- gh-104635: Add a test case for variables that have a dependency. #106583