Python Bytecode

Christos TZOTZIOY Georgiou DLNXPEGFQVEB at spammotel.com
Wed Aug 21 06:47:26 EDT 2002


On Fri, 02 Aug 2002 16:53:27 GMT, rumours say that "Terry Reedy"
<tjreedy at udel.edu> might have written:

>Can you or someone answer a question regarding the following from the
>above:
>"
>JUMP_IF_TRUE    delta
>If TOS is true, increment the byte code counter by delta. TOS is left
>on the stack.
>
>JUMP_IF_FALSE    delta
>If TOS is false, increment the byte code counter by delta. TOS is not
>changed.
>"

As Tim, Neal and Michael have also noticed, there are two cases
(shortcut 'and' - 'or' comparisons and multiple comparisons, eg. 0<x<10)
where the TOS value must not be popped.
There are two quick-and-dirty ways to overcome this possibility, both
introducing new opcodes (affecting opcodes.h, ceval.c, compile.c):

1: introduce JUMP_IF_FALSE_POP and JUMP_IF_TRUE_POP (both doing a test
and then a pop).  They can be used in the following compile.c functions:
com_list_if, com_assert_stmt, com_if_stmt, com_while_stmt,
com_try_except.  The relevant POP_TOP's can be safely removed then, and
so can two JUMP_FORWARD's.

2: change JUMP_IF_FALSE and JUMP_IF_TRUE to always pop (and remove all
JUMP_IF related POP_TOP's), but then you introduce two opcodes:
STORE_TRUE and STORE_FALSE (STORE_TRUE would PUSH(Py_True);
Py_INCREF(Py_True); and samewise STORE_FALSE), which should be inserted
at the end of com_test and com_and_test respectively.
The slightly more tough point here is com_comparison, where if you reach
the "if (anchor)" point, instead of ROT_TWO and then POP_TOP, you must
POP_TOP and then PUSH_FALSE (since you get to that point *always* after
a JUMP_IF_FALSE) to let the False value pass through to the next opcode.

I agree (without any thorough scientific backing :) that the savings
should not be that great; I'll give it (method 2) a try though, and
report back... won't make any promises :)

PS An opcode optimizing pass would be interesting... stuff like
STORE_FAST n and then immediate LOAD_FAST n, which seem often to be used
in loops with calculations using intermediate variables, are good
candidates, but in many cases (like my example) would need new opcodes
(STORE_FAST_NOPOP).
-- 
TZOTZIOY, I speak England very best,
Real email address: 'dHpvdEBzaWwtdGVjLmdy\n'.decode('base64')



More information about the Python-list mailing list