bpo-32477: Move jumps optimization from the peepholer to the compiler. by serhiy-storchaka · Pull Request #5077 · python/cpython (original) (raw)

EDIT: _module_repr_from_spec() code was wrong, I fixed it.

I tested on this Python code:

def _module_repr_from_spec(spec): """Return the repr to use for the module.""" # We mostly replicate _module_repr() using the spec attributes. name = '?' if spec.name is None else spec.name if spec.origin is None: if spec.loader is None: return '<module {!r}>'.format(name) else: return '<module {!r} ({!r})>'.format(name, spec.loader) else: if spec.has_location: return '<module {!r} from {!r}>'.format(name, spec.origin) else: return '<module {!r} ({})>'.format(spec.name, spec.origin)

I ran the peephole optimizer twice:

diff --git a/Python/compile.c b/Python/compile.c index 45e78cb22c..7d361c6af0 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -5577,6 +5577,13 @@ makecode(struct compiler *c, struct assembler *a) if (!bytecode) goto error;

The bytecode is different.

Before:

             60 CALL_METHOD              2
             62 RETURN_VALUE
             64 JUMP_FORWARD            36 (to 102)

 13     >>   66 LOAD_FAST                0 (spec)
             68 LOAD_ATTR                4 (has_location)
             70 POP_JUMP_IF_FALSE       86

After:

             60 CALL_METHOD              2
             62 RETURN_VALUE

 13     >>   64 LOAD_FAST                0 (spec)
             66 LOAD_ATTR                4 (has_location)
             68 POP_JUMP_IF_FALSE       84

=> the JUMP_FORWARD has been removed: it was deadcode. As a side effect, offsets and jump targets are different. Example: LOAD_FAST moves from offset 66 to 62, and "POP_JUMP_IF_FALSE 86" becomes "POP_JUMP_IF_FALSE 84".

The question is now if we can modify the peephole to get the same result when it's only run once, or if we have to move the jump optimization to the compiler.