diff options
author | Guido van Rossum <guido@python.org> | 2023-07-07 17:42:10 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-07 17:42:10 (GMT) |
commit | 11038c56ad80dde2cdf65190e78a59d579c94b3a (patch) | |
tree | 2472d506be753af094dace3a78841a39f0412910 /Python | |
parent | 363f4f99c524a6d763d1548986a79c42cc7ca292 (diff) | |
download | cpython-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.h | 9 | ||||
-rw-r--r-- | Python/optimizer.c | 53 |
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"); |