Re: [Python-Dev] Generated Bytecode ...
On Fri, Oct 23, 2015 at 3:23 AM, Victor Stinner wrote: > Note: I propose "noopt" because we already have "optimization level 0" > which still uses optimizations, it's the default mode. It's different > than gcc -O0 which really disables all optimizations. I already prefix > the "noopt" suffix for .pyc files than "opt--1" proposed by Brett in > http://bugs.python.org/issue2506 Strictly speaking, this isn't completely true. Most (all?) C/C++ compilers do some level of optimization when they are "disabled". GCC/Clang, for example, both will do some form of constant folding with -O0. The compilers are just *much* less aggressive with the primary goal of making the debugging experience much more enjoyable. The situation here sounds similar -- we want an option to provide a better debugging and tracing experience, which seems like a very reasonable idea to me. -- Meador ___ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Generated Bytecode ...
On 10/26/2015 10:36 PM, Victor Stinner wrote: 2015-10-24 4:34 GMT+09:00 Terry Reedy : How about -x nopeep to specifically skip the peephole optimizer? Raymond wrote "IIRC, the code was never generated in the first place (before the peephole pass)." I based that suggestion on what others said about why code was not generated. I think the actual situation supports my point that turning off 'all optimizations' means reviewing the entire process of generating code, from start to finish, to find anything that might be called an 'optimization' and that could be disabled or given a 'un-optimized' alternative. -- Terry Jan Reedy ___ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Generated Bytecode ...
2015-10-24 4:34 GMT+09:00 Terry Reedy : > How about -x nopeep to specifically skip the peephole optimizer? Raymond wrote "IIRC, the code was never generated in the first place (before the peephole pass)." So "nopeep" would have a different purpose. Victor ___ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Generated Bytecode ...
On 10/23/2015 4:23 AM, Victor Stinner wrote: Hi, 2015-10-22 19:02 GMT+02:00 Brett Cannon : It's not specified anywhere; it's just what the peepholer decides to remove. The exact code can be found at https://hg.python.org/cpython/file/default/Python/peephole.c . There has been talk in the past for adding a -X flag to disable the peepholer, but it never went any farther beyond that. Yeah, I remember that I had the same issue than Stéphane when I worked on my astoptimizer project :-) I wanted to completly disable the peephole optimizer because I wanted to reimplement the optimizations on the AST instead of rewriting the bytecode. I would be nice to have a "-X noopt" command line option for that. How about -x nopeep to specifically skip the peephole optimizer? -- Terry Jan Reedy ___ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Generated Bytecode ...
> On Oct 22, 2015, at 10:02 AM, Brett Cannon wrote: > > So my question is, the byte code generator removes the unused functions, > variables etc…, is it right? > > Technically the peepholer removes the dead branch, but since the peepholer is > run on all bytecode you can't avoid it. IIRC, the code was never generated in the first place (before the peephole pass). This used to be true before the AST branch was added and I think it may still be true. Raymond Hettinger ___ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Generated Bytecode ...
> On Oct 25, 2015, at 12:33 PM, Raymond Hettinger > wrote: > >> On Oct 22, 2015, at 10:02 AM, Brett Cannon wrote: >> >> So my question is, the byte code generator removes the unused functions, >> variables etc…, is it right? >> >> Technically the peepholer removes the dead branch, but since the peepholer >> is run on all bytecode you can't avoid it. > > IIRC, the code was never generated in the first place (before the peephole > pass). This used to be true before the AST branch was added and I think it > may still be true. I just verified this. So Brett's post was incorrect and misleading. Raymond --- Verify by turning-off the optimizations -- cpython $ hg diff Python/peephole.c diff --git a/Python/peephole.c b/Python/peephole.c --- a/Python/peephole.c +++ b/Python/peephole.c @@ -383,7 +383,7 @@ /* Avoid situations where jump retargeting could overflow */ assert(PyBytes_Check(code)); codelen = PyBytes_GET_SIZE(code); -if (codelen > 32700) +if (codelen > 0) goto exitUnchanged; Then run a simple disassembly --- from dis import dis def f(x): if 0: print('First') print('Second') dis(f) The output is --- $ py tmp.py 6 0 LOAD_GLOBAL 0 (print) 3 LOAD_CONST 1 ('Second') 6 CALL_FUNCTION1 (1 positional, 0 keyword pair) 9 POP_TOP 10 LOAD_CONST 0 (None) 13 RETURN_VALUE ___ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Generated Bytecode ...
Thank you for your confirmation, I am going to read the devguide. > On 25 oct. 2015, at 7:50 PM, Raymond Hettinger > wrote: > > >>> On Oct 25, 2015, at 12:33 PM, Raymond Hettinger >>> wrote: >>> >>> On Oct 22, 2015, at 10:02 AM, Brett Cannon wrote: >>> >>> So my question is, the byte code generator removes the unused functions, >>> variables etc…, is it right? >>> >>> Technically the peepholer removes the dead branch, but since the peepholer >>> is run on all bytecode you can't avoid it. >> >> IIRC, the code was never generated in the first place (before the peephole >> pass). This used to be true before the AST branch was added and I think it >> may still be true. > > I just verified this. So Brett's post was incorrect and misleading. > > > Raymond > > > --- Verify by turning-off the optimizations -- > cpython $ hg diff Python/peephole.c > diff --git a/Python/peephole.c b/Python/peephole.c > --- a/Python/peephole.c > +++ b/Python/peephole.c > @@ -383,7 +383,7 @@ > /* Avoid situations where jump retargeting could overflow */ > assert(PyBytes_Check(code)); > codelen = PyBytes_GET_SIZE(code); > -if (codelen > 32700) > +if (codelen > 0) > goto exitUnchanged; > > Then run a simple disassembly --- > > from dis import dis > > def f(x): >if 0: >print('First') >print('Second') > > dis(f) > > The output is --- > > $ py tmp.py > 6 0 LOAD_GLOBAL 0 (print) > 3 LOAD_CONST 1 ('Second') > 6 CALL_FUNCTION1 (1 positional, 0 keyword pair) > 9 POP_TOP > 10 LOAD_CONST 0 (None) > 13 RETURN_VALUE > ___ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Generated Bytecode ...
Hi, 2015-10-22 19:02 GMT+02:00 Brett Cannon : > It's not specified anywhere; it's just what the peepholer decides to remove. > The exact code can be found at > https://hg.python.org/cpython/file/default/Python/peephole.c . There has > been talk in the past for adding a -X flag to disable the peepholer, but it > never went any farther beyond that. Yeah, I remember that I had the same issue than Stéphane when I worked on my astoptimizer project :-) I wanted to completly disable the peephole optimizer because I wanted to reimplement the optimizations on the AST instead of rewriting the bytecode. I would be nice to have a "-X noopt" command line option for that. By the way, the peephole optimizer cannot remove "if 0: yield" because it's a workaround of a limitation in CPython. It's not possible to declare that a function is a generator even if it doesn't call yield. Well, "async def" solves partially the issue, but sometimes you don't want generators with "async def". If I recall correctly, another usecase of "-X noopt" is code coverage: the peephole optimizers punchs holes in the code coverage because it looks like some lines are never executed. Note: I propose "noopt" because we already have "optimization level 0" which still uses optimizations, it's the default mode. It's different than gcc -O0 which really disables all optimizations. I already prefix the "noopt" suffix for .pyc files than "opt--1" proposed by Brett in http://bugs.python.org/issue2506 Victor ___ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Generated Bytecode ...
On Fri, Oct 23, 2015 at 3:05 PM, Terry Reedy wrote: > Indeed, whether 'pass' should be compiled to 'NOP' or nothing depends on > one's view of the meaning of pass and whether it must be executed (by going > though the ceval loop once and doing nothing) or not. Hmm. I thought 'pass' was a syntactic element, not an executable statement. For instance, these functions all contain the same code: def f1(): pass def f2(): """docstring""" def f3(): return None def f4(): global foo Or is there something I'm misunderstanding here? ChrisA ___ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Generated Bytecode ...
On 10/22/2015 1:56 PM, R. David Murray wrote: On Thu, 22 Oct 2015 17:02:48 -, Brett Cannon wrote: On Thu, 22 Oct 2015 at 09:37 Stéphane Wirtel wrote: Hi all, When we compile a python script # test.py if 0: x = 1 python -mdis test.py There is no byte code for the condition. The code above is logically equivalent to 'pass'. CPython could compile 'pass' (or code equivalent to it) to the NOP bytecode, but I believe it does not. (The doc implies that NOP is only introduced by the peephole optimizer as a replacement for other statements.) So my question is, >>> the byte code generator removes the unused functions, variables etc…, It does not do this. >>> def f(): a=111 >>> dis(f) 1 0 LOAD_CONST 1 (111) 3 STORE_FAST 0 (a) 6 LOAD_CONST 0 (None) 9 RETURN_VALUE A code checker might report that a in unused, suggesting that you remove the assignment manually, but python does not do it for you. >>> is it right? It depends on whether one philosophically considers the meaning of python code to be a particular computational operation or a particular computational result. From the former viewpoint, one might think or want the useless assignment. From the latter viewpoint, in this particular context, deleting the assignment statement would be correct. But this is too sophisticated a judgement for CPython's simple code improvement. The philosophical question is illustrated by "What is the meaning of '2+2'?". Does it mean 'get 2 and add 2' (and if so, when must this be done)? Does it mean '4'? Current constant folding at the AST or pre-bytecode stage presumes that the answer '4', at runtime, is adequate. Indeed, whether 'pass' should be compiled to 'NOP' or nothing depends on one's view of the meaning of pass and whether it must be executed (by going though the ceval loop once and doing nothing) or not. Technically the peepholer removes the dead branch, >> but since the peepholer is run on all bytecode you can't avoid it. There's an issue (http://bugs.python.org/issue2506) for being able to disable all optimizations (that Ned Batchelder, among others, would really Ned initially just asked for the peephole optimizer to be disabled, which is specific and concrete. He then seemed to ask to be able to disable 'all optimizations'. This is somewhat vague and presupposed a baseline of no optimizations, which is not practical. like to see happen :). Raymond rejected it as not being worthwhile. He noted that there are multiple costs for implementation, maintenance, documentation, and testing. Also that most things currently done by the peephole optimizer, after code is generated, could be done before or as code is generated, and that one cost might be to make better code generation more difficult. I still agree with Ned and others that there should, just on principle, be a way to disable all optimizations. The question is what counts as an optimization? Generating byte code is not part of the language. It could be considered a CPython optimization versus storing the original text or an ast version thereof. This is not practical. More realistic: would you have the optimization of no code for 'pass' disabled? Or how about constant folding? Or the optimization of having successive string literals pasted together in the parser, rather than later in the total process? (I believe I have read that this is where it currently happens.) My point here is that optimizations are spread throughout the chain from code to result. Most (all?) compilers have such a feature, for debugging reasons if nothing else. Compilers that make iffy assumptions and do non-equivalent transformations to produce faster code, at the cost of breaking some legal code, must have a means to disable such assumptions and transformations. Or rather, such optimizations should be off by default. Each optimization level defines a subset of the language for which the assumptions and transformations are valid. For CPython, it has been proposed that there should be optional optimization levels that assume that some dynamic features are not being used: the builtins module is not modified; built-in objects are not masked; modules are not monkey patched. Guido has so far rejected the idea of such language-subsetting optimizations. My strong impression is that the -O0 'no optimization' level of modern compilers (for C, for instance) *generally* means 'no potentially dangerous and wrong optimizations' and that they in fact include many safe optimizations relative to compilers of a few decades ago. I am sure that there is no way to disable many of the safe optimizations that are now so taken for granted that they are 'normal' and not seen as 'optimizations'. In other words, I believe that the meaning of 'no optimizations' has evolved.
Re: [Python-Dev] Generated Bytecode ...
On Thu, 22 Oct 2015 17:02:48 -, Brett Cannon wrote: > On Thu, 22 Oct 2015 at 09:37 Stéphane Wirtel wrote: > > > Hi all, > > > > When we compile a python script > > > > # test.py > > if 0: > > x = 1 > > > > python -mdis test.py > > > > There is no byte code for the condition. > > > > So my question is, the byte code generator removes the unused functions, > > variables etcâ¦, is it right? > > > > Technically the peepholer removes the dead branch, but since the peepholer > is run on all bytecode you can't avoid it. There's an issue (http://bugs.python.org/issue2506) for being able to disable all optimizations (that Ned Batchelder, among others, would really like to see happen :). Raymond rejected it as not being worthwhile. I still agree with Ned and others that there should, just on principle, be a way to disable all optimizations. Most (all?) compilers have such a feature, for debugging reasons if nothing else. We even have a way to spell it in the generated byte code files now (opt-0). But, someone would have to champion it and write a patch proposal. --David ___ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Generated Bytecode ...
On Thu, 22 Oct 2015 at 09:37 Stéphane Wirtel wrote: > Hi all, > > When we compile a python script > > # test.py > if 0: > x = 1 > > python -mdis test.py > > There is no byte code for the condition. > > So my question is, the byte code generator removes the unused functions, > variables etc…, is it right? > Technically the peepholer removes the dead branch, but since the peepholer is run on all bytecode you can't avoid it. > > What are the cases where the generator does not generate the byte codes ? > It's not specified anywhere; it's just what the peepholer decides to remove. The exact code can be found at https://hg.python.org/cpython/file/default/Python/peephole.c . There has been talk in the past for adding a -X flag to disable the peepholer, but it never went any farther beyond that. ___ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Generated Bytecode ...
Thank you Brett, I am going to read the source code, I am going to give a presentation at PyCon.IE about this part and I wanted to be sure about the dead branches. Thanks On 22 Oct 2015, at 19:02, Brett Cannon wrote: > On Thu, 22 Oct 2015 at 09:37 Stéphane Wirtel wrote: > >> Hi all, >> >> When we compile a python script >> >> # test.py >> if 0: >> x = 1 >> >> python -mdis test.py >> >> There is no byte code for the condition. >> >> So my question is, the byte code generator removes the unused functions, >> variables etc…, is it right? >> > > Technically the peepholer removes the dead branch, but since the peepholer > is run on all bytecode you can't avoid it. > > >> >> What are the cases where the generator does not generate the byte codes ? >> > > It's not specified anywhere; it's just what the peepholer decides to > remove. The exact code can be found at > https://hg.python.org/cpython/file/default/Python/peephole.c . There has > been talk in the past for adding a -X flag to disable the peepholer, but it > never went any farther beyond that. -- Stéphane Wirtel - http://wirtel.be - @matrixise signature.asc Description: OpenPGP digital signature ___ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] Generated Bytecode ...
Hi all, When we compile a python script # test.py if 0: x = 1 python -mdis test.py There is no byte code for the condition. So my question is, the byte code generator removes the unused functions, variables etc…, is it right? What are the cases where the generator does not generate the byte codes ? Thank you, Stéphane -- Stéphane Wirtel - http://wirtel.be - @matrixise signature.asc Description: OpenPGP digital signature ___ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com