diff options
| author | Guido van Rossum <guido@python.org> | 2023-06-28 18:28:07 (GMT) |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-06-28 18:28:07 (GMT) |
| commit | 11731434df2d7d29b4260e5ad65b993cea775c36 (patch) | |
| tree | ef3afdb759174a31e607534a0daa3d8a4606bd28 /Python | |
| parent | c283a0cff5603540f06d9017e484b3602cc62e7c (diff) | |
| download | cpython-11731434df2d7d29b4260e5ad65b993cea775c36.zip cpython-11731434df2d7d29b4260e5ad65b993cea775c36.tar.gz cpython-11731434df2d7d29b4260e5ad65b993cea775c36.tar.bz2 | |
gh-104584: Emit macro expansions to opcode_metadata.h (#106163)
This produces longer traces (superblocks?).
Also improved debug output (uop names are now printed instead of numeric opcodes). This would be simpler if the numeric opcode values were generated by generate_cases.py, but that's another project.
Refactored some code in generate_cases.py so the essential algorithm for cache effects is only run once. (Deciding which effects are used and what the total cache size is, regardless of what's used.)
Diffstat (limited to 'Python')
| -rw-r--r-- | Python/ceval.c | 6 | ||||
| -rw-r--r-- | Python/opcode_metadata.h | 32 | ||||
| -rw-r--r-- | Python/optimizer.c | 8 |
3 files changed, 40 insertions, 6 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index e19860d..65b6f24 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2817,10 +2817,10 @@ _PyUopExecute(_PyExecutorObject *executor, _PyInterpreterFrame *frame, PyObject oparg = (int)operand; #ifdef LLTRACE if (lltrace >= 3) { - const char *opname = opcode < 256 ? _PyOpcode_OpName[opcode] : ""; + const char *opname = opcode < 256 ? _PyOpcode_OpName[opcode] : _PyOpcode_uop_name[opcode]; int stack_level = (int)(stack_pointer - _PyFrame_Stackbase(frame)); - fprintf(stderr, " uop %s %d, operand %" PRIu64 ", stack_level %d\n", - opname, opcode, operand, stack_level); + fprintf(stderr, " uop %s, operand %" PRIu64 ", stack_level %d\n", + opname, operand, stack_level); } #endif pc++; diff --git a/Python/opcode_metadata.h b/Python/opcode_metadata.h index 4e31a5e..cfdc092 100644 --- a/Python/opcode_metadata.h +++ b/Python/opcode_metadata.h @@ -913,6 +913,9 @@ struct opcode_macro_expansion { #ifndef NEED_OPCODE_METADATA extern const struct opcode_metadata _PyOpcode_opcode_metadata[512]; extern const struct opcode_macro_expansion _PyOpcode_macro_expansion[256]; +#ifdef Py_DEBUG +extern const char * const _PyOpcode_uop_name[512]; +#endif #else const struct opcode_metadata _PyOpcode_opcode_metadata[512] = { [NOP] = { true, INSTR_FMT_IX, 0 }, @@ -1131,10 +1134,18 @@ const struct opcode_macro_expansion _PyOpcode_macro_expansion[256] = { [STORE_FAST] = { .nuops = 1, .uops = { { STORE_FAST, 0, 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 } } }, [END_SEND] = { .nuops = 1, .uops = { { END_SEND, 0, 0 } } }, [UNARY_NEGATIVE] = { .nuops = 1, .uops = { { UNARY_NEGATIVE, 0, 0 } } }, [UNARY_NOT] = { .nuops = 1, .uops = { { UNARY_NOT, 0, 0 } } }, [UNARY_INVERT] = { .nuops = 1, .uops = { { UNARY_INVERT, 0, 0 } } }, + [BINARY_OP_MULTIPLY_INT] = { .nuops = 2, .uops = { { _GUARD_BOTH_INT, 0, 0 }, { _BINARY_OP_MULTIPLY_INT, 0, 0 } } }, + [BINARY_OP_ADD_INT] = { .nuops = 2, .uops = { { _GUARD_BOTH_INT, 0, 0 }, { _BINARY_OP_ADD_INT, 0, 0 } } }, + [BINARY_OP_SUBTRACT_INT] = { .nuops = 2, .uops = { { _GUARD_BOTH_INT, 0, 0 }, { _BINARY_OP_SUBTRACT_INT, 0, 0 } } }, + [BINARY_OP_MULTIPLY_FLOAT] = { .nuops = 2, .uops = { { _GUARD_BOTH_FLOAT, 0, 0 }, { _BINARY_OP_MULTIPLY_FLOAT, 0, 0 } } }, + [BINARY_OP_ADD_FLOAT] = { .nuops = 2, .uops = { { _GUARD_BOTH_FLOAT, 0, 0 }, { _BINARY_OP_ADD_FLOAT, 0, 0 } } }, + [BINARY_OP_SUBTRACT_FLOAT] = { .nuops = 2, .uops = { { _GUARD_BOTH_FLOAT, 0, 0 }, { _BINARY_OP_SUBTRACT_FLOAT, 0, 0 } } }, + [BINARY_OP_ADD_UNICODE] = { .nuops = 2, .uops = { { _GUARD_BOTH_UNICODE, 0, 0 }, { _BINARY_OP_ADD_UNICODE, 0, 0 } } }, [BINARY_SLICE] = { .nuops = 1, .uops = { { BINARY_SLICE, 0, 0 } } }, [STORE_SLICE] = { .nuops = 1, .uops = { { STORE_SLICE, 0, 0 } } }, [BINARY_SUBSCR_LIST_INT] = { .nuops = 1, .uops = { { BINARY_SUBSCR_LIST_INT, 0, 0 } } }, @@ -1162,6 +1173,9 @@ const struct opcode_macro_expansion _PyOpcode_macro_expansion[256] = { [DELETE_ATTR] = { .nuops = 1, .uops = { { DELETE_ATTR, 0, 0 } } }, [STORE_GLOBAL] = { .nuops = 1, .uops = { { STORE_GLOBAL, 0, 0 } } }, [DELETE_GLOBAL] = { .nuops = 1, .uops = { { DELETE_GLOBAL, 0, 0 } } }, + [LOAD_LOCALS] = { .nuops = 1, .uops = { { _LOAD_LOCALS, 0, 0 } } }, + [LOAD_NAME] = { .nuops = 2, .uops = { { _LOAD_LOCALS, 0, 0 }, { _LOAD_FROM_DICT_OR_GLOBALS, 0, 0 } } }, + [LOAD_FROM_DICT_OR_GLOBALS] = { .nuops = 1, .uops = { { _LOAD_FROM_DICT_OR_GLOBALS, 0, 0 } } }, [DELETE_DEREF] = { .nuops = 1, .uops = { { DELETE_DEREF, 0, 0 } } }, [LOAD_FROM_DICT_OR_DEREF] = { .nuops = 1, .uops = { { LOAD_FROM_DICT_OR_DEREF, 0, 0 } } }, [LOAD_DEREF] = { .nuops = 1, .uops = { { LOAD_DEREF, 0, 0 } } }, @@ -1207,4 +1221,22 @@ const struct opcode_macro_expansion _PyOpcode_macro_expansion[256] = { [COPY] = { .nuops = 1, .uops = { { COPY, 0, 0 } } }, [SWAP] = { .nuops = 1, .uops = { { SWAP, 0, 0 } } }, }; +#ifdef Py_DEBUG +const char * const _PyOpcode_uop_name[512] = { + [300] = "EXIT_TRACE", + [301] = "SET_IP", + [302] = "_GUARD_BOTH_INT", + [303] = "_BINARY_OP_MULTIPLY_INT", + [304] = "_BINARY_OP_ADD_INT", + [305] = "_BINARY_OP_SUBTRACT_INT", + [306] = "_GUARD_BOTH_FLOAT", + [307] = "_BINARY_OP_MULTIPLY_FLOAT", + [308] = "_BINARY_OP_ADD_FLOAT", + [309] = "_BINARY_OP_SUBTRACT_FLOAT", + [310] = "_GUARD_BOTH_UNICODE", + [311] = "_BINARY_OP_ADD_UNICODE", + [312] = "_LOAD_LOCALS", + [313] = "_LOAD_FROM_DICT_OR_GLOBALS", +}; +#endif #endif diff --git a/Python/optimizer.c b/Python/optimizer.c index 0a6cc5c..9d77ab4 100644 --- a/Python/optimizer.c +++ b/Python/optimizer.c @@ -325,8 +325,8 @@ translate_bytecode_to_trace( } #define ADD_TO_TRACE(OPCODE, OPERAND) \ if (lltrace >= 2) { \ - const char *opname = (OPCODE) < 256 ? _PyOpcode_OpName[(OPCODE)] : ""; \ - fprintf(stderr, " ADD_TO_TRACE(%s %d, %" PRIu64 ")\n", opname, (OPCODE), (uint64_t)(OPERAND)); \ + const char *opname = (OPCODE) < 256 ? _PyOpcode_OpName[(OPCODE)] : _PyOpcode_uop_name[(OPCODE)]; \ + fprintf(stderr, " ADD_TO_TRACE(%s, %" PRIu64 ")\n", opname, (uint64_t)(OPERAND)); \ } \ trace[trace_length].opcode = (OPCODE); \ trace[trace_length].operand = (OPERAND); \ @@ -474,6 +474,8 @@ PyUnstable_Optimizer_NewUOpOptimizer(void) } opt->optimize = uop_optimize; opt->resume_threshold = UINT16_MAX; - opt->backedge_threshold = 0; + // Need at least 3 iterations to settle specializations. + // A few lower bits of the counter are reserved for other flags. + opt->backedge_threshold = 3 << OPTIMIZER_BITS_IN_COUNTER; return (PyObject *)opt; } |
