[New-bugs-announce] [issue37271] Make multiple passes of the peephole optimizer until bytecode cannot be optimized further

Pablo Galindo Salgado report at bugs.python.org
Thu Jun 13 21:58:30 EDT 2019


New submission from Pablo Galindo Salgado <pablogsal at gmail.com>:

The peephole optimizer currently does not optimize the result of its own optimization when its possible. For example, consider the following code:

    if a:
        if b:
            if (c or d):
                foo()
        else:
            bar()
    else:
        baz()

The bytecode for this is:

  2           0 LOAD_GLOBAL              0 (a)
              2 POP_JUMP_IF_FALSE       32

  4           4 LOAD_GLOBAL              1 (b)
              6 POP_JUMP_IF_FALSE       24

  5           8 LOAD_GLOBAL              2 (c)
             10 POP_JUMP_IF_TRUE        16

  6          12 LOAD_GLOBAL              3 (d)
             14 POP_JUMP_IF_FALSE       30

  7     >>   16 LOAD_GLOBAL              4 (foo)
             18 CALL_FUNCTION            0
             20 POP_TOP
             22 JUMP_ABSOLUTE           38

  9     >>   24 LOAD_GLOBAL              5 (bar)
             26 CALL_FUNCTION            0
             28 POP_TOP
        >>   30 JUMP_FORWARD             6 (to 38)

 11     >>   32 LOAD_GLOBAL              6 (baz)
             34 CALL_FUNCTION            0
             36 POP_TOP
        >>   38 LOAD_CONST               0 (None)
             40 RETURN_VALUE

Notice that the 14 POP_JUMP_IF_FALSE 30 jumps to another jump (30 JUMP_FORWARD 6 (to 38)). If we repeat the optimizations until the resulting bytecode does not change more we get:

  2           0 LOAD_GLOBAL              0 (a)
              2 POP_JUMP_IF_FALSE       32

  4           4 LOAD_GLOBAL              1 (b)
              6 POP_JUMP_IF_FALSE       24

  5           8 LOAD_GLOBAL              2 (c)
             10 POP_JUMP_IF_TRUE        16

  6          12 LOAD_GLOBAL              3 (d)

  5          14 POP_JUMP_IF_FALSE       38

  7     >>   16 LOAD_GLOBAL              4 (foo)
             18 CALL_FUNCTION            0
             20 POP_TOP
             22 JUMP_ABSOLUTE           38

  9     >>   24 LOAD_GLOBAL              5 (bar)
             26 CALL_FUNCTION            0
             28 POP_TOP
             30 JUMP_FORWARD             6 (to 38)

 11     >>   32 LOAD_GLOBAL              6 (baz)
             34 CALL_FUNCTION            0
             36 POP_TOP
        >>   38 LOAD_CONST              

Notice that in this example the original instruction now is (14 POP_JUMP_IF_FALSE  38).

----------
components: Interpreter Core
messages: 345543
nosy: pablogsal
priority: normal
severity: normal
status: open
title: Make multiple passes of the peephole optimizer until bytecode cannot be optimized further
versions: Python 3.9

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue37271>
_______________________________________


More information about the New-bugs-announce mailing list