On 7/12/20 9:04 AM, Daniel Moisset wrote:
>
> The existing implementation has optimizations here. If that's
> important, we could achieve the same result with a little dataflow
> analysis to optimize away the dead store. We could even
> special-case optimizing away dead stores /only/ to '_' and /only/
> in match/case statements and all would be forgiven.
>
> This might work, although it's quite different to what python does in
> general (are you supposed to see the value of `_` in a debugger? or in
> `locals()`? )
All excellent points. The debugger question is easier to answer.
Debuggers for compiled code have dealt with this for years; I'm unsure
of the exact wording but gdb prints something like "<value optimized out>".
As for locals(), my first thought was "suppress the optimization in the
presence of a locals() call". I dimly recall a precedent where the
presence of locals() in a function body affected code generation, though
sadly it escapes me at the moment**. Anyway, that seems like a nasty
hack, and it only handles one method of extracting a locals
dict--there's several more, including sys._getframe and
inspect.getframeinfo. And then the user could rebind those and we
wouldn't notice. This seems like a non-starter.
Having thought about it some, I propose it'd be acceptable to do dead
store optimization if-and-only-if optimizations are explicitly enabled,
e.g. with "-O". Allowing explicitly-enabled optimizations to observably
affect runtime behavior does have some precedent, e.g. "-OO" which
breaks doctest, docopt, etc. It'd be a shame if the existence of
locals() et al meant Python could never ever perform dead store
optimization.
Your other (elided) point is correct too, about sequence matching for a
sequence we don't care about not being as cheap and simple as a store
and an extra reference.
Cheers,
//arry/
** Or maybe I'm confused and thinking of something else entirely. Maybe
it was "import * inside a function body disables fast locals in Python
2"? But that doesn't seem to be true either.
>
> The existing implementation has optimizations here. If that's
> important, we could achieve the same result with a little dataflow
> analysis to optimize away the dead store. We could even
> special-case optimizing away dead stores /only/ to '_' and /only/
> in match/case statements and all would be forgiven.
>
> This might work, although it's quite different to what python does in
> general (are you supposed to see the value of `_` in a debugger? or in
> `locals()`? )
All excellent points. The debugger question is easier to answer.
Debuggers for compiled code have dealt with this for years; I'm unsure
of the exact wording but gdb prints something like "<value optimized out>".
As for locals(), my first thought was "suppress the optimization in the
presence of a locals() call". I dimly recall a precedent where the
presence of locals() in a function body affected code generation, though
sadly it escapes me at the moment**. Anyway, that seems like a nasty
hack, and it only handles one method of extracting a locals
dict--there's several more, including sys._getframe and
inspect.getframeinfo. And then the user could rebind those and we
wouldn't notice. This seems like a non-starter.
Having thought about it some, I propose it'd be acceptable to do dead
store optimization if-and-only-if optimizations are explicitly enabled,
e.g. with "-O". Allowing explicitly-enabled optimizations to observably
affect runtime behavior does have some precedent, e.g. "-OO" which
breaks doctest, docopt, etc. It'd be a shame if the existence of
locals() et al meant Python could never ever perform dead store
optimization.
Your other (elided) point is correct too, about sequence matching for a
sequence we don't care about not being as cheap and simple as a store
and an extra reference.
Cheers,
//arry/
** Or maybe I'm confused and thinking of something else entirely. Maybe
it was "import * inside a function body disables fast locals in Python
2"? But that doesn't seem to be true either.