summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2023-07-11 18:08:10 (GMT)
committerGitHub <noreply@github.com>2023-07-11 18:08:10 (GMT)
commitcabd6e8a107127ff02f0b514148f648fb2472a58 (patch)
tree503576bebc0f89d59bc198bb7d54f6284737b5b9 /Python
parent292ac4bfe92768140c2d383fd329cfa1949869b2 (diff)
downloadcpython-cabd6e8a107127ff02f0b514148f648fb2472a58.zip
cpython-cabd6e8a107127ff02f0b514148f648fb2472a58.tar.gz
cpython-cabd6e8a107127ff02f0b514148f648fb2472a58.tar.bz2
gh-106529: Support JUMP_BACKWARD in Tier 2 (uops) (#106543)
During superblock generation, a JUMP_BACKWARD instruction is translated to either a JUMP_TO_TOP micro-op (when the target of the jump is exactly the beginning of the superblock, closing the loop), or a SAVE_IP + EXIT_TRACE pair, when the jump goes elsewhere. The new JUMP_TO_TOP instruction includes a CHECK_EVAL_BREAKER() call, so a closed loop can still be interrupted.
Diffstat (limited to 'Python')
-rw-r--r--Python/ceval.c7
-rw-r--r--Python/opcode_metadata.h54
-rw-r--r--Python/optimizer.c15
3 files changed, 48 insertions, 28 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 866acd2..57e478c 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -2783,6 +2783,13 @@ _PyUopExecute(_PyExecutorObject *executor, _PyInterpreterFrame *frame, PyObject
break;
}
+ case JUMP_TO_TOP:
+ {
+ pc = 0;
+ CHECK_EVAL_BREAKER();
+ break;
+ }
+
case SAVE_IP:
{
frame->prev_instr = ip_offset + oparg;
diff --git a/Python/opcode_metadata.h b/Python/opcode_metadata.h
index 34ac85d..4a41cd8 100644
--- a/Python/opcode_metadata.h
+++ b/Python/opcode_metadata.h
@@ -23,19 +23,20 @@
#define SAVE_IP 301
#define _POP_JUMP_IF_FALSE 302
#define _POP_JUMP_IF_TRUE 303
-#define _GUARD_BOTH_INT 304
-#define _BINARY_OP_MULTIPLY_INT 305
-#define _BINARY_OP_ADD_INT 306
-#define _BINARY_OP_SUBTRACT_INT 307
-#define _GUARD_BOTH_FLOAT 308
-#define _BINARY_OP_MULTIPLY_FLOAT 309
-#define _BINARY_OP_ADD_FLOAT 310
-#define _BINARY_OP_SUBTRACT_FLOAT 311
-#define _GUARD_BOTH_UNICODE 312
-#define _BINARY_OP_ADD_UNICODE 313
-#define _LOAD_LOCALS 314
-#define _LOAD_FROM_DICT_OR_GLOBALS 315
-#define IS_NONE 316
+#define JUMP_TO_TOP 304
+#define _GUARD_BOTH_INT 305
+#define _BINARY_OP_MULTIPLY_INT 306
+#define _BINARY_OP_ADD_INT 307
+#define _BINARY_OP_SUBTRACT_INT 308
+#define _GUARD_BOTH_FLOAT 309
+#define _BINARY_OP_MULTIPLY_FLOAT 310
+#define _BINARY_OP_ADD_FLOAT 311
+#define _BINARY_OP_SUBTRACT_FLOAT 312
+#define _GUARD_BOTH_UNICODE 313
+#define _BINARY_OP_ADD_UNICODE 314
+#define _LOAD_LOCALS 315
+#define _LOAD_FROM_DICT_OR_GLOBALS 316
+#define IS_NONE 317
#ifndef NEED_OPCODE_METADATA
extern int _PyOpcode_num_popped(int opcode, int oparg, bool jump);
@@ -1298,18 +1299,19 @@ const char * const _PyOpcode_uop_name[512] = {
[301] = "SAVE_IP",
[302] = "_POP_JUMP_IF_FALSE",
[303] = "_POP_JUMP_IF_TRUE",
- [304] = "_GUARD_BOTH_INT",
- [305] = "_BINARY_OP_MULTIPLY_INT",
- [306] = "_BINARY_OP_ADD_INT",
- [307] = "_BINARY_OP_SUBTRACT_INT",
- [308] = "_GUARD_BOTH_FLOAT",
- [309] = "_BINARY_OP_MULTIPLY_FLOAT",
- [310] = "_BINARY_OP_ADD_FLOAT",
- [311] = "_BINARY_OP_SUBTRACT_FLOAT",
- [312] = "_GUARD_BOTH_UNICODE",
- [313] = "_BINARY_OP_ADD_UNICODE",
- [314] = "_LOAD_LOCALS",
- [315] = "_LOAD_FROM_DICT_OR_GLOBALS",
- [316] = "IS_NONE",
+ [304] = "JUMP_TO_TOP",
+ [305] = "_GUARD_BOTH_INT",
+ [306] = "_BINARY_OP_MULTIPLY_INT",
+ [307] = "_BINARY_OP_ADD_INT",
+ [308] = "_BINARY_OP_SUBTRACT_INT",
+ [309] = "_GUARD_BOTH_FLOAT",
+ [310] = "_BINARY_OP_MULTIPLY_FLOAT",
+ [311] = "_BINARY_OP_ADD_FLOAT",
+ [312] = "_BINARY_OP_SUBTRACT_FLOAT",
+ [313] = "_GUARD_BOTH_UNICODE",
+ [314] = "_BINARY_OP_ADD_UNICODE",
+ [315] = "_LOAD_LOCALS",
+ [316] = "_LOAD_FROM_DICT_OR_GLOBALS",
+ [317] = "IS_NONE",
};
#endif // NEED_OPCODE_METADATA
diff --git a/Python/optimizer.c b/Python/optimizer.c
index 0807319..8d4162b 100644
--- a/Python/optimizer.c
+++ b/Python/optimizer.c
@@ -372,9 +372,7 @@ translate_bytecode_to_trace(
_PyUOpInstruction *trace,
int buffer_size)
{
-#ifdef Py_DEBUG
_Py_CODEUNIT *initial_instr = instr;
-#endif
int trace_length = 0;
int max_length = buffer_size;
@@ -456,6 +454,19 @@ translate_bytecode_to_trace(
break;
}
+ case JUMP_BACKWARD:
+ {
+ if (instr + 2 - oparg == initial_instr
+ && trace_length + 3 <= max_length)
+ {
+ ADD_TO_TRACE(JUMP_TO_TOP, 0);
+ }
+ else {
+ DPRINTF(2, "JUMP_BACKWARD not to top ends trace\n");
+ }
+ goto done;
+ }
+
default:
{
const struct opcode_macro_expansion *expansion = &_PyOpcode_macro_expansion[opcode];