[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.


------------ 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