[Python-Dev] JUMP_ABSOLUTE in nested if statements
Raymond Hettinger
raymond.hettinger at gmail.com
Sat Jun 18 18:10:21 EDT 2016
> On Jun 18, 2016, at 2:04 PM, Obiesie ike-nwosu via Python-Dev <python-dev at python.org> wrote:
>
> Hi,
>
> Could some one give a hand with explaining to me why we have a JUMP_ABSOLUTE followed by a JUMP_FORWARD op code when this function is disassembled.
> < snipped>
> From my understanding, once JUMP_ABSOLUTE is executed, then JUMP_FORWARD is never gotten to so must be dead code so why is it being generated?
> Furthermore why is JUMP_ABSOLUTE rather than JUMP_FORWARD used in this particular case of nested if statements? I have tried other types of nested if statements and it has always been JUMP_FORWARD that
> is generated.
The AST compilation step generates code with two JUMP_FORWARDs (see below). Then, the peephole optimizer recognizes a jump-to-an-unconditional-jump and replaces the first one with a JUMP_ABSOLUTE to save an unnecessary step.
The reason that it uses JUMP_ABSOLUTE instead of JUMP_FORWARD is that the former is more general (it can jump backwards). Using the more general form reduces the complexity of the optimizer.
The reason that the remaining jump-to-jump isn't optimized is that the peepholer is intentionally kept simplistic, making only a single pass over the opcodes. That misses some optimizations but gets the most common cases.
FWIW, the jump opcodes are very fast, so missing the final jump-to-jump isn't much of a loss.
If you're curious, the relevant code is in Python/compile.c and Python/peephole.c. The compile.c code generated opcodes in the most straight-forward way possible and then the peephole optimizer gets some of the low-hanging fruit by making a few simple transformations.
Raymond
------------ AST generated code before peephole optimization -----------------
5 0 LOAD_CONST 1 (10)
3 LOAD_CONST 2 (11)
6 BUILD_TUPLE 2
9 UNPACK_SEQUENCE 2
12 STORE_FAST 0 (a)
15 STORE_FAST 1 (b)
6 18 LOAD_FAST 0 (a)
21 LOAD_CONST 1 (10)
24 COMPARE_OP 5 (>=)
27 POP_JUMP_IF_FALSE 53
7 30 LOAD_FAST 1 (b)
33 LOAD_CONST 2 (11)
36 COMPARE_OP 5 (>=)
39 POP_JUMP_IF_FALSE 50
8 42 LOAD_CONST 3 ('hello world')
45 PRINT_ITEM
46 PRINT_NEWLINE
47 JUMP_FORWARD 0 (to 50)
>> 50 JUMP_FORWARD 0 (to 53)
>> 53 LOAD_CONST 0 (None)
56 RETURN_VALUE
More information about the Python-Dev
mailing list