[Python-checkins] bpo-44900: Add five superinstructions. (GH-27741)
markshannon
webhook-mailer at python.org
Mon Aug 16 07:23:17 EDT 2021
https://github.com/python/cpython/commit/4f51fa9e2d3ea9316e674fb9a9f3e3112e83661c
commit: 4f51fa9e2d3ea9316e674fb9a9f3e3112e83661c
branch: main
author: Mark Shannon <mark at hotpy.org>
committer: markshannon <mark at hotpy.org>
date: 2021-08-16T12:23:13+01:00
summary:
bpo-44900: Add five superinstructions. (GH-27741)
* LOAD_FAST LOAD_FAST
* STORE_FAST LOAD_FAST
* LOAD_FAST LOAD_CONST
* LOAD_CONST LOAD_FAST
* STORE_FAST STORE_FAST
files:
A Misc/NEWS.d/next/Core and Builtins/2021-08-12-14-00-57.bpo-44900.w2gpwy.rst
M Include/opcode.h
M Lib/opcode.py
M Python/ceval.c
M Python/opcode_targets.h
M Python/specialize.c
diff --git a/Include/opcode.h b/Include/opcode.h
index 50b783289590d..3334242e7e4d4 100644
--- a/Include/opcode.h
+++ b/Include/opcode.h
@@ -153,6 +153,11 @@ extern "C" {
#define STORE_ATTR_SPLIT_KEYS 45
#define STORE_ATTR_SLOT 46
#define STORE_ATTR_WITH_HINT 47
+#define LOAD_FAST__LOAD_FAST 48
+#define STORE_FAST__LOAD_FAST 58
+#define LOAD_FAST__LOAD_CONST 80
+#define LOAD_CONST__LOAD_FAST 81
+#define STORE_FAST__STORE_FAST 87
#ifdef NEED_OPCODE_JUMP_TABLES
static uint32_t _PyOpcode_RelativeJump[8] = {
0U,
diff --git a/Lib/opcode.py b/Lib/opcode.py
index 061506d0b88bd..53cdc4aa0d549 100644
--- a/Lib/opcode.py
+++ b/Lib/opcode.py
@@ -237,8 +237,13 @@ def jabs_op(name, op):
"STORE_ATTR_SPLIT_KEYS",
"STORE_ATTR_SLOT",
"STORE_ATTR_WITH_HINT",
+ # Super instructions
+ "LOAD_FAST__LOAD_FAST",
+ "STORE_FAST__LOAD_FAST",
+ "LOAD_FAST__LOAD_CONST",
+ "LOAD_CONST__LOAD_FAST",
+ "STORE_FAST__STORE_FAST",
]
-
_specialization_stats = [
"specialization_success",
"specialization_failure",
diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-08-12-14-00-57.bpo-44900.w2gpwy.rst b/Misc/NEWS.d/next/Core and Builtins/2021-08-12-14-00-57.bpo-44900.w2gpwy.rst
new file mode 100644
index 0000000000000..8d94d6aed80ea
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2021-08-12-14-00-57.bpo-44900.w2gpwy.rst
@@ -0,0 +1,7 @@
+Add five superinstructions for PEP 659 quickening:
+
+* LOAD_FAST LOAD_FAST
+* STORE_FAST LOAD_FAST
+* LOAD_FAST LOAD_CONST
+* LOAD_CONST LOAD_FAST
+* STORE_FAST STORE_FAST
diff --git a/Python/ceval.c b/Python/ceval.c
index 111689ff62980..48787493fdd2c 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -1266,16 +1266,21 @@ eval_frame_handle_pending(PyThreadState *tstate)
#define PRE_DISPATCH_GOTO() do { LLTRACE_INSTR(); RECORD_DXPROFILE(); } while (0)
#endif
+#define NOTRACE_DISPATCH() \
+ { \
+ frame->f_lasti = INSTR_OFFSET(); \
+ NEXTOPARG(); \
+ PRE_DISPATCH_GOTO(); \
+ DISPATCH_GOTO(); \
+ }
+
/* Do interpreter dispatch accounting for tracing and instrumentation */
#define DISPATCH() \
{ \
if (cframe.use_tracing OR_DTRACE_LINE) { \
goto tracing_dispatch; \
} \
- frame->f_lasti = INSTR_OFFSET(); \
- NEXTOPARG(); \
- PRE_DISPATCH_GOTO(); \
- DISPATCH_GOTO(); \
+ NOTRACE_DISPATCH(); \
}
#define CHECK_EVAL_BREAKER() \
@@ -1682,11 +1687,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
TARGET(LOAD_FAST): {
PyObject *value = GETLOCAL(oparg);
if (value == NULL) {
- format_exc_check_arg(tstate, PyExc_UnboundLocalError,
- UNBOUNDLOCAL_ERROR_MSG,
- PyTuple_GetItem(co->co_localsplusnames,
- oparg));
- goto error;
+ goto unbound_local_error;
}
Py_INCREF(value);
PUSH(value);
@@ -1708,6 +1709,73 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
DISPATCH();
}
+ TARGET(LOAD_FAST__LOAD_FAST): {
+ PyObject *value = GETLOCAL(oparg);
+ if (value == NULL) {
+ goto unbound_local_error;
+ }
+ NEXTOPARG();
+ Py_INCREF(value);
+ PUSH(value);
+ value = GETLOCAL(oparg);
+ if (value == NULL) {
+ goto unbound_local_error;
+ }
+ Py_INCREF(value);
+ PUSH(value);
+ NOTRACE_DISPATCH();
+ }
+
+ TARGET(LOAD_FAST__LOAD_CONST): {
+ PyObject *value = GETLOCAL(oparg);
+ if (value == NULL) {
+ goto unbound_local_error;
+ }
+ NEXTOPARG();
+ Py_INCREF(value);
+ PUSH(value);
+ value = GETITEM(consts, oparg);
+ Py_INCREF(value);
+ PUSH(value);
+ NOTRACE_DISPATCH();
+ }
+
+ TARGET(STORE_FAST__LOAD_FAST): {
+ PyObject *value = POP();
+ SETLOCAL(oparg, value);
+ NEXTOPARG();
+ value = GETLOCAL(oparg);
+ if (value == NULL) {
+ goto unbound_local_error;
+ }
+ Py_INCREF(value);
+ PUSH(value);
+ NOTRACE_DISPATCH();
+ }
+
+ TARGET(STORE_FAST__STORE_FAST): {
+ PyObject *value = POP();
+ SETLOCAL(oparg, value);
+ NEXTOPARG();
+ value = POP();
+ SETLOCAL(oparg, value);
+ NOTRACE_DISPATCH();
+ }
+
+ TARGET(LOAD_CONST__LOAD_FAST): {
+ PyObject *value = GETITEM(consts, oparg);
+ NEXTOPARG();
+ Py_INCREF(value);
+ PUSH(value);
+ value = GETLOCAL(oparg);
+ if (value == NULL) {
+ goto unbound_local_error;
+ }
+ Py_INCREF(value);
+ PUSH(value);
+ NOTRACE_DISPATCH();
+ }
+
TARGET(POP_TOP): {
PyObject *value = POP();
Py_DECREF(value);
@@ -4592,6 +4660,15 @@ MISS_WITH_OPARG_COUNTER(BINARY_SUBSCR)
goto error;
}
+unbound_local_error:
+ {
+ format_exc_check_arg(tstate, PyExc_UnboundLocalError,
+ UNBOUNDLOCAL_ERROR_MSG,
+ PyTuple_GetItem(co->co_localsplusnames, oparg)
+ );
+ goto error;
+ }
+
error:
/* Double-check exception status. */
#ifdef NDEBUG
diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h
index 24ee44f2d08c0..c8036a63f2201 100644
--- a/Python/opcode_targets.h
+++ b/Python/opcode_targets.h
@@ -47,7 +47,7 @@ static void *opcode_targets[256] = {
&&TARGET_STORE_ATTR_SPLIT_KEYS,
&&TARGET_STORE_ATTR_SLOT,
&&TARGET_STORE_ATTR_WITH_HINT,
- &&_unknown_opcode,
+ &&TARGET_LOAD_FAST__LOAD_FAST,
&&TARGET_WITH_EXCEPT_START,
&&TARGET_GET_AITER,
&&TARGET_GET_ANEXT,
@@ -57,7 +57,7 @@ static void *opcode_targets[256] = {
&&TARGET_INPLACE_ADD,
&&TARGET_INPLACE_SUBTRACT,
&&TARGET_INPLACE_MULTIPLY,
- &&_unknown_opcode,
+ &&TARGET_STORE_FAST__LOAD_FAST,
&&TARGET_INPLACE_MODULO,
&&TARGET_STORE_SUBSCR,
&&TARGET_DELETE_SUBSCR,
@@ -79,14 +79,14 @@ static void *opcode_targets[256] = {
&&TARGET_INPLACE_AND,
&&TARGET_INPLACE_XOR,
&&TARGET_INPLACE_OR,
- &&_unknown_opcode,
- &&_unknown_opcode,
+ &&TARGET_LOAD_FAST__LOAD_CONST,
+ &&TARGET_LOAD_CONST__LOAD_FAST,
&&TARGET_LIST_TO_TUPLE,
&&TARGET_RETURN_VALUE,
&&TARGET_IMPORT_STAR,
&&TARGET_SETUP_ANNOTATIONS,
&&TARGET_YIELD_VALUE,
- &&_unknown_opcode,
+ &&TARGET_STORE_FAST__STORE_FAST,
&&_unknown_opcode,
&&TARGET_POP_EXCEPT,
&&TARGET_STORE_NAME,
diff --git a/Python/specialize.c b/Python/specialize.c
index e653ae41c5778..ecab69bcae78e 100644
--- a/Python/specialize.c
+++ b/Python/specialize.c
@@ -303,6 +303,7 @@ optimize(SpecializedCacheOrInstruction *quickened, int len)
_Py_CODEUNIT *instructions = first_instruction(quickened);
int cache_offset = 0;
int previous_opcode = -1;
+ int previous_oparg = 0;
for(int i = 0; i < len; i++) {
int opcode = _Py_OPCODE(instructions[i]);
int oparg = _Py_OPARG(instructions[i]);
@@ -338,14 +339,32 @@ optimize(SpecializedCacheOrInstruction *quickened, int len)
case JUMP_ABSOLUTE:
instructions[i] = _Py_MAKECODEUNIT(JUMP_ABSOLUTE_QUICK, oparg);
break;
- /* Insert superinstructions here
- E.g.
case LOAD_FAST:
- if (previous_opcode == LOAD_FAST)
- instructions[i-1] = _Py_MAKECODEUNIT(LOAD_FAST__LOAD_FAST, oparg);
- */
+ switch(previous_opcode) {
+ case LOAD_FAST:
+ instructions[i-1] = _Py_MAKECODEUNIT(LOAD_FAST__LOAD_FAST, previous_oparg);
+ break;
+ case STORE_FAST:
+ instructions[i-1] = _Py_MAKECODEUNIT(STORE_FAST__LOAD_FAST, previous_oparg);
+ break;
+ case LOAD_CONST:
+ instructions[i-1] = _Py_MAKECODEUNIT(LOAD_CONST__LOAD_FAST, previous_oparg);
+ break;
+ }
+ break;
+ case STORE_FAST:
+ if (previous_opcode == STORE_FAST) {
+ instructions[i-1] = _Py_MAKECODEUNIT(STORE_FAST__STORE_FAST, previous_oparg);
+ }
+ break;
+ case LOAD_CONST:
+ if (previous_opcode == LOAD_FAST) {
+ instructions[i-1] = _Py_MAKECODEUNIT(LOAD_FAST__LOAD_CONST, previous_oparg);
+ }
+ break;
}
previous_opcode = opcode;
+ previous_oparg = oparg;
}
}
assert(cache_offset+1 == get_cache_count(quickened));
More information about the Python-checkins
mailing list