8000 bpo-46031: add POP_JUMP_IF_NOT_NONE and POP_JUMP_IF_NONE (GH-30019) · python/cpython@3db762d · GitHub
[go: up one dir, main page]

Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 3db762d

Browse files
authored
bpo-46031: add POP_JUMP_IF_NOT_NONE and POP_JUMP_IF_NONE (GH-30019)
1 parent 35d6540 commit 3db762d

File tree

9 files changed

+86
-14
lines changed

9 files changed

+86
-14
lines changed

Doc/library/dis.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,20 @@ All of the following opcodes use their arguments.
896896
.. versionadded:: 3.11
897897

898898

899+
.. opcode:: POP_JUMP_IF_NOT_NONE (target)
900+
901+
If TOS is not none, sets the bytecode counter to *target*. TOS is popped.
902+
903+
.. versionadded:: 3.11
904+
905+
906+
.. opcode:: POP_JUMP_IF_NONE (target)
907+
908+
If TOS is none, sets the bytecode counter to *target*. TOS is popped.
909+
910+
.. versionadded:: 3.11
911+
912+
899913
.. opcode:: PREP_RERAISE_STAR
900914

901915
Combines the raised and reraised exceptions list from TOS, into an exception

Doc/whatsnew/3.11.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,9 @@ CPython bytecode changes
398398
* Added :opcode:`COPY`, which pushes the *i*-th item to the top of the stack.
399399
The item is not removed from its original location.
400400

401+
* Add :opcode:`POP_JUMP_IF_NOT_NONE` and :opcode:`POP_JUMP_IF_NONE` opcodes to
402+
speed up conditional jumps.
403+
401404
* :opcode:`JUMP_IF_NOT_EXC_MATCH` no longer pops the active exception.
402405

403406

Include/opcode.h

Lines changed: 7 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/importlib/_bootstrap_external.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ def _write_atomic(path, data, mode=0o666):
378378
# Python 3.11a4 3470 (bpo-46221: PREP_RERAISE_STAR no longer pushes lasti)
379379
# Python 3.11a4 3471 (bpo-46202: remove pop POP_EXCEPT_AND_RERAISE)
380380
# Python 3.11a4 3472 (bpo-46009: replace GEN_START with POP_TOP)
381+
# Python 3.11a4 3473 (Add POP_JUMP_IF_NOT_NONE/POP_JUMP_IF_NONE opcodes)
381382

382383
#
383384
# MAGIC must change whenever the bytecode emitted by the compiler may no
@@ -387,7 +388,7 @@ def _write_atomic(path, data, mode=0o666):
387388
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
388389
# in PC/launcher.c must also be updated.
389390

390-
MAGIC_NUMBER = (3472).to_bytes(2, 'little') + b'\r\n'
391+
MAGIC_NUMBER = (3473).to_bytes(2, 'little') + b'\r\n'
391392
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
392393

393394
_PYCACHE = '__pycache__'

Lib/opcode.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,9 @@ def jabs_op(name, op):
148148
haslocal.append(125)
149149
def_op('DELETE_FAST', 126) # Local variable number
150150
haslocal.append(126)
151-
152151
jabs_op('JUMP_IF_NOT_EG_MATCH', 127)
153-
152+
jabs_op('POP_JUMP_IF_NOT_NONE', 128)
153+
jabs_op('POP_JUMP_IF_NONE', 129)
154154
def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3)
155155

156156
def_op('MAKE_FUNCTION', 132) # Flags
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add :opcode:`POP_JUMP_IF_NOT_NONE` and :opcode:`POP_JUMP_IF_NONE` opcodes to speed up conditional jumps.

Python/ceval.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4049,6 +4049,30 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
40494049
DISPATCH();
40504050
}
40514051

4052+
TARGET(POP_JUMP_IF_NOT_NONE) {
4053+
PyObject *value = POP();
4054+
if (!Py_IsNone(value)) {
4055+
Py_DECREF(value);
4056+
JUMPTO(oparg);
4057+
CHECK_EVAL_BREAKER();
4058+
DISPATCH();
4059+
}
4060+
Py_DECREF(value);
4061+
DISPATCH();
4062+
}
4063+
4064+
TARGET(POP_JUMP_IF_NONE) {
4065+
PyObject *value = POP();
4066+
if (Py_IsNone(value)) {
4067+
Py_DECREF(value);
4068+
JUMPTO(oparg);
4069+
CHECK_EVAL_BREAKER();
4070+
DISPATCH();
4071+
}
4072+
Py_DECREF(value);
4073+
DISPATCH();
4074+
}
4075+
40524076
TARGET(JUMP_IF_FALSE_OR_POP) {
40534077
PyObject *cond = TOP();
40544078
int err;

Python/compile.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,8 @@ stack_effect(int opcode, int oparg, int jump)
11101110

11111111
case POP_JUMP_IF_FALSE:
11121112
case POP_JUMP_IF_TRUE:
1113+
case POP_JUMP_IF_NONE:
1114+
case POP_JUMP_IF_NOT_NONE:
11131115
return -1;
11141116

11151117
case LOAD_GLOBAL:
@@ -8519,6 +8521,21 @@ optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts)
85198521
bb->b_instr[i+1].i_opcode = NOP;
85208522
}
85218523
break;
8524+
case IS_OP:
8525+
cnt = get_const_value(inst->i_opcode, oparg, consts);
8526+
if (cnt == NULL) {
8527+
goto error;
8528+
}
8529+
int jump_op = i+2 < bb->b_iused ? bb->b_instr[i+2].i_opcode : 0;
8530+
if (Py_IsNone(cnt) && (jump_op == POP_JUMP_IF_FALSE || jump_op == POP_JUMP_IF_TRUE)) {
8531+
unsigned char nextarg = bb->b_instr[i+1].i_oparg;
8532+
inst->i_opcode = NOP;
8533+
bb->b_instr[i+1].i_opcode = NOP;
8534+
bb->b_instr[i+2].i_opcode = nextarg ^ (jump_op == POP_JUMP_IF_FALSE) ?
8535+
POP_JUMP_IF_NOT_NONE : POP_JUMP_IF_NONE;
8536+
}
8537+
Py_DECREF(cnt);
8538+
break;
85228539
}
85238540
break;
85248541
}
@@ -8611,6 +8628,14 @@ optimize_basic_block(struct compiler *c, basicblock *bb, PyObject *consts)
86118628
break;
86128629
}
86138630
break;
8631+
case POP_JUMP_IF_NOT_NONE:
8632+
case POP_JUMP_IF_NONE:
8633+
switch (target->i_opcode) {
8634+
case JUMP_ABSOLUTE:
8635+
case JUMP_FORWARD:
8636+
i -= jump_thread(inst, target, inst->i_opcode);
8637+
}
8638+
break;
86148639
case POP_JUMP_IF_FALSE:
86158640
switch (target->i_opcode) {
86168641
case JUMP_ABSOLUTE:
@@ -8766,6 +8791,8 @@ normalize_basic_block(basicblock *bb) {
87668791
case JUMP_FORWARD:
87678792
bb->b_nofallthrough = 1;
87688793
/* fall through */
8794+
case POP_JUMP_IF_NOT_NONE:
8795+
case POP_JUMP_IF_NONE:
87698796
case POP_JUMP_IF_FALSE:
87708797
case POP_JUMP_IF_TRUE:
87718798
case JUMP_IF_FALSE_OR_POP:

Python/opcode_targets.h

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)
0