summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2023-07-07 17:42:10 (GMT)
committerGitHub <noreply@github.com>2023-07-07 17:42:10 (GMT)
commit11038c56ad80dde2cdf65190e78a59d579c94b3a (patch)
tree2472d506be753af094dace3a78841a39f0412910 /Python
parent363f4f99c524a6d763d1548986a79c42cc7ca292 (diff)
downloadcpython-11038c56ad80dde2cdf65190e78a59d579c94b3a.zip
cpython-11038c56ad80dde2cdf65190e78a59d579c94b3a.tar.gz
cpython-11038c56ad80dde2cdf65190e78a59d579c94b3a.tar.bz2
gh-104584: Move super-instruction special-casing to generator (#106500)
Instead of special-casing specific instructions, we add a few more special values to the 'size' field of expansions, so in the future we can automatically handle additional super-instructions in the generator.
Diffstat (limited to 'Python')
-rw-r--r--Python/opcode_metadata.h9
-rw-r--r--Python/optimizer.c53
2 files changed, 25 insertions, 37 deletions
diff --git a/Python/opcode_metadata.h b/Python/opcode_metadata.h
index ac86a4a..d29f721 100644
--- a/Python/opcode_metadata.h
+++ b/Python/opcode_metadata.h
@@ -934,6 +934,12 @@ struct opcode_macro_expansion {
struct { int16_t uop; int8_t size; int8_t offset; } uops[8];
};
+#define OPARG_FULL 0
+#define OPARG_CACHE_1 1
+#define OPARG_CACHE_2 2
+#define OPARG_CACHE_4 4
+#define OPARG_TOP 5
+#define OPARG_BOTTOM 6
#define OPCODE_METADATA_FMT(OP) (_PyOpcode_opcode_metadata[(OP)].instr_format)
#define SAME_OPCODE_METADATA(OP1, OP2) \
@@ -1165,8 +1171,11 @@ const struct opcode_macro_expansion _PyOpcode_macro_expansion[256] = {
[LOAD_FAST_CHECK] = { .nuops = 1, .uops = { { LOAD_FAST_CHECK, 0, 0 } } },
[LOAD_FAST] = { .nuops = 1, .uops = { { LOAD_FAST, 0, 0 } } },
[LOAD_FAST_AND_CLEAR] = { .nuops = 1, .uops = { { LOAD_FAST_AND_CLEAR, 0, 0 } } },
+ [LOAD_FAST_LOAD_FAST] = { .nuops = 2, .uops = { { LOAD_FAST, 5, 0 }, { LOAD_FAST, 6, 0 } } },
[LOAD_CONST] = { .nuops = 1, .uops = { { LOAD_CONST, 0, 0 } } },
[STORE_FAST] = { .nuops = 1, .uops = { { STORE_FAST, 0, 0 } } },
+ [STORE_FAST_LOAD_FAST] = { .nuops = 2, .uops = { { STORE_FAST, 5, 0 }, { LOAD_FAST, 6, 0 } } },
+ [STORE_FAST_STORE_FAST] = { .nuops = 2, .uops = { { STORE_FAST, 5, 0 }, { STORE_FAST, 6, 0 } } },
[POP_TOP] = { .nuops = 1, .uops = { { POP_TOP, 0, 0 } } },
[PUSH_NULL] = { .nuops = 1, .uops = { { PUSH_NULL, 0, 0 } } },
[END_FOR] = { .nuops = 2, .uops = { { POP_TOP, 0, 0 }, { POP_TOP, 0, 0 } } },
diff --git a/Python/optimizer.c b/Python/optimizer.c
index db117bb..2870f2f 100644
--- a/Python/optimizer.c
+++ b/Python/optimizer.c
@@ -411,44 +411,15 @@ translate_bytecode_to_trace(
for (;;) {
ADD_TO_TRACE(SAVE_IP, (int)(instr - (_Py_CODEUNIT *)code->co_code_adaptive));
int opcode = instr->op.code;
- uint64_t operand = instr->op.arg;
+ int oparg = instr->op.arg;
int extras = 0;
while (opcode == EXTENDED_ARG) {
instr++;
extras += 1;
opcode = instr->op.code;
- operand = (operand << 8) | instr->op.arg;
+ oparg = (oparg << 8) | instr->op.arg;
}
switch (opcode) {
- case LOAD_FAST_LOAD_FAST:
- case STORE_FAST_LOAD_FAST:
- case STORE_FAST_STORE_FAST:
- {
- // Reserve space for two uops (+ SAVE_IP + EXIT_TRACE)
- if (trace_length + 4 > max_length) {
- DPRINTF(1, "Ran out of space for LOAD_FAST_LOAD_FAST\n");
- goto done;
- }
- uint64_t oparg1 = operand >> 4;
- uint64_t oparg2 = operand & 15;
- switch (opcode) {
- case LOAD_FAST_LOAD_FAST:
- ADD_TO_TRACE(LOAD_FAST, oparg1);
- ADD_TO_TRACE(LOAD_FAST, oparg2);
- break;
- case STORE_FAST_LOAD_FAST:
- ADD_TO_TRACE(STORE_FAST, oparg1);
- ADD_TO_TRACE(LOAD_FAST, oparg2);
- break;
- case STORE_FAST_STORE_FAST:
- ADD_TO_TRACE(STORE_FAST, oparg1);
- ADD_TO_TRACE(STORE_FAST, oparg2);
- break;
- default:
- Py_FatalError("Missing case");
- }
- break;
- }
default:
{
const struct opcode_macro_expansion *expansion = &_PyOpcode_macro_expansion[opcode];
@@ -462,9 +433,11 @@ translate_bytecode_to_trace(
goto done;
}
for (int i = 0; i < nuops; i++) {
+ uint64_t operand;
int offset = expansion->uops[i].offset;
switch (expansion->uops[i].size) {
- case 0:
+ case OPARG_FULL:
+ operand = oparg;
if (extras && OPCODE_HAS_JUMP(opcode)) {
if (opcode == JUMP_BACKWARD_NO_INTERRUPT) {
operand -= extras;
@@ -475,19 +448,25 @@ translate_bytecode_to_trace(
}
}
break;
- case 1:
+ case OPARG_CACHE_1:
operand = read_u16(&instr[offset].cache);
break;
- case 2:
+ case OPARG_CACHE_2:
operand = read_u32(&instr[offset].cache);
break;
- case 4:
+ case OPARG_CACHE_4:
operand = read_u64(&instr[offset].cache);
break;
+ case OPARG_TOP: // First half of super-instr
+ operand = oparg >> 4;
+ break;
+ case OPARG_BOTTOM: // Second half of super-instr
+ operand = oparg & 0xF;
+ break;
default:
fprintf(stderr,
- "opcode=%d, operand=%" PRIu64 "; nuops=%d, i=%d; size=%d, offset=%d\n",
- opcode, operand, nuops, i,
+ "opcode=%d, oparg=%d; nuops=%d, i=%d; size=%d, offset=%d\n",
+ opcode, oparg, nuops, i,
expansion->uops[i].size,
expansion->uops[i].offset);
Py_FatalError("garbled expansion");