[Python-Dev] lnotab and the AST optimizer

2008-07-24 Thread Thomas Lee
I'm making some good progress with the AST optimizer, and now the main 
thing standing in my way is lnotab. Currently lnotab expects bytecode 
sequencing to be roughly in-sync with the order of the source file and a 
few things that the optimizer does (e.g. swapping the bodies of an 
if/else after removing negation such that if not X: A; else: B becomes 
if X: B; else A) breaks this assumption. This will result in either an 
assertion failure or incorrect line numbers being reported.


It seems that lnotab is used in relatively few places in the source code 
at the moment, but if I'm going to make a change to how lnotab works I 
want to do so in a way that's going to allow me to move forward while 
keeping everybody happy.


I'm away for a few days so I probably won't be able to get back to 
anybody until either Sunday or Monday, but I'd appreciate it if anybody 
in the know can weigh in on this.


Cheers,
Tom
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] lnotab and the AST optimizer

2008-07-24 Thread Antoine Pitrou

Hi,

 I'm making some good progress with the AST optimizer, and now the main 
 thing standing in my way is lnotab. Currently lnotab expects bytecode 
 sequencing to be roughly in-sync with the order of the source file and a 
 few things that the optimizer does (e.g. swapping the bodies of an 
 if/else after removing negation such that if not X: A; else: B becomes 
 if X: B; else A) breaks this assumption. This will result in either an 
 assertion failure or incorrect line numbers being reported.

In http://bugs.python.org/issue2459 (speedup for / while / if with better
bytecode) I had the same problem and decided to change the lnotab format so
that line number increments are signed bytes rather than unsigned. The proposed
patch contains many other changes, but with a bit of perseverance you may be
able to extract the lnotab-related modifications... ;)

This modification will allow many more types of control flow transformations
than the current scheme does.


By the way:
 swapping the bodies of an 
 if/else after removing negation such that if not X: A; else: B becomes 
 if X: B; else A)

Is this really an optimization? if and if not should use the same number of
opcodes (the former produces JUMP_IF_FALSE and the latter JUMP_IF_TRUE).

Regards

Antoine.


___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] lnotab and the AST optimizer

2008-07-24 Thread Antoine Pitrou
Antoine Pitrou solipsis at pitrou.net writes:
 
 In http://bugs.python.org/issue2459 (speedup for / while / if with better
 bytecode) I had the same problem and decided to change the lnotab format so
 that line number increments are signed bytes rather than unsigned.

By the way, the same change could be done for relative jump offsets in the
bytecode (change them from unsigned shorts to signed shorts). Taken together,
both modifications would release a lot of constraints on the ordering of code
blocks.


___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] lnotab and the AST optimizer

2008-07-24 Thread Thomas Lee

Antoine Pitrou wrote:

Hi,

  
Hi. Thanks for getting back to me so quickly. I can even respond before 
I have to drag myself off to bed. :)


I'm making some good progress with the AST optimizer, and now the main 
thing standing in my way is lnotab. Currently lnotab expects bytecode 
sequencing to be roughly in-sync with the order of the source file and a 
few things that the optimizer does (e.g. swapping the bodies of an 
if/else after removing negation such that if not X: A; else: B becomes 
if X: B; else A) breaks this assumption. This will result in either an 
assertion failure or incorrect line numbers being reported.



In http://bugs.python.org/issue2459 (speedup for / while / if with better
bytecode) I had the same problem and decided to change the lnotab format so
that line number increments are signed bytes rather than unsigned. The proposed
patch contains many other changes, but with a bit of perseverance you may be
able to extract the lnotab-related modifications... ;)

This modification will allow many more types of control flow transformations
than the current scheme does.

  

Great, thanks! I'll check it out next week.

By the way:
  
swapping the bodies of an 
if/else after removing negation such that if not X: A; else: B becomes 
if X: B; else A)



Is this really an optimization? if and if not should use the same number of
opcodes (the former produces JUMP_IF_FALSE and the latter JUMP_IF_TRUE).

  


Not quite. :) Even if we were producing a JUMP_IF_FALSE, it'd still be 
nice to optimize away the UNARY_NOT in the former.


In practice, both actually produce a JUMP_IF_TRUE due to an existing 
optimization in the peephole optimizer which does just that. I'm trying 
to emulate this at the AST level because I'm part of a secret, evil 
conspiracy to be rid of the peephole optimizer. Shh. The relevant code 
in the peepholer, plus comment:


   /* Replace UNARY_NOT JUMP_IF_FALSE POP_TOP with
  withJUMP_IF_TRUE POP_TOP */
   case UNARY_NOT:
   if (codestr[i+1] != JUMP_IF_FALSE  ||
   codestr[i+4] != POP_TOP  ||
   !ISBASICBLOCK(blocks,i,5))
   continue;
   tgt = GETJUMPTGT(codestr, (i+1));
   if (codestr[tgt] != POP_TOP)
   continue;
   j = GETARG(codestr, i+1) + 1;
   codestr[i] = JUMP_IF_TRUE;
   SETARG(codestr, i, j);
   codestr[i+3] = POP_TOP;
   codestr[i+4] = NOP;
   break;

A little hackage with the dis module seems to confirm this is the case.

Of course, if you know of a situation where this optimization doesn't 
apply and we actually wind up with a JUMP_IF_FALSE for an if/else 
post-peephole, I'm all ears.


Thanks again!

Cheers,
T

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] lnotab and the AST optimizer

2008-07-24 Thread Thomas Lee

Antoine Pitrou wrote:

Antoine Pitrou solipsis at pitrou.net writes:
  

In http://bugs.python.org/issue2459 (speedup for / while / if with better
bytecode) I had the same problem and decided to change the lnotab format so
that line number increments are signed bytes rather than unsigned.



By the way, the same change could be done for relative jump offsets in the
bytecode (change them from unsigned shorts to signed shorts). Taken together,
both modifications would release a lot of constraints on the ordering of code
blocks.


___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/tom%40vector-seven.com
  
By the way, you were right about JUMP_IF_TRUE/JUMP_IF_FALSE. It's far 
too late. Apologies.


I'm still pretty sure this is the peepholer's doing, though, and if 
that's the case then I want to try and deal with it at the AST level.


Which is what's being achieved with the AST optimization I originally 
proposed, right?


Cheers,
T
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] lnotab and the AST optimizer

2008-07-24 Thread Antoine Pitrou
Thomas Lee tom at vector-seven.com writes:
 By the way, you were right about JUMP_IF_TRUE/JUMP_IF_FALSE. It's far 
 too late. Apologies.
 
 I'm still pretty sure this is the peepholer's doing,

Yes indeed.

 Which is what's being achieved with the AST optimization I originally 
 proposed, right?

Well, not exactly, your optimization eliminates the UNARY_NOT by swapping the
if/else blocks, while the peepholer eliminates the UNARY_NOT by fusing it with
the subsequent jump opcode. In this case it doesn't make much of a difference,
but if there is only an if without an else, the peepholer's optimization is
still possible while yours is not.

(bottom line: the peepholer is not dead!)

cheers,

Antoine.


___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] lnotab and the AST optimizer

2008-07-24 Thread Thomas Lee

Antoine Pitrou wrote:

Thomas Lee tom at vector-seven.com writes:
  
By the way, you were right about JUMP_IF_TRUE/JUMP_IF_FALSE. It's far 
too late. Apologies.


I'm still pretty sure this is the peepholer's doing,



Yes indeed.

  
Which is what's being achieved with the AST optimization I originally 
proposed, right?



Well, not exactly, your optimization eliminates the UNARY_NOT by swapping the
if/else blocks, while the peepholer eliminates the UNARY_NOT by fusing it with
the subsequent jump opcode. In this case it doesn't make much of a difference,
but if there is only an if without an else, the peepholer's optimization is
still possible while yours is not.

  


Unless a pass is injected into the if body, which will generate no 
additional bytecode and still have the same net effect.



(bottom line: the peepholer is not dead!)

  

We'll see ;)

Thanks for all your help, I'm looking forward to getting my hands on 
that patch.


Cheers,
T

___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] lnotab and the AST optimizer

2008-07-24 Thread Phillip J. Eby

At 12:56 AM 7/25/2008 +1000, Thomas Lee wrote:
I'm making some good progress with the AST optimizer, and now the 
main thing standing in my way is lnotab. Currently lnotab expects 
bytecode sequencing to be roughly in-sync with the order of the 
source file and a few things that the optimizer does (e.g. swapping 
the bodies of an if/else after removing negation such that if not 
X: A; else: B becomes if X: B; else A) breaks this assumption. 
This will result in either an assertion failure or incorrect line 
numbers being reported.


It seems that lnotab is used in relatively few places in the source 
code at the moment, but if I'm going to make a change to how lnotab 
works I want to do so in a way that's going to allow me to move 
forward while keeping everybody happy.


I'm away for a few days so I probably won't be able to get back to 
anybody until either Sunday or Monday, but I'd appreciate it if 
anybody in the know can weigh in on this.


I'd personally love it if the lnotab were capable of handling line 
numbers from different files as well as out-of-order lines.  (For 
function inlining, among other more esoteric things.)


___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] lnotab and the AST optimizer

2008-07-24 Thread Greg Ewing

Thomas Lee wrote:
I'm making some good progress with the AST optimizer, and now the main 
thing standing in my way is lnotab.


My suggestion would be to drop the idea of trying to
compress the lnotab in clever ways, and just make it
a straightforward list of bytecode offset/line number
pairs. I can't imagine that the size of an uncompressed
lnotab would be a problem in this day and age.

If ordering is an issue, generate it internally as a
dict and convert it to a sorted list on output.

--
Greg
___
Python-Dev mailing list
Python-Dev@python.org
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com