From cdc6e1170b9ce4dcff7169ba54302c68df54b5bf Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Thu, 19 Sep 2024 16:05:04 +0100 Subject: [PATCH 1/4] Add LOAD_FAST_DEFERRED as marker for potentially deferred references --- Include/internal/pycore_magic_number.h | 4 +- Include/internal/pycore_opcode_metadata.h | 9 +- Include/internal/pycore_uop_ids.h | 1 + Include/internal/pycore_uop_metadata.h | 4 + Include/opcode_ids.h | 67 +++--- Lib/_opcode_metadata.py | 67 +++--- Python/bytecodes.c | 5 + Python/codegen.c | 265 ++++++++++++---------- Python/executor_cases.c.h | 11 + Python/flowgraph.c | 1 + Python/generated_cases.c.h | 13 ++ Python/opcode_targets.h | 2 +- Python/optimizer_cases.c.h | 9 + 13 files changed, 271 insertions(+), 187 deletions(-) diff --git a/Include/internal/pycore_magic_number.h b/Include/internal/pycore_magic_number.h index 095eb0f8a89b79..587e3ad89ed677 100644 --- a/Include/internal/pycore_magic_number.h +++ b/Include/internal/pycore_magic_number.h @@ -259,6 +259,8 @@ Known values: Python 3.14a1 3605 (Move ENTER_EXECUTOR to opcode 255) Python 3.14a1 3606 (Specialize CALL_KW) + Python 3.14a1 3607 (LOAD_FAST_DEFERRED) + Python 3.15 will start with 3650 Please don't copy-paste the same pre-release tag for new entries above!!! @@ -270,7 +272,7 @@ PC/launcher.c must also be updated. */ -#define PYC_MAGIC_NUMBER 3606 +#define PYC_MAGIC_NUMBER 3607 /* This is equivalent to converting PYC_MAGIC_NUMBER to 2 bytes (little-endian) and then appending b'\r\n'. */ #define PYC_MAGIC_NUMBER_TOKEN \ diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index 51479afae3833d..0d5b2b5928cff6 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -319,6 +319,8 @@ int _PyOpcode_num_popped(int opcode, int oparg) { return 0; case LOAD_FAST_CHECK: return 0; + case LOAD_FAST_DEFERRED: + return 0; case LOAD_FAST_LOAD_FAST: return 0; case LOAD_FROM_DICT_OR_DEREF: @@ -776,6 +778,8 @@ int _PyOpcode_num_pushed(int opcode, int oparg) { return 1; case LOAD_FAST_CHECK: return 1; + case LOAD_FAST_DEFERRED: + return 1; case LOAD_FAST_LOAD_FAST: return 2; case LOAD_FROM_DICT_OR_DEREF: @@ -1148,6 +1152,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[264] = { [LOAD_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_PURE_FLAG }, [LOAD_FAST_AND_CLEAR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG }, [LOAD_FAST_CHECK] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, + [LOAD_FAST_DEFERRED] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG }, [LOAD_FAST_LOAD_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG }, [LOAD_FROM_DICT_OR_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [LOAD_FROM_DICT_OR_GLOBALS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, @@ -1352,6 +1357,7 @@ _PyOpcode_macro_expansion[256] = { [LOAD_FAST] = { .nuops = 1, .uops = { { _LOAD_FAST, 0, 0 } } }, [LOAD_FAST_AND_CLEAR] = { .nuops = 1, .uops = { { _LOAD_FAST_AND_CLEAR, 0, 0 } } }, [LOAD_FAST_CHECK] = { .nuops = 1, .uops = { { _LOAD_FAST_CHECK, 0, 0 } } }, + [LOAD_FAST_DEFERRED] = { .nuops = 1, .uops = { { _LOAD_FAST_DEFERRED, 0, 0 } } }, [LOAD_FAST_LOAD_FAST] = { .nuops = 2, .uops = { { _LOAD_FAST, 5, 0 }, { _LOAD_FAST, 6, 0 } } }, [LOAD_FROM_DICT_OR_DEREF] = { .nuops = 1, .uops = { { _LOAD_FROM_DICT_OR_DEREF, 0, 0 } } }, [LOAD_GLOBAL] = { .nuops = 1, .uops = { { _LOAD_GLOBAL, 0, 0 } } }, @@ -1568,6 +1574,7 @@ const char *_PyOpcode_OpName[264] = { [LOAD_FAST] = "LOAD_FAST", [LOAD_FAST_AND_CLEAR] = "LOAD_FAST_AND_CLEAR", [LOAD_FAST_CHECK] = "LOAD_FAST_CHECK", + [LOAD_FAST_DEFERRED] = "LOAD_FAST_DEFERRED", [LOAD_FAST_LOAD_FAST] = "LOAD_FAST_LOAD_FAST", [LOAD_FROM_DICT_OR_DEREF] = "LOAD_FROM_DICT_OR_DEREF", [LOAD_FROM_DICT_OR_GLOBALS] = "LOAD_FROM_DICT_OR_GLOBALS", @@ -1820,6 +1827,7 @@ const uint8_t _PyOpcode_Deopt[256] = { [LOAD_FAST] = LOAD_FAST, [LOAD_FAST_AND_CLEAR] = LOAD_FAST_AND_CLEAR, [LOAD_FAST_CHECK] = LOAD_FAST_CHECK, + [LOAD_FAST_DEFERRED] = LOAD_FAST_DEFERRED, [LOAD_FAST_LOAD_FAST] = LOAD_FAST_LOAD_FAST, [LOAD_FROM_DICT_OR_DEREF] = LOAD_FROM_DICT_OR_DEREF, [LOAD_FROM_DICT_OR_GLOBALS] = LOAD_FROM_DICT_OR_GLOBALS, @@ -1900,7 +1908,6 @@ const uint8_t _PyOpcode_Deopt[256] = { #endif // NEED_OPCODE_METADATA #define EXTRA_CASES \ - case 117: \ case 118: \ case 119: \ case 120: \ diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index b950f760d74ac7..a1bc9fb9cb62ea 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -209,6 +209,7 @@ extern "C" { #define _LOAD_FAST_7 435 #define _LOAD_FAST_AND_CLEAR LOAD_FAST_AND_CLEAR #define _LOAD_FAST_CHECK LOAD_FAST_CHECK +#define _LOAD_FAST_DEFERRED LOAD_FAST_DEFERRED #define _LOAD_FAST_LOAD_FAST LOAD_FAST_LOAD_FAST #define _LOAD_FROM_DICT_OR_DEREF LOAD_FROM_DICT_OR_DEREF #define _LOAD_FROM_DICT_OR_GLOBALS LOAD_FROM_DICT_OR_GLOBALS diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index 4d0ab22e6aa8f3..5b2973d1e9f605 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -33,6 +33,7 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = { [_LOAD_FAST_6] = HAS_LOCAL_FLAG | HAS_PURE_FLAG, [_LOAD_FAST_7] = HAS_LOCAL_FLAG | HAS_PURE_FLAG, [_LOAD_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_PURE_FLAG, + [_LOAD_FAST_DEFERRED] = HAS_ARG_FLAG | HAS_LOCAL_FLAG, [_LOAD_FAST_AND_CLEAR] = HAS_ARG_FLAG | HAS_LOCAL_FLAG, [_LOAD_FAST_LOAD_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG, [_LOAD_CONST] = HAS_ARG_FLAG | HAS_CONST_FLAG | HAS_PURE_FLAG, @@ -469,6 +470,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = { [_LOAD_FAST_7] = "_LOAD_FAST_7", [_LOAD_FAST_AND_CLEAR] = "_LOAD_FAST_AND_CLEAR", [_LOAD_FAST_CHECK] = "_LOAD_FAST_CHECK", + [_LOAD_FAST_DEFERRED] = "_LOAD_FAST_DEFERRED", [_LOAD_FAST_LOAD_FAST] = "_LOAD_FAST_LOAD_FAST", [_LOAD_FROM_DICT_OR_DEREF] = "_LOAD_FROM_DICT_OR_DEREF", [_LOAD_GLOBAL] = "_LOAD_GLOBAL", @@ -580,6 +582,8 @@ int _PyUop_num_popped(int opcode, int oparg) return 0; case _LOAD_FAST: return 0; + case _LOAD_FAST_DEFERRED: + return 0; case _LOAD_FAST_AND_CLEAR: return 0; case _LOAD_FAST_LOAD_FAST: diff --git a/Include/opcode_ids.h b/Include/opcode_ids.h index 5ded0b41b4830e..5622be3c9e7d16 100644 --- a/Include/opcode_ids.h +++ b/Include/opcode_ids.h @@ -94,39 +94,40 @@ extern "C" { #define LOAD_FAST 81 #define LOAD_FAST_AND_CLEAR 82 #define LOAD_FAST_CHECK 83 -#define LOAD_FAST_LOAD_FAST 84 -#define LOAD_FROM_DICT_OR_DEREF 85 -#define LOAD_FROM_DICT_OR_GLOBALS 86 -#define LOAD_GLOBAL 87 -#define LOAD_NAME 88 -#define LOAD_SPECIAL 89 -#define LOAD_SUPER_ATTR 90 -#define MAKE_CELL 91 -#define MAP_ADD 92 -#define MATCH_CLASS 93 -#define POP_JUMP_IF_FALSE 94 -#define POP_JUMP_IF_NONE 95 -#define POP_JUMP_IF_NOT_NONE 96 -#define POP_JUMP_IF_TRUE 97 -#define RAISE_VARARGS 98 -#define RERAISE 99 -#define RETURN_CONST 100 -#define SEND 101 -#define SET_ADD 102 -#define SET_FUNCTION_ATTRIBUTE 103 -#define SET_UPDATE 104 -#define STORE_ATTR 105 -#define STORE_DEREF 106 -#define STORE_FAST 107 -#define STORE_FAST_LOAD_FAST 108 -#define STORE_FAST_STORE_FAST 109 -#define STORE_GLOBAL 110 -#define STORE_NAME 111 -#define SWAP 112 -#define UNPACK_EX 113 -#define UNPACK_SEQUENCE 114 -#define YIELD_VALUE 115 -#define _DO_CALL_FUNCTION_EX 116 +#define LOAD_FAST_DEFERRED 84 +#define LOAD_FAST_LOAD_FAST 85 +#define LOAD_FROM_DICT_OR_DEREF 86 +#define LOAD_FROM_DICT_OR_GLOBALS 87 +#define LOAD_GLOBAL 88 +#define LOAD_NAME 89 +#define LOAD_SPECIAL 90 +#define LOAD_SUPER_ATTR 91 +#define MAKE_CELL 92 +#define MAP_ADD 93 +#define MATCH_CLASS 94 +#define POP_JUMP_IF_FALSE 95 +#define POP_JUMP_IF_NONE 96 +#define POP_JUMP_IF_NOT_NONE 97 +#define POP_JUMP_IF_TRUE 98 +#define RAISE_VARARGS 99 +#define RERAISE 100 +#define RETURN_CONST 101 +#define SEND 102 +#define SET_ADD 103 +#define SET_FUNCTION_ATTRIBUTE 104 +#define SET_UPDATE 105 +#define STORE_ATTR 106 +#define STORE_DEREF 107 +#define STORE_FAST 108 +#define STORE_FAST_LOAD_FAST 109 +#define STORE_FAST_STORE_FAST 110 +#define STORE_GLOBAL 111 +#define STORE_NAME 112 +#define SWAP 113 +#define UNPACK_EX 114 +#define UNPACK_SEQUENCE 115 +#define YIELD_VALUE 116 +#define _DO_CALL_FUNCTION_EX 117 #define RESUME 149 #define BINARY_OP_ADD_FLOAT 150 #define BINARY_OP_ADD_INT 151 diff --git a/Lib/_opcode_metadata.py b/Lib/_opcode_metadata.py index 6e4b33921863cb..0e24edecab7888 100644 --- a/Lib/_opcode_metadata.py +++ b/Lib/_opcode_metadata.py @@ -283,39 +283,40 @@ 'LOAD_FAST': 81, 'LOAD_FAST_AND_CLEAR': 82, 'LOAD_FAST_CHECK': 83, - 'LOAD_FAST_LOAD_FAST': 84, - 'LOAD_FROM_DICT_OR_DEREF': 85, - 'LOAD_FROM_DICT_OR_GLOBALS': 86, - 'LOAD_GLOBAL': 87, - 'LOAD_NAME': 88, - 'LOAD_SPECIAL': 89, - 'LOAD_SUPER_ATTR': 90, - 'MAKE_CELL': 91, - 'MAP_ADD': 92, - 'MATCH_CLASS': 93, - 'POP_JUMP_IF_FALSE': 94, - 'POP_JUMP_IF_NONE': 95, - 'POP_JUMP_IF_NOT_NONE': 96, - 'POP_JUMP_IF_TRUE': 97, - 'RAISE_VARARGS': 98, - 'RERAISE': 99, - 'RETURN_CONST': 100, - 'SEND': 101, - 'SET_ADD': 102, - 'SET_FUNCTION_ATTRIBUTE': 103, - 'SET_UPDATE': 104, - 'STORE_ATTR': 105, - 'STORE_DEREF': 106, - 'STORE_FAST': 107, - 'STORE_FAST_LOAD_FAST': 108, - 'STORE_FAST_STORE_FAST': 109, - 'STORE_GLOBAL': 110, - 'STORE_NAME': 111, - 'SWAP': 112, - 'UNPACK_EX': 113, - 'UNPACK_SEQUENCE': 114, - 'YIELD_VALUE': 115, - '_DO_CALL_FUNCTION_EX': 116, + 'LOAD_FAST_DEFERRED': 84, + 'LOAD_FAST_LOAD_FAST': 85, + 'LOAD_FROM_DICT_OR_DEREF': 86, + 'LOAD_FROM_DICT_OR_GLOBALS': 87, + 'LOAD_GLOBAL': 88, + 'LOAD_NAME': 89, + 'LOAD_SPECIAL': 90, + 'LOAD_SUPER_ATTR': 91, + 'MAKE_CELL': 92, + 'MAP_ADD': 93, + 'MATCH_CLASS': 94, + 'POP_JUMP_IF_FALSE': 95, + 'POP_JUMP_IF_NONE': 96, + 'POP_JUMP_IF_NOT_NONE': 97, + 'POP_JUMP_IF_TRUE': 98, + 'RAISE_VARARGS': 99, + 'RERAISE': 100, + 'RETURN_CONST': 101, + 'SEND': 102, + 'SET_ADD': 103, + 'SET_FUNCTION_ATTRIBUTE': 104, + 'SET_UPDATE': 105, + 'STORE_ATTR': 106, + 'STORE_DEREF': 107, + 'STORE_FAST': 108, + 'STORE_FAST_LOAD_FAST': 109, + 'STORE_FAST_STORE_FAST': 110, + 'STORE_GLOBAL': 111, + 'STORE_NAME': 112, + 'SWAP': 113, + 'UNPACK_EX': 114, + 'UNPACK_SEQUENCE': 115, + 'YIELD_VALUE': 116, + '_DO_CALL_FUNCTION_EX': 117, 'INSTRUMENTED_END_FOR': 236, 'INSTRUMENTED_END_SEND': 237, 'INSTRUMENTED_LOAD_SUPER_ATTR': 238, diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 846404e28bb18f..5f357561dc11fe 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -244,6 +244,11 @@ dummy_func( value = PyStackRef_DUP(GETLOCAL(oparg)); } + inst(LOAD_FAST_DEFERRED, (-- value)) { + assert(!PyStackRef_IsNull(GETLOCAL(oparg))); + value = PyStackRef_DUP(GETLOCAL(oparg)); + } + inst(LOAD_FAST_AND_CLEAR, (-- value)) { value = GETLOCAL(oparg); // do not use SETLOCAL here, it decrefs the old value diff --git a/Python/codegen.c b/Python/codegen.c index 0305f4299aec56..b9639bdc31fb35 100644 --- a/Python/codegen.c +++ b/Python/codegen.c @@ -186,11 +186,16 @@ typedef struct { Py_ssize_t on_top; } pattern_context; -static int codegen_nameop(compiler *, location, identifier, expr_context_ty); +static int codegen_nameop2(compiler *, location, identifier, expr_context_ty, bool); + +static inline int codegen_nameop(compiler *c, location l, identifier i, expr_context_ty e) +{ + return codegen_nameop2(c, l, i, e, false); +} static int codegen_visit_stmt(compiler *, stmt_ty); static int codegen_visit_keyword(compiler *, keyword_ty); -static int codegen_visit_expr(compiler *, expr_ty); +static int codegen_visit_expr(compiler *, expr_ty, bool); static int codegen_augassign(compiler *, stmt_ty); static int codegen_annassign(compiler *, stmt_ty); static int codegen_subscript(compiler *, expr_ty); @@ -419,9 +424,21 @@ codegen_addop_j(instr_sequence *seq, location loc, #define VISIT(C, TYPE, V) \ RETURN_IF_ERROR(codegen_visit_ ## TYPE((C), (V))); +#define VISIT_EXPR(C, V) \ + RETURN_IF_ERROR(codegen_visit_expr((C), (V), false)); + +#define VISIT_EXPR_CONSUMED(C, V) \ + RETURN_IF_ERROR(codegen_visit_expr((C), (V), true)); + +#define VISIT_EXPR2(C, V, B) \ + RETURN_IF_ERROR(codegen_visit_expr((C), (V), (B))); + #define VISIT_IN_SCOPE(C, TYPE, V) \ RETURN_IF_ERROR_IN_SCOPE((C), codegen_visit_ ## TYPE((C), (V))) +#define VISIT_EXPR_IN_SCOPE(C, V) \ + RETURN_IF_ERROR_IN_SCOPE((C), codegen_visit_expr((C), (V), false)) + #define VISIT_SEQ(C, TYPE, SEQ) { \ int _i; \ asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */ \ @@ -431,6 +448,15 @@ codegen_addop_j(instr_sequence *seq, location loc, } \ } +#define VISIT_EXPR_SEQ(C, SEQ, B) { \ + int _i; \ + asdl_expr_seq *seq = (SEQ); /* avoid variable capture */ \ + for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \ + expr_ty elt = (expr_ty)asdl_seq_GET(seq, _i); \ + RETURN_IF_ERROR(codegen_visit_expr((C), elt, (B))); \ + } \ +} + #define VISIT_SEQ_IN_SCOPE(C, TYPE, SEQ) { \ int _i; \ asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */ \ @@ -723,7 +749,7 @@ codegen_process_deferred_annotations(compiler *c, location loc) return ERROR; } ADDOP_LOAD_CONST_NEW(c, LOC(st), mangled); - VISIT(c, expr, st->v.AnnAssign.annotation); + VISIT_EXPR(c, st->v.AnnAssign.annotation); } Py_DECREF(deferred_anno); @@ -737,7 +763,7 @@ codegen_process_deferred_annotations(compiler *c, location loc) int _PyCodegen_Expression(compiler *c, expr_ty e) { - VISIT(c, expr, e); + VISIT_EXPR(c, e); return SUCCESS; } @@ -845,7 +871,7 @@ codegen_decorators(compiler *c, asdl_expr_seq* decos) } for (Py_ssize_t i = 0; i < asdl_seq_LEN(decos); i++) { - VISIT(c, expr, (expr_ty)asdl_seq_GET(decos, i)); + VISIT_EXPR(c, (expr_ty)asdl_seq_GET(decos, i)); } return SUCCESS; } @@ -883,7 +909,7 @@ codegen_kwonlydefaults(compiler *c, location loc, return ERROR; } ADDOP_LOAD_CONST_NEW(c, loc, mangled); - VISIT(c, expr, default_); + VISIT_EXPR(c, default_); } } if (default_count) { @@ -926,11 +952,11 @@ codegen_argannotation(compiler *c, identifier id, // Do [annotation_value] = [*Ts]. // (Note that in theory we could end up here even for an argument // other than *args, but in practice the grammar doesn't allow it.) - VISIT(c, expr, annotation->v.Starred.value); + VISIT_EXPR(c, annotation->v.Starred.value); ADDOP_I(c, loc, UNPACK_SEQUENCE, (Py_ssize_t) 1); } else { - VISIT(c, expr, annotation); + VISIT_EXPR(c, annotation); } } *annotations_len += 1; @@ -1025,7 +1051,7 @@ static int codegen_defaults(compiler *c, arguments_ty args, location loc) { - VISIT_SEQ(c, expr, args->defaults); + VISIT_EXPR_SEQ(c, args->defaults, false); ADDOP_I(c, loc, BUILD_TUPLE, asdl_seq_LEN(args->defaults)); return SUCCESS; } @@ -1079,11 +1105,11 @@ codegen_type_param_bound_or_default(compiler *c, expr_ty e, ADDOP_LOAD_CONST_NEW(c, LOC(e), defaults); RETURN_IF_ERROR(codegen_setup_annotations_scope(c, LOC(e), key, name)); if (allow_starred && e->kind == Starred_kind) { - VISIT(c, expr, e->v.Starred.value); + VISIT_EXPR(c, e->v.Starred.value); ADDOP_I(c, LOC(e), UNPACK_SEQUENCE, (Py_ssize_t)1); } else { - VISIT(c, expr, e); + VISIT_EXPR(c, e); } ADDOP_IN_SCOPE(c, LOC(e), RETURN_VALUE); PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 1); @@ -1583,7 +1609,7 @@ codegen_typealias_body(compiler *c, stmt_ty s) /* Make None the first constant, so the evaluate function can't have a docstring. */ RETURN_IF_ERROR(_PyCompile_AddConst(c, Py_None)); - VISIT_IN_SCOPE(c, expr, s->v.TypeAlias.value); + VISIT_EXPR_IN_SCOPE(c, s->v.TypeAlias.value); ADDOP_IN_SCOPE(c, loc, RETURN_VALUE); PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 0); _PyCompile_ExitScope(c); @@ -1795,17 +1821,16 @@ codegen_jump_if(compiler *c, location loc, if (n > 0) { RETURN_IF_ERROR(codegen_check_compare(c, e)); NEW_JUMP_TARGET_LABEL(c, cleanup); - VISIT(c, expr, e->v.Compare.left); + VISIT_EXPR_CONSUMED(c, e->v.Compare.left); for (Py_ssize_t i = 0; i < n; i++) { - VISIT(c, expr, - (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i)); + VISIT_EXPR_CONSUMED(c, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i)); ADDOP_I(c, LOC(e), SWAP, 2); ADDOP_I(c, LOC(e), COPY, 2); ADDOP_COMPARE(c, LOC(e), asdl_seq_GET(e->v.Compare.ops, i)); ADDOP(c, LOC(e), TO_BOOL); ADDOP_JUMP(c, LOC(e), POP_JUMP_IF_FALSE, cleanup); } - VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n)); + VISIT_EXPR_CONSUMED(c, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n)); ADDOP_COMPARE(c, LOC(e), asdl_seq_GET(e->v.Compare.ops, n)); ADDOP(c, LOC(e), TO_BOOL); ADDOP_JUMP(c, LOC(e), cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next); @@ -1830,7 +1855,7 @@ codegen_jump_if(compiler *c, location loc, } /* general implementation */ - VISIT(c, expr, e); + VISIT_EXPR(c, e); ADDOP(c, LOC(e), TO_BOOL); ADDOP_JUMP(c, LOC(e), cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next); return SUCCESS; @@ -1846,11 +1871,11 @@ codegen_ifexp(compiler *c, expr_ty e) RETURN_IF_ERROR( codegen_jump_if(c, LOC(e), e->v.IfExp.test, next, 0)); - VISIT(c, expr, e->v.IfExp.body); + VISIT_EXPR(c, e->v.IfExp.body); ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end); USE_LABEL(c, next); - VISIT(c, expr, e->v.IfExp.orelse); + VISIT_EXPR(c, e->v.IfExp.orelse); USE_LABEL(c, end); return SUCCESS; @@ -1882,7 +1907,7 @@ codegen_lambda(compiler *c, expr_ty e) docstring. */ RETURN_IF_ERROR(_PyCompile_AddConst(c, Py_None)); - VISIT_IN_SCOPE(c, expr, e->v.Lambda.body); + VISIT_EXPR_IN_SCOPE(c, e->v.Lambda.body); if (SYMTABLE_ENTRY(c)->ste_generator) { co = _PyCompile_OptimizeAndAssemble(c, 0); } @@ -1941,7 +1966,7 @@ codegen_for(compiler *c, stmt_ty s) RETURN_IF_ERROR(_PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_FOR_LOOP, start, end, NULL)); - VISIT(c, expr, s->v.For.iter); + VISIT_EXPR(c, s->v.For.iter); loc = LOC(s->v.For.iter); ADDOP(c, loc, GET_ITER); @@ -1955,7 +1980,7 @@ codegen_for(compiler *c, stmt_ty s) ADDOP(c, LOC(s->v.For.target), NOP); USE_LABEL(c, body); - VISIT(c, expr, s->v.For.target); + VISIT_EXPR(c, s->v.For.target); VISIT_SEQ(c, stmt, s->v.For.body); /* Mark jump as artificial */ ADDOP_JUMP(c, NO_LOCATION, JUMP, start); @@ -1986,7 +2011,7 @@ codegen_async_for(compiler *c, stmt_ty s) NEW_JUMP_TARGET_LABEL(c, except); NEW_JUMP_TARGET_LABEL(c, end); - VISIT(c, expr, s->v.AsyncFor.iter); + VISIT_EXPR(c, s->v.AsyncFor.iter); ADDOP(c, LOC(s->v.AsyncFor.iter), GET_AITER); USE_LABEL(c, start); @@ -2000,7 +2025,7 @@ codegen_async_for(compiler *c, stmt_ty s) ADDOP(c, loc, POP_BLOCK); /* for SETUP_FINALLY */ /* Success block for __anext__ */ - VISIT(c, expr, s->v.AsyncFor.target); + VISIT_EXPR(c, s->v.AsyncFor.target); VISIT_SEQ(c, stmt, s->v.AsyncFor.body); /* Mark jump as artificial */ ADDOP_JUMP(c, NO_LOCATION, JUMP, start); @@ -2064,7 +2089,7 @@ codegen_return(compiler *c, stmt_ty s) } if (preserve_tos) { - VISIT(c, expr, s->v.Return.value); + VISIT_EXPR(c, s->v.Return.value); } else { /* Emit instruction with line number for return value */ if (s->v.Return.value != NULL) { @@ -2326,7 +2351,7 @@ codegen_try_except(compiler *c, stmt_ty s) NEW_JUMP_TARGET_LABEL(c, next_except); except = next_except; if (handler->v.ExceptHandler.type) { - VISIT(c, expr, handler->v.ExceptHandler.type); + VISIT_EXPR(c, handler->v.ExceptHandler.type); ADDOP(c, loc, CHECK_EXC_MATCH); ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, except); } @@ -2519,7 +2544,7 @@ codegen_try_star_except(compiler *c, stmt_ty s) ADDOP_I(c, loc, COPY, 2); } if (handler->v.ExceptHandler.type) { - VISIT(c, expr, handler->v.ExceptHandler.type); + VISIT_EXPR(c, handler->v.ExceptHandler.type); ADDOP(c, loc, CHECK_EG_MATCH); ADDOP_I(c, loc, COPY, 1); ADDOP_JUMP(c, loc, POP_JUMP_IF_NONE, no_match); @@ -2810,7 +2835,7 @@ codegen_assert(compiler *c, stmt_ty s) RETURN_IF_ERROR(codegen_jump_if(c, LOC(s), s->v.Assert.test, end, 1)); ADDOP_I(c, LOC(s), LOAD_COMMON_CONSTANT, CONSTANT_ASSERTIONERROR); if (s->v.Assert.msg) { - VISIT(c, expr, s->v.Assert.msg); + VISIT_EXPR(c, s->v.Assert.msg); ADDOP_I(c, LOC(s), CALL, 0); } ADDOP_I(c, LOC(s->v.Assert.test), RAISE_VARARGS, 1); @@ -2823,7 +2848,7 @@ static int codegen_stmt_expr(compiler *c, location loc, expr_ty value) { if (IS_INTERACTIVE_TOP_LEVEL(c)) { - VISIT(c, expr, value); + VISIT_EXPR(c, value); ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_PRINT); ADDOP(c, NO_LOCATION, POP_TOP); return SUCCESS; @@ -2835,7 +2860,7 @@ codegen_stmt_expr(compiler *c, location loc, expr_ty value) return SUCCESS; } - VISIT(c, expr, value); + VISIT_EXPR(c, value); ADDOP(c, NO_LOCATION, POP_TOP); /* artificial */ return SUCCESS; } @@ -2854,18 +2879,17 @@ codegen_visit_stmt(compiler *c, stmt_ty s) case Return_kind: return codegen_return(c, s); case Delete_kind: - VISIT_SEQ(c, expr, s->v.Delete.targets) + VISIT_EXPR_SEQ(c, s->v.Delete.targets, false); break; case Assign_kind: { Py_ssize_t n = asdl_seq_LEN(s->v.Assign.targets); - VISIT(c, expr, s->v.Assign.value); + VISIT_EXPR(c, s->v.Assign.value); for (Py_ssize_t i = 0; i < n; i++) { if (i < n - 1) { ADDOP_I(c, LOC(s), COPY, 1); } - VISIT(c, expr, - (expr_ty)asdl_seq_GET(s->v.Assign.targets, i)); + VISIT_EXPR(c, (expr_ty)asdl_seq_GET(s->v.Assign.targets, i)); } break; } @@ -2885,10 +2909,10 @@ codegen_visit_stmt(compiler *c, stmt_ty s) { Py_ssize_t n = 0; if (s->v.Raise.exc) { - VISIT(c, expr, s->v.Raise.exc); + VISIT_EXPR(c, s->v.Raise.exc); n++; if (s->v.Raise.cause) { - VISIT(c, expr, s->v.Raise.cause); + VISIT_EXPR(c, s->v.Raise.cause); n++; } } @@ -3027,8 +3051,8 @@ codegen_load_classdict_freevar(compiler *c, location loc) } static int -codegen_nameop(compiler *c, location loc, - identifier name, expr_context_ty ctx) +codegen_nameop2(compiler *c, location loc, + identifier name, expr_context_ty ctx, bool ref_consumed) { assert(!_PyUnicode_EqualToASCIIString(name, "None") && !_PyUnicode_EqualToASCIIString(name, "True") && @@ -3080,9 +3104,15 @@ codegen_nameop(compiler *c, location loc, break; case COMPILE_OP_FAST: switch (ctx) { - case Load: op = LOAD_FAST; break; - case Store: op = STORE_FAST; break; - case Del: op = DELETE_FAST; break; + case Load: + op = ref_consumed ? LOAD_FAST_DEFERRED : LOAD_FAST; + break; + case Store: + op = STORE_FAST; + break; + case Del: + op = DELETE_FAST; + break; } ADDOP_N(c, loc, op, mangled, varnames); return SUCCESS; @@ -3148,13 +3178,13 @@ codegen_boolop(compiler *c, expr_ty e) n = asdl_seq_LEN(s) - 1; assert(n >= 0); for (i = 0; i < n; ++i) { - VISIT(c, expr, (expr_ty)asdl_seq_GET(s, i)); + VISIT_EXPR(c, (expr_ty)asdl_seq_GET(s, i)); ADDOP_I(c, loc, COPY, 1); ADDOP(c, loc, TO_BOOL); ADDOP_JUMP(c, loc, jumpi, end); ADDOP(c, loc, POP_TOP); } - VISIT(c, expr, (expr_ty)asdl_seq_GET(s, n)); + VISIT_EXPR(c, (expr_ty)asdl_seq_GET(s, n)); USE_LABEL(c, end); return SUCCESS; @@ -3206,7 +3236,7 @@ starunpack_helper_impl(compiler *c, location loc, if (!seen_star && !big) { for (Py_ssize_t i = 0; i < n; i++) { expr_ty elt = asdl_seq_GET(elts, i); - VISIT(c, expr, elt); + VISIT_EXPR(c, elt); } if (injected_arg) { RETURN_IF_ERROR(codegen_nameop(c, loc, injected_arg, Load)); @@ -3231,11 +3261,11 @@ starunpack_helper_impl(compiler *c, location loc, ADDOP_I(c, loc, build, i+pushed); sequence_built = 1; } - VISIT(c, expr, elt->v.Starred.value); + VISIT_EXPR(c, elt->v.Starred.value); ADDOP_I(c, loc, extend, 1); } else { - VISIT(c, expr, elt); + VISIT_EXPR(c, elt); if (sequence_built) { ADDOP_I(c, loc, add, 1); } @@ -3296,7 +3326,7 @@ assignment_helper(compiler *c, location loc, asdl_expr_seq *elts) RETURN_IF_ERROR(unpack_helper(c, loc, elts)); for (Py_ssize_t i = 0; i < n; i++) { expr_ty elt = asdl_seq_GET(elts, i); - VISIT(c, expr, elt->kind != Starred_kind ? elt : elt->v.Starred.value); + VISIT_EXPR(c, elt->kind != Starred_kind ? elt : elt->v.Starred.value); } return SUCCESS; } @@ -3314,7 +3344,7 @@ codegen_list(compiler *c, expr_ty e) BUILD_LIST, LIST_APPEND, LIST_EXTEND, 0); } else { - VISIT_SEQ(c, expr, elts); + VISIT_EXPR_SEQ(c, elts, true); } return SUCCESS; } @@ -3332,7 +3362,7 @@ codegen_tuple(compiler *c, expr_ty e) BUILD_LIST, LIST_APPEND, LIST_EXTEND, 1); } else { - VISIT_SEQ(c, expr, elts); + VISIT_EXPR_SEQ(c, elts, true); } return SUCCESS; } @@ -3367,8 +3397,8 @@ codegen_subdict(compiler *c, expr_ty e, Py_ssize_t begin, Py_ssize_t end) ADDOP_I(c, loc, BUILD_MAP, 0); } for (i = begin; i < end; i++) { - VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.keys, i)); - VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i)); + VISIT_EXPR(c, (expr_ty)asdl_seq_GET(e->v.Dict.keys, i)); + VISIT_EXPR(c, (expr_ty)asdl_seq_GET(e->v.Dict.values, i)); if (big) { ADDOP_I(c, loc, MAP_ADD, 1); } @@ -3404,7 +3434,7 @@ codegen_dict(compiler *c, expr_ty e) ADDOP_I(c, loc, BUILD_MAP, 0); have_dict = 1; } - VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i)); + VISIT_EXPR(c, (expr_ty)asdl_seq_GET(e->v.Dict.values, i)); ADDOP_I(c, loc, DICT_UPDATE, 1); } else { @@ -3441,18 +3471,17 @@ codegen_compare(compiler *c, expr_ty e) Py_ssize_t i, n; RETURN_IF_ERROR(codegen_check_compare(c, e)); - VISIT(c, expr, e->v.Compare.left); + VISIT_EXPR_CONSUMED(c, e->v.Compare.left); assert(asdl_seq_LEN(e->v.Compare.ops) > 0); n = asdl_seq_LEN(e->v.Compare.ops) - 1; if (n == 0) { - VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, 0)); + VISIT_EXPR_CONSUMED(c, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, 0)); ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, 0)); } else { NEW_JUMP_TARGET_LABEL(c, cleanup); for (i = 0; i < n; i++) { - VISIT(c, expr, - (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i)); + VISIT_EXPR_CONSUMED(c, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i)); ADDOP_I(c, loc, SWAP, 2); ADDOP_I(c, loc, COPY, 2); ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, i)); @@ -3461,7 +3490,7 @@ codegen_compare(compiler *c, expr_ty e) ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, cleanup); ADDOP(c, loc, POP_TOP); } - VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n)); + VISIT_EXPR_CONSUMED(c, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n)); ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, n)); NEW_JUMP_TARGET_LABEL(c, end); ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end); @@ -3676,8 +3705,8 @@ load_args_for_super(compiler *c, expr_ty e) { RETURN_IF_ERROR(codegen_nameop(c, LOC(e->v.Call.func), super_name, Load)); if (asdl_seq_LEN(e->v.Call.args) == 2) { - VISIT(c, expr, asdl_seq_GET(e->v.Call.args, 0)); - VISIT(c, expr, asdl_seq_GET(e->v.Call.args, 1)); + VISIT_EXPR(c, asdl_seq_GET(e->v.Call.args, 0)); + VISIT_EXPR(c, asdl_seq_GET(e->v.Call.args, 1)); return SUCCESS; } @@ -3780,12 +3809,12 @@ maybe_optimize_method_call(compiler *c, expr_ty e) loc = update_start_location_to_match_attr(c, loc, meth); ADDOP(c, loc, NOP); } else { - VISIT(c, expr, meth->v.Attribute.value); + VISIT_EXPR(c, meth->v.Attribute.value); loc = update_start_location_to_match_attr(c, loc, meth); ADDOP_NAME(c, loc, LOAD_METHOD, meth->v.Attribute.attr, names); } - VISIT_SEQ(c, expr, e->v.Call.args); + VISIT_EXPR_SEQ(c, e->v.Call.args, true); if (kwdsl) { VISIT_SEQ(c, keyword, kwds); @@ -3832,7 +3861,7 @@ codegen_call(compiler *c, expr_ty e) return SUCCESS; } RETURN_IF_ERROR(check_caller(c, e->v.Call.func)); - VISIT(c, expr, e->v.Call.func); + VISIT_EXPR(c, e->v.Call.func); location loc = LOC(e->v.Call.func); ADDOP(c, loc, PUSH_NULL); loc = LOC(e); @@ -3852,13 +3881,13 @@ codegen_joined_str(compiler *c, expr_ty e) ADDOP_NAME(c, loc, LOAD_METHOD, &_Py_ID(join), names); ADDOP_I(c, loc, BUILD_LIST, 0); for (Py_ssize_t i = 0; i < asdl_seq_LEN(e->v.JoinedStr.values); i++) { - VISIT(c, expr, asdl_seq_GET(e->v.JoinedStr.values, i)); + VISIT_EXPR(c, asdl_seq_GET(e->v.JoinedStr.values, i)); ADDOP_I(c, loc, LIST_APPEND, 1); } ADDOP_I(c, loc, CALL, 1); } else { - VISIT_SEQ(c, expr, e->v.JoinedStr.values); + VISIT_EXPR_SEQ(c, e->v.JoinedStr.values, true); if (value_count > 1) { ADDOP_I(c, loc, BUILD_STRING, value_count); } @@ -3892,7 +3921,7 @@ codegen_formatted_value(compiler *c, expr_ty e) int oparg; /* The expression to be formatted. */ - VISIT(c, expr, e->v.FormattedValue.value); + VISIT_EXPR(c, e->v.FormattedValue.value); location loc = LOC(e); if (conversion != -1) { @@ -3909,7 +3938,7 @@ codegen_formatted_value(compiler *c, expr_ty e) } if (e->v.FormattedValue.format_spec) { /* Evaluate the format spec, and update our opcode arg. */ - VISIT(c, expr, e->v.FormattedValue.format_spec); + VISIT_EXPR(c, e->v.FormattedValue.format_spec); ADDOP(c, loc, FORMAT_WITH_SPEC); } else { ADDOP(c, loc, FORMAT_SIMPLE); @@ -3932,7 +3961,7 @@ codegen_subkwargs(compiler *c, location loc, for (i = begin; i < end; i++) { kw = asdl_seq_GET(keywords, i); ADDOP_LOAD_CONST(c, loc, kw->arg); - VISIT(c, expr, kw->value); + VISIT_EXPR(c, kw->value); if (big) { ADDOP_I(c, NO_LOCATION, MAP_ADD, 1); } @@ -3998,7 +4027,7 @@ codegen_call_helper_impl(compiler *c, location loc, for (i = 0; i < nelts; i++) { expr_ty elt = asdl_seq_GET(args, i); assert(elt->kind != Starred_kind); - VISIT(c, expr, elt); + VISIT_EXPR(c, elt); } if (injected_arg) { RETURN_IF_ERROR(codegen_nameop(c, loc, injected_arg, Load)); @@ -4019,7 +4048,7 @@ codegen_call_helper_impl(compiler *c, location loc, /* Do positional arguments. */ if (n == 0 && nelts == 1 && ((expr_ty)asdl_seq_GET(args, 0))->kind == Starred_kind) { - VISIT(c, expr, ((expr_ty)asdl_seq_GET(args, 0))->v.Starred.value); + VISIT_EXPR(c, ((expr_ty)asdl_seq_GET(args, 0))->v.Starred.value); } else { RETURN_IF_ERROR(starunpack_helper_impl(c, loc, args, injected_arg, n, @@ -4047,7 +4076,7 @@ codegen_call_helper_impl(compiler *c, location loc, ADDOP_I(c, loc, BUILD_MAP, 0); have_dict = 1; } - VISIT(c, expr, kw->value); + VISIT_EXPR(c, kw->value); ADDOP_I(c, loc, DICT_MERGE, 1); } else { @@ -4152,12 +4181,12 @@ codegen_sync_comprehension_generator(compiler *c, location loc, if (asdl_seq_LEN(elts) == 1) { expr_ty elt = asdl_seq_GET(elts, 0); if (elt->kind != Starred_kind) { - VISIT(c, expr, elt); + VISIT_EXPR(c, elt); start = NO_LABEL; } } if (IS_JUMP_TARGET_LABEL(start)) { - VISIT(c, expr, gen->iter); + VISIT_EXPR(c, gen->iter); ADDOP(c, LOC(gen->iter), GET_ITER); } } @@ -4168,7 +4197,7 @@ codegen_sync_comprehension_generator(compiler *c, location loc, USE_LABEL(c, start); ADDOP_JUMP(c, LOC(gen->iter), FOR_ITER, anchor); } - VISIT(c, expr, gen->target); + VISIT_EXPR(c, gen->target); /* XXX this needs to be cleaned up...a lot! */ Py_ssize_t n = asdl_seq_LEN(gen->ifs); @@ -4191,23 +4220,23 @@ codegen_sync_comprehension_generator(compiler *c, location loc, /* comprehension specific code */ switch (type) { case COMP_GENEXP: - VISIT(c, expr, elt); + VISIT_EXPR(c, elt); ADDOP_YIELD(c, elt_loc); ADDOP(c, elt_loc, POP_TOP); break; case COMP_LISTCOMP: - VISIT(c, expr, elt); + VISIT_EXPR(c, elt); ADDOP_I(c, elt_loc, LIST_APPEND, depth + 1); break; case COMP_SETCOMP: - VISIT(c, expr, elt); + VISIT_EXPR(c, elt); ADDOP_I(c, elt_loc, SET_ADD, depth + 1); break; case COMP_DICTCOMP: /* With '{k: v}', k is evaluated before v, so we do the same. */ - VISIT(c, expr, elt); - VISIT(c, expr, val); + VISIT_EXPR(c, elt); + VISIT_EXPR(c, val); elt_loc = LOCATION(elt->lineno, val->end_lineno, elt->col_offset, @@ -4256,7 +4285,7 @@ codegen_async_comprehension_generator(compiler *c, location loc, } else { /* Sub-iter - calculate on the fly */ - VISIT(c, expr, gen->iter); + VISIT_EXPR(c, gen->iter); ADDOP(c, LOC(gen->iter), GET_AITER); } } @@ -4272,7 +4301,7 @@ codegen_async_comprehension_generator(compiler *c, location loc, ADDOP_LOAD_CONST(c, loc, Py_None); ADD_YIELD_FROM(c, loc, 1); ADDOP(c, loc, POP_BLOCK); - VISIT(c, expr, gen->target); + VISIT_EXPR(c, gen->target); Py_ssize_t n = asdl_seq_LEN(gen->ifs); for (Py_ssize_t i = 0; i < n; i++) { @@ -4294,23 +4323,23 @@ codegen_async_comprehension_generator(compiler *c, location loc, /* comprehension specific code */ switch (type) { case COMP_GENEXP: - VISIT(c, expr, elt); + VISIT_EXPR(c, elt); ADDOP_YIELD(c, elt_loc); ADDOP(c, elt_loc, POP_TOP); break; case COMP_LISTCOMP: - VISIT(c, expr, elt); + VISIT_EXPR(c, elt); ADDOP_I(c, elt_loc, LIST_APPEND, depth + 1); break; case COMP_SETCOMP: - VISIT(c, expr, elt); + VISIT_EXPR(c, elt); ADDOP_I(c, elt_loc, SET_ADD, depth + 1); break; case COMP_DICTCOMP: /* With '{k: v}', k is evaluated before v, so we do the same. */ - VISIT(c, expr, elt); - VISIT(c, expr, val); + VISIT_EXPR(c, elt); + VISIT_EXPR(c, val); elt_loc = LOCATION(elt->lineno, val->end_lineno, elt->col_offset, @@ -4473,7 +4502,7 @@ pop_inlined_comprehension_state(compiler *c, location loc, static inline int codegen_comprehension_iter(compiler *c, comprehension_ty comp) { - VISIT(c, expr, comp->iter); + VISIT_EXPR(c, comp->iter); if (comp->is_async) { ADDOP(c, LOC(comp->iter), GET_AITER); } @@ -4649,7 +4678,7 @@ codegen_dictcomp(compiler *c, expr_ty e) static int codegen_visit_keyword(compiler *c, keyword_ty k) { - VISIT(c, expr, k->value); + VISIT_EXPR(c, k->value); return SUCCESS; } @@ -4716,7 +4745,7 @@ codegen_async_with(compiler *c, stmt_ty s, int pos) NEW_JUMP_TARGET_LABEL(c, cleanup); /* Evaluate EXPR */ - VISIT(c, expr, item->context_expr); + VISIT_EXPR(c, item->context_expr); loc = LOC(item->context_expr); ADDOP_I(c, loc, COPY, 1); ADDOP_I(c, loc, LOAD_SPECIAL, SPECIAL___AEXIT__); @@ -4735,7 +4764,7 @@ codegen_async_with(compiler *c, stmt_ty s, int pos) RETURN_IF_ERROR(_PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_ASYNC_WITH, block, final, s)); if (item->optional_vars) { - VISIT(c, expr, item->optional_vars); + VISIT_EXPR(c, item->optional_vars); } else { /* Discard result from context.__aenter__() */ @@ -4818,7 +4847,7 @@ codegen_with(compiler *c, stmt_ty s, int pos) NEW_JUMP_TARGET_LABEL(c, cleanup); /* Evaluate EXPR */ - VISIT(c, expr, item->context_expr); + VISIT_EXPR(c, item->context_expr); /* Will push bound __exit__ */ location loc = LOC(item->context_expr); ADDOP_I(c, loc, COPY, 1); @@ -4834,7 +4863,7 @@ codegen_with(compiler *c, stmt_ty s, int pos) RETURN_IF_ERROR(_PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_WITH, block, final, s)); if (item->optional_vars) { - VISIT(c, expr, item->optional_vars); + VISIT_EXPR(c, item->optional_vars); } else { /* Discard result from context.__enter__() */ @@ -4875,24 +4904,24 @@ codegen_with(compiler *c, stmt_ty s, int pos) } static int -codegen_visit_expr(compiler *c, expr_ty e) +codegen_visit_expr(compiler *c, expr_ty e, bool ref_consumed) { location loc = LOC(e); switch (e->kind) { case NamedExpr_kind: - VISIT(c, expr, e->v.NamedExpr.value); + VISIT_EXPR(c, e->v.NamedExpr.value); ADDOP_I(c, loc, COPY, 1); - VISIT(c, expr, e->v.NamedExpr.target); + VISIT_EXPR(c, e->v.NamedExpr.target); break; case BoolOp_kind: return codegen_boolop(c, e); case BinOp_kind: - VISIT(c, expr, e->v.BinOp.left); - VISIT(c, expr, e->v.BinOp.right); + VISIT_EXPR_CONSUMED(c, e->v.BinOp.left); + VISIT_EXPR_CONSUMED(c, e->v.BinOp.right); ADDOP_BINARY(c, loc, e->v.BinOp.op); break; case UnaryOp_kind: - VISIT(c, expr, e->v.UnaryOp.operand); + VISIT_EXPR_CONSUMED(c, e->v.UnaryOp.operand); if (e->v.UnaryOp.op == UAdd) { ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_UNARY_POSITIVE); } @@ -4925,7 +4954,7 @@ codegen_visit_expr(compiler *c, expr_ty e) return _PyCompile_Error(c, loc, "'yield' outside function"); } if (e->v.Yield.value) { - VISIT(c, expr, e->v.Yield.value); + VISIT_EXPR(c, e->v.Yield.value); } else { ADDOP_LOAD_CONST(c, loc, Py_None); @@ -4939,13 +4968,13 @@ codegen_visit_expr(compiler *c, expr_ty e) if (SCOPE_TYPE(c) == COMPILE_SCOPE_ASYNC_FUNCTION) { return _PyCompile_Error(c, loc, "'yield from' inside async function"); } - VISIT(c, expr, e->v.YieldFrom.value); + VISIT_EXPR(c, e->v.YieldFrom.value); ADDOP(c, loc, GET_YIELD_FROM_ITER); ADDOP_LOAD_CONST(c, loc, Py_None); ADD_YIELD_FROM(c, loc, 0); break; case Await_kind: - VISIT(c, expr, e->v.Await.value); + VISIT_EXPR(c, e->v.Await.value); ADDOP_I(c, loc, GET_AWAITABLE, 0); ADDOP_LOAD_CONST(c, loc, Py_None); ADD_YIELD_FROM(c, loc, 1); @@ -4977,7 +5006,7 @@ codegen_visit_expr(compiler *c, expr_ty e) } } RETURN_IF_ERROR(_PyCompile_MaybeAddStaticAttributeToClass(c, e)); - VISIT(c, expr, e->v.Attribute.value); + VISIT_EXPR_CONSUMED(c, e->v.Attribute.value); loc = LOC(e); loc = update_start_location_to_match_attr(c, loc, e); switch (e->v.Attribute.ctx) { @@ -5014,7 +5043,7 @@ codegen_visit_expr(compiler *c, expr_ty e) break; } case Name_kind: - return codegen_nameop(c, loc, e->v.Name.id, e->v.Name.ctx); + return codegen_nameop2(c, loc, e->v.Name.id, e->v.Name.ctx, ref_consumed); /* child nodes of List and Tuple will have expr_context set */ case List_kind: return codegen_list(c, e); @@ -5041,13 +5070,13 @@ codegen_augassign(compiler *c, stmt_ty s) switch (e->kind) { case Attribute_kind: - VISIT(c, expr, e->v.Attribute.value); + VISIT_EXPR(c, e->v.Attribute.value); ADDOP_I(c, loc, COPY, 1); loc = update_start_location_to_match_attr(c, loc, e); ADDOP_NAME(c, loc, LOAD_ATTR, e->v.Attribute.attr, names); break; case Subscript_kind: - VISIT(c, expr, e->v.Subscript.value); + VISIT_EXPR(c, e->v.Subscript.value); if (is_two_element_slice(e->v.Subscript.slice)) { RETURN_IF_ERROR(codegen_slice(c, e->v.Subscript.slice)); ADDOP_I(c, loc, COPY, 3); @@ -5056,7 +5085,7 @@ codegen_augassign(compiler *c, stmt_ty s) ADDOP(c, loc, BINARY_SLICE); } else { - VISIT(c, expr, e->v.Subscript.slice); + VISIT_EXPR(c, e->v.Subscript.slice); ADDOP_I(c, loc, COPY, 2); ADDOP_I(c, loc, COPY, 2); ADDOP(c, loc, BINARY_SUBSCR); @@ -5074,7 +5103,7 @@ codegen_augassign(compiler *c, stmt_ty s) loc = LOC(s); - VISIT(c, expr, s->v.AugAssign.value); + VISIT_EXPR(c, s->v.AugAssign.value); ADDOP_INPLACE(c, loc, s->v.AugAssign.op); loc = LOC(e); @@ -5109,7 +5138,7 @@ codegen_augassign(compiler *c, stmt_ty s) static int codegen_check_ann_expr(compiler *c, expr_ty e) { - VISIT(c, expr, e); + VISIT_EXPR(c, e); ADDOP(c, LOC(e), POP_TOP); return SUCCESS; } @@ -5173,8 +5202,8 @@ codegen_annassign(compiler *c, stmt_ty s) /* We perform the actual assignment first. */ if (s->v.AnnAssign.value) { - VISIT(c, expr, s->v.AnnAssign.value); - VISIT(c, expr, targ); + VISIT_EXPR(c, s->v.AnnAssign.value); + VISIT_EXPR(c, targ); } switch (targ->kind) { case Name_kind: @@ -5232,7 +5261,7 @@ codegen_subscript(compiler *c, expr_ty e) RETURN_IF_ERROR(check_index(c, e->v.Subscript.value, e->v.Subscript.slice)); } - VISIT(c, expr, e->v.Subscript.value); + VISIT_EXPR(c, e->v.Subscript.value); if (is_two_element_slice(e->v.Subscript.slice) && ctx != Del) { RETURN_IF_ERROR(codegen_slice(c, e->v.Subscript.slice)); if (ctx == Load) { @@ -5244,7 +5273,7 @@ codegen_subscript(compiler *c, expr_ty e) } } else { - VISIT(c, expr, e->v.Subscript.slice); + VISIT_EXPR(c, e->v.Subscript.slice); switch (ctx) { case Load: op = BINARY_SUBSCR; break; case Store: op = STORE_SUBSCR; break; @@ -5266,14 +5295,14 @@ codegen_slice(compiler *c, expr_ty s) /* only handles the cases where BUILD_SLICE is emitted */ if (s->v.Slice.lower) { - VISIT(c, expr, s->v.Slice.lower); + VISIT_EXPR(c, s->v.Slice.lower); } else { ADDOP_LOAD_CONST(c, LOC(s), Py_None); } if (s->v.Slice.upper) { - VISIT(c, expr, s->v.Slice.upper); + VISIT_EXPR(c, s->v.Slice.upper); } else { ADDOP_LOAD_CONST(c, LOC(s), Py_None); @@ -5281,7 +5310,7 @@ codegen_slice(compiler *c, expr_ty s) if (s->v.Slice.step) { n++; - VISIT(c, expr, s->v.Slice.step); + VISIT_EXPR(c, s->v.Slice.step); } return n; } @@ -5585,7 +5614,7 @@ codegen_pattern_class(compiler *c, pattern_ty p, pattern_context *pc) if (nattrs) { RETURN_IF_ERROR(validate_kwd_attrs(c, kwd_attrs, kwd_patterns)); } - VISIT(c, expr, p->v.MatchClass.cls); + VISIT_EXPR(c, p->v.MatchClass.cls); PyObject *attr_names = PyTuple_New(nattrs); if (attr_names == NULL) { return ERROR; @@ -5652,7 +5681,7 @@ codegen_pattern_mapping_key(compiler *c, PyObject *seen, pattern_ty p, Py_ssize_ const char *e = "mapping pattern keys may only match literals and attribute lookups"; return _PyCompile_Error(c, LOC(p), e); } - VISIT(c, expr, key); + VISIT_EXPR(c, key); return SUCCESS; } @@ -5976,7 +6005,7 @@ codegen_pattern_value(compiler *c, pattern_ty p, pattern_context *pc) const char *e = "patterns may only match literals and attribute lookups"; return _PyCompile_Error(c, LOC(p), e); } - VISIT(c, expr, value); + VISIT_EXPR(c, value); ADDOP_COMPARE(c, LOC(p), Eq); ADDOP(c, LOC(p), TO_BOOL); RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE)); @@ -6023,7 +6052,7 @@ codegen_pattern(compiler *c, pattern_ty p, pattern_context *pc) static int codegen_match_inner(compiler *c, stmt_ty s, pattern_context *pc) { - VISIT(c, expr, s->v.Match.subject); + VISIT_EXPR(c, s->v.Match.subject); NEW_JUMP_TARGET_LABEL(c, end); Py_ssize_t cases = asdl_seq_LEN(s->v.Match.cases); assert(cases > 0); diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 93ab068f9de949..25d8926b9b77ce 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -182,6 +182,17 @@ break; } + case _LOAD_FAST_DEFERRED: { + _PyStackRef value; + oparg = CURRENT_OPARG(); + assert(!PyStackRef_IsNull(GETLOCAL(oparg))); + value = PyStackRef_DUP(GETLOCAL(oparg)); + stack_pointer[0] = value; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + break; + } + case _LOAD_FAST_AND_CLEAR: { _PyStackRef value; oparg = CURRENT_OPARG(); diff --git a/Python/flowgraph.c b/Python/flowgraph.c index f7d8efb28e21c4..c4fa7a500ccabb 100644 --- a/Python/flowgraph.c +++ b/Python/flowgraph.c @@ -1994,6 +1994,7 @@ scan_block_for_locals(basicblock *b, basicblock ***sp) unsafe_mask &= ~bit; break; case LOAD_FAST: + case LOAD_FAST_DEFERRED: if (unsafe_mask & bit) { instr->i_opcode = LOAD_FAST_CHECK; } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 6d902e2c1d9ba8..f1095edc00b1d5 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -5567,6 +5567,19 @@ DISPATCH(); } + TARGET(LOAD_FAST_DEFERRED) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(LOAD_FAST_DEFERRED); + _PyStackRef value; + assert(!PyStackRef_IsNull(GETLOCAL(oparg))); + value = PyStackRef_DUP(GETLOCAL(oparg)); + stack_pointer[0] = value; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + DISPATCH(); + } + TARGET(LOAD_FAST_LOAD_FAST) { frame->instr_ptr = next_instr; next_instr += 1; diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index 49f01ca2932ee2..8f48a94d19ee9f 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -83,6 +83,7 @@ static void *opcode_targets[256] = { &&TARGET_LOAD_FAST, &&TARGET_LOAD_FAST_AND_CLEAR, &&TARGET_LOAD_FAST_CHECK, + &&TARGET_LOAD_FAST_DEFERRED, &&TARGET_LOAD_FAST_LOAD_FAST, &&TARGET_LOAD_FROM_DICT_OR_DEREF, &&TARGET_LOAD_FROM_DICT_OR_GLOBALS, @@ -147,7 +148,6 @@ static void *opcode_targets[256] = { &&_unknown_opcode, &&_unknown_opcode, &&_unknown_opcode, - &&_unknown_opcode, &&TARGET_RESUME, &&TARGET_BINARY_OP_ADD_FLOAT, &&TARGET_BINARY_OP_ADD_INT, diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index a6cfa271ae6758..b3341e502e0a1a 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -45,6 +45,15 @@ break; } + case _LOAD_FAST_DEFERRED: { + _Py_UopsSymbol *value; + value = sym_new_not_null(ctx); + stack_pointer[0] = value; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + break; + } + case _LOAD_FAST_AND_CLEAR: { _Py_UopsSymbol *value; value = GETLOCAL(oparg); From dc4bea41cf757e2a3308a236170c85113fcb8a86 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 20 Sep 2024 09:39:07 +0100 Subject: [PATCH 2/4] 'defer' more LOAD_FASTs --- Python/codegen.c | 98 ++++++++++++++++++++++++------------------------ 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/Python/codegen.c b/Python/codegen.c index b9639bdc31fb35..8100449d9b4e27 100644 --- a/Python/codegen.c +++ b/Python/codegen.c @@ -871,7 +871,7 @@ codegen_decorators(compiler *c, asdl_expr_seq* decos) } for (Py_ssize_t i = 0; i < asdl_seq_LEN(decos); i++) { - VISIT_EXPR(c, (expr_ty)asdl_seq_GET(decos, i)); + VISIT_EXPR_CONSUMED(c, (expr_ty)asdl_seq_GET(decos, i)); } return SUCCESS; } @@ -1855,14 +1855,14 @@ codegen_jump_if(compiler *c, location loc, } /* general implementation */ - VISIT_EXPR(c, e); + VISIT_EXPR_CONSUMED(c, e); ADDOP(c, LOC(e), TO_BOOL); ADDOP_JUMP(c, LOC(e), cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next); return SUCCESS; } static int -codegen_ifexp(compiler *c, expr_ty e) +codegen_ifexp(compiler *c, expr_ty e, bool ref_consumed) { assert(e->kind == IfExp_kind); NEW_JUMP_TARGET_LABEL(c, end); @@ -1871,11 +1871,11 @@ codegen_ifexp(compiler *c, expr_ty e) RETURN_IF_ERROR( codegen_jump_if(c, LOC(e), e->v.IfExp.test, next, 0)); - VISIT_EXPR(c, e->v.IfExp.body); + VISIT_EXPR2(c, e->v.IfExp.body, ref_consumed); ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end); USE_LABEL(c, next); - VISIT_EXPR(c, e->v.IfExp.orelse); + VISIT_EXPR2(c, e->v.IfExp.orelse, ref_consumed); USE_LABEL(c, end); return SUCCESS; @@ -1966,7 +1966,7 @@ codegen_for(compiler *c, stmt_ty s) RETURN_IF_ERROR(_PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_FOR_LOOP, start, end, NULL)); - VISIT_EXPR(c, s->v.For.iter); + VISIT_EXPR_CONSUMED(c, s->v.For.iter); loc = LOC(s->v.For.iter); ADDOP(c, loc, GET_ITER); @@ -2011,7 +2011,7 @@ codegen_async_for(compiler *c, stmt_ty s) NEW_JUMP_TARGET_LABEL(c, except); NEW_JUMP_TARGET_LABEL(c, end); - VISIT_EXPR(c, s->v.AsyncFor.iter); + VISIT_EXPR_CONSUMED(c, s->v.AsyncFor.iter); ADDOP(c, LOC(s->v.AsyncFor.iter), GET_AITER); USE_LABEL(c, start); @@ -2351,7 +2351,7 @@ codegen_try_except(compiler *c, stmt_ty s) NEW_JUMP_TARGET_LABEL(c, next_except); except = next_except; if (handler->v.ExceptHandler.type) { - VISIT_EXPR(c, handler->v.ExceptHandler.type); + VISIT_EXPR_CONSUMED(c, handler->v.ExceptHandler.type); ADDOP(c, loc, CHECK_EXC_MATCH); ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, except); } @@ -2544,7 +2544,7 @@ codegen_try_star_except(compiler *c, stmt_ty s) ADDOP_I(c, loc, COPY, 2); } if (handler->v.ExceptHandler.type) { - VISIT_EXPR(c, handler->v.ExceptHandler.type); + VISIT_EXPR_CONSUMED(c, handler->v.ExceptHandler.type); ADDOP(c, loc, CHECK_EG_MATCH); ADDOP_I(c, loc, COPY, 1); ADDOP_JUMP(c, loc, POP_JUMP_IF_NONE, no_match); @@ -2848,7 +2848,7 @@ static int codegen_stmt_expr(compiler *c, location loc, expr_ty value) { if (IS_INTERACTIVE_TOP_LEVEL(c)) { - VISIT_EXPR(c, value); + VISIT_EXPR_CONSUMED(c, value); ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_PRINT); ADDOP(c, NO_LOCATION, POP_TOP); return SUCCESS; @@ -2860,7 +2860,7 @@ codegen_stmt_expr(compiler *c, location loc, expr_ty value) return SUCCESS; } - VISIT_EXPR(c, value); + VISIT_EXPR_CONSUMED(c, value); ADDOP(c, NO_LOCATION, POP_TOP); /* artificial */ return SUCCESS; } @@ -3161,7 +3161,7 @@ codegen_nameop2(compiler *c, location loc, } static int -codegen_boolop(compiler *c, expr_ty e) +codegen_boolop(compiler *c, expr_ty e, bool ref_consumed) { int jumpi; Py_ssize_t i, n; @@ -3178,13 +3178,13 @@ codegen_boolop(compiler *c, expr_ty e) n = asdl_seq_LEN(s) - 1; assert(n >= 0); for (i = 0; i < n; ++i) { - VISIT_EXPR(c, (expr_ty)asdl_seq_GET(s, i)); + VISIT_EXPR2(c, (expr_ty)asdl_seq_GET(s, i), ref_consumed); ADDOP_I(c, loc, COPY, 1); ADDOP(c, loc, TO_BOOL); ADDOP_JUMP(c, loc, jumpi, end); ADDOP(c, loc, POP_TOP); } - VISIT_EXPR(c, (expr_ty)asdl_seq_GET(s, n)); + VISIT_EXPR2(c, (expr_ty)asdl_seq_GET(s, n), ref_consumed); USE_LABEL(c, end); return SUCCESS; @@ -3397,8 +3397,8 @@ codegen_subdict(compiler *c, expr_ty e, Py_ssize_t begin, Py_ssize_t end) ADDOP_I(c, loc, BUILD_MAP, 0); } for (i = begin; i < end; i++) { - VISIT_EXPR(c, (expr_ty)asdl_seq_GET(e->v.Dict.keys, i)); - VISIT_EXPR(c, (expr_ty)asdl_seq_GET(e->v.Dict.values, i)); + VISIT_EXPR_CONSUMED(c, (expr_ty)asdl_seq_GET(e->v.Dict.keys, i)); + VISIT_EXPR_CONSUMED(c, (expr_ty)asdl_seq_GET(e->v.Dict.values, i)); if (big) { ADDOP_I(c, loc, MAP_ADD, 1); } @@ -3434,7 +3434,7 @@ codegen_dict(compiler *c, expr_ty e) ADDOP_I(c, loc, BUILD_MAP, 0); have_dict = 1; } - VISIT_EXPR(c, (expr_ty)asdl_seq_GET(e->v.Dict.values, i)); + VISIT_EXPR_CONSUMED(c, (expr_ty)asdl_seq_GET(e->v.Dict.values, i)); ADDOP_I(c, loc, DICT_UPDATE, 1); } else { @@ -3705,8 +3705,8 @@ load_args_for_super(compiler *c, expr_ty e) { RETURN_IF_ERROR(codegen_nameop(c, LOC(e->v.Call.func), super_name, Load)); if (asdl_seq_LEN(e->v.Call.args) == 2) { - VISIT_EXPR(c, asdl_seq_GET(e->v.Call.args, 0)); - VISIT_EXPR(c, asdl_seq_GET(e->v.Call.args, 1)); + VISIT_EXPR_CONSUMED(c, asdl_seq_GET(e->v.Call.args, 0)); + VISIT_EXPR_CONSUMED(c, asdl_seq_GET(e->v.Call.args, 1)); return SUCCESS; } @@ -3809,7 +3809,7 @@ maybe_optimize_method_call(compiler *c, expr_ty e) loc = update_start_location_to_match_attr(c, loc, meth); ADDOP(c, loc, NOP); } else { - VISIT_EXPR(c, meth->v.Attribute.value); + VISIT_EXPR_CONSUMED(c, meth->v.Attribute.value); loc = update_start_location_to_match_attr(c, loc, meth); ADDOP_NAME(c, loc, LOAD_METHOD, meth->v.Attribute.attr, names); } @@ -3861,7 +3861,7 @@ codegen_call(compiler *c, expr_ty e) return SUCCESS; } RETURN_IF_ERROR(check_caller(c, e->v.Call.func)); - VISIT_EXPR(c, e->v.Call.func); + VISIT_EXPR_CONSUMED(c, e->v.Call.func); location loc = LOC(e->v.Call.func); ADDOP(c, loc, PUSH_NULL); loc = LOC(e); @@ -3881,7 +3881,7 @@ codegen_joined_str(compiler *c, expr_ty e) ADDOP_NAME(c, loc, LOAD_METHOD, &_Py_ID(join), names); ADDOP_I(c, loc, BUILD_LIST, 0); for (Py_ssize_t i = 0; i < asdl_seq_LEN(e->v.JoinedStr.values); i++) { - VISIT_EXPR(c, asdl_seq_GET(e->v.JoinedStr.values, i)); + VISIT_EXPR_CONSUMED(c, asdl_seq_GET(e->v.JoinedStr.values, i)); ADDOP_I(c, loc, LIST_APPEND, 1); } ADDOP_I(c, loc, CALL, 1); @@ -3921,7 +3921,7 @@ codegen_formatted_value(compiler *c, expr_ty e) int oparg; /* The expression to be formatted. */ - VISIT_EXPR(c, e->v.FormattedValue.value); + VISIT_EXPR_CONSUMED(c, e->v.FormattedValue.value); location loc = LOC(e); if (conversion != -1) { @@ -3938,7 +3938,7 @@ codegen_formatted_value(compiler *c, expr_ty e) } if (e->v.FormattedValue.format_spec) { /* Evaluate the format spec, and update our opcode arg. */ - VISIT_EXPR(c, e->v.FormattedValue.format_spec); + VISIT_EXPR_CONSUMED(c, e->v.FormattedValue.format_spec); ADDOP(c, loc, FORMAT_WITH_SPEC); } else { ADDOP(c, loc, FORMAT_SIMPLE); @@ -3961,7 +3961,7 @@ codegen_subkwargs(compiler *c, location loc, for (i = begin; i < end; i++) { kw = asdl_seq_GET(keywords, i); ADDOP_LOAD_CONST(c, loc, kw->arg); - VISIT_EXPR(c, kw->value); + VISIT_EXPR_CONSUMED(c, kw->value); if (big) { ADDOP_I(c, NO_LOCATION, MAP_ADD, 1); } @@ -4027,7 +4027,7 @@ codegen_call_helper_impl(compiler *c, location loc, for (i = 0; i < nelts; i++) { expr_ty elt = asdl_seq_GET(args, i); assert(elt->kind != Starred_kind); - VISIT_EXPR(c, elt); + VISIT_EXPR_CONSUMED(c, elt); } if (injected_arg) { RETURN_IF_ERROR(codegen_nameop(c, loc, injected_arg, Load)); @@ -4048,7 +4048,7 @@ codegen_call_helper_impl(compiler *c, location loc, /* Do positional arguments. */ if (n == 0 && nelts == 1 && ((expr_ty)asdl_seq_GET(args, 0))->kind == Starred_kind) { - VISIT_EXPR(c, ((expr_ty)asdl_seq_GET(args, 0))->v.Starred.value); + VISIT_EXPR_CONSUMED(c, ((expr_ty)asdl_seq_GET(args, 0))->v.Starred.value); } else { RETURN_IF_ERROR(starunpack_helper_impl(c, loc, args, injected_arg, n, @@ -4225,18 +4225,18 @@ codegen_sync_comprehension_generator(compiler *c, location loc, ADDOP(c, elt_loc, POP_TOP); break; case COMP_LISTCOMP: - VISIT_EXPR(c, elt); + VISIT_EXPR_CONSUMED(c, elt); ADDOP_I(c, elt_loc, LIST_APPEND, depth + 1); break; case COMP_SETCOMP: - VISIT_EXPR(c, elt); + VISIT_EXPR_CONSUMED(c, elt); ADDOP_I(c, elt_loc, SET_ADD, depth + 1); break; case COMP_DICTCOMP: /* With '{k: v}', k is evaluated before v, so we do the same. */ - VISIT_EXPR(c, elt); - VISIT_EXPR(c, val); + VISIT_EXPR_CONSUMED(c, elt); + VISIT_EXPR_CONSUMED(c, val); elt_loc = LOCATION(elt->lineno, val->end_lineno, elt->col_offset, @@ -4285,7 +4285,7 @@ codegen_async_comprehension_generator(compiler *c, location loc, } else { /* Sub-iter - calculate on the fly */ - VISIT_EXPR(c, gen->iter); + VISIT_EXPR_CONSUMED(c, gen->iter); ADDOP(c, LOC(gen->iter), GET_AITER); } } @@ -4328,18 +4328,18 @@ codegen_async_comprehension_generator(compiler *c, location loc, ADDOP(c, elt_loc, POP_TOP); break; case COMP_LISTCOMP: - VISIT_EXPR(c, elt); + VISIT_EXPR_CONSUMED(c, elt); ADDOP_I(c, elt_loc, LIST_APPEND, depth + 1); break; case COMP_SETCOMP: - VISIT_EXPR(c, elt); + VISIT_EXPR_CONSUMED(c, elt); ADDOP_I(c, elt_loc, SET_ADD, depth + 1); break; case COMP_DICTCOMP: /* With '{k: v}', k is evaluated before v, so we do the same. */ - VISIT_EXPR(c, elt); - VISIT_EXPR(c, val); + VISIT_EXPR_CONSUMED(c, elt); + VISIT_EXPR_CONSUMED(c, val); elt_loc = LOCATION(elt->lineno, val->end_lineno, elt->col_offset, @@ -4502,7 +4502,7 @@ pop_inlined_comprehension_state(compiler *c, location loc, static inline int codegen_comprehension_iter(compiler *c, comprehension_ty comp) { - VISIT_EXPR(c, comp->iter); + VISIT_EXPR_CONSUMED(c, comp->iter); if (comp->is_async) { ADDOP(c, LOC(comp->iter), GET_AITER); } @@ -4745,7 +4745,7 @@ codegen_async_with(compiler *c, stmt_ty s, int pos) NEW_JUMP_TARGET_LABEL(c, cleanup); /* Evaluate EXPR */ - VISIT_EXPR(c, item->context_expr); + VISIT_EXPR_CONSUMED(c, item->context_expr); loc = LOC(item->context_expr); ADDOP_I(c, loc, COPY, 1); ADDOP_I(c, loc, LOAD_SPECIAL, SPECIAL___AEXIT__); @@ -4847,7 +4847,7 @@ codegen_with(compiler *c, stmt_ty s, int pos) NEW_JUMP_TARGET_LABEL(c, cleanup); /* Evaluate EXPR */ - VISIT_EXPR(c, item->context_expr); + VISIT_EXPR_CONSUMED(c, item->context_expr); /* Will push bound __exit__ */ location loc = LOC(item->context_expr); ADDOP_I(c, loc, COPY, 1); @@ -4909,12 +4909,12 @@ codegen_visit_expr(compiler *c, expr_ty e, bool ref_consumed) location loc = LOC(e); switch (e->kind) { case NamedExpr_kind: - VISIT_EXPR(c, e->v.NamedExpr.value); + VISIT_EXPR2(c, e->v.NamedExpr.value, ref_consumed); ADDOP_I(c, loc, COPY, 1); VISIT_EXPR(c, e->v.NamedExpr.target); break; case BoolOp_kind: - return codegen_boolop(c, e); + return codegen_boolop(c, e, ref_consumed); case BinOp_kind: VISIT_EXPR_CONSUMED(c, e->v.BinOp.left); VISIT_EXPR_CONSUMED(c, e->v.BinOp.right); @@ -4936,7 +4936,7 @@ codegen_visit_expr(compiler *c, expr_ty e, bool ref_consumed) case Lambda_kind: return codegen_lambda(c, e); case IfExp_kind: - return codegen_ifexp(c, e); + return codegen_ifexp(c, e, ref_consumed); case Dict_kind: return codegen_dict(c, e); case Set_kind: @@ -4974,7 +4974,7 @@ codegen_visit_expr(compiler *c, expr_ty e, bool ref_consumed) ADD_YIELD_FROM(c, loc, 0); break; case Await_kind: - VISIT_EXPR(c, e->v.Await.value); + VISIT_EXPR_CONSUMED(c, e->v.Await.value); ADDOP_I(c, loc, GET_AWAITABLE, 0); ADDOP_LOAD_CONST(c, loc, Py_None); ADD_YIELD_FROM(c, loc, 1); @@ -5070,13 +5070,13 @@ codegen_augassign(compiler *c, stmt_ty s) switch (e->kind) { case Attribute_kind: - VISIT_EXPR(c, e->v.Attribute.value); + VISIT_EXPR_CONSUMED(c, e->v.Attribute.value); ADDOP_I(c, loc, COPY, 1); loc = update_start_location_to_match_attr(c, loc, e); ADDOP_NAME(c, loc, LOAD_ATTR, e->v.Attribute.attr, names); break; case Subscript_kind: - VISIT_EXPR(c, e->v.Subscript.value); + VISIT_EXPR_CONSUMED(c, e->v.Subscript.value); if (is_two_element_slice(e->v.Subscript.slice)) { RETURN_IF_ERROR(codegen_slice(c, e->v.Subscript.slice)); ADDOP_I(c, loc, COPY, 3); @@ -5085,14 +5085,14 @@ codegen_augassign(compiler *c, stmt_ty s) ADDOP(c, loc, BINARY_SLICE); } else { - VISIT_EXPR(c, e->v.Subscript.slice); + VISIT_EXPR_CONSUMED(c, e->v.Subscript.slice); ADDOP_I(c, loc, COPY, 2); ADDOP_I(c, loc, COPY, 2); ADDOP(c, loc, BINARY_SUBSCR); } break; case Name_kind: - RETURN_IF_ERROR(codegen_nameop(c, loc, e->v.Name.id, Load)); + RETURN_IF_ERROR(codegen_nameop2(c, loc, e->v.Name.id, Load, true)); break; default: PyErr_Format(PyExc_SystemError, @@ -5103,7 +5103,7 @@ codegen_augassign(compiler *c, stmt_ty s) loc = LOC(s); - VISIT_EXPR(c, s->v.AugAssign.value); + VISIT_EXPR_CONSUMED(c, s->v.AugAssign.value); ADDOP_INPLACE(c, loc, s->v.AugAssign.op); loc = LOC(e); @@ -5138,7 +5138,7 @@ codegen_augassign(compiler *c, stmt_ty s) static int codegen_check_ann_expr(compiler *c, expr_ty e) { - VISIT_EXPR(c, e); + VISIT_EXPR_CONSUMED(c, e); ADDOP(c, LOC(e), POP_TOP); return SUCCESS; } From 7fb4dc85831c022ccd5d540668b5f4cf021e83f6 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Fri, 20 Sep 2024 10:27:40 +0100 Subject: [PATCH 3/4] Update generated files --- Programs/test_frozenmain.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Programs/test_frozenmain.h b/Programs/test_frozenmain.h index 624d9c0b653ad7..67ea9329f4797f 100644 --- a/Programs/test_frozenmain.h +++ b/Programs/test_frozenmain.h @@ -2,16 +2,16 @@ unsigned char M_test_frozenmain[] = { 227,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0, 0,0,0,0,0,243,166,0,0,0,149,0,79,0,79,1, - 70,0,111,0,79,0,79,1,70,1,111,1,88,2,31,0, - 79,2,49,1,0,0,0,0,0,0,29,0,88,2,31,0, - 79,3,88,0,77,6,0,0,0,0,0,0,0,0,0,0, + 70,0,112,0,79,0,79,1,70,1,112,1,89,2,31,0, + 79,2,49,1,0,0,0,0,0,0,29,0,89,2,31,0, + 79,3,89,0,77,6,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,49,2,0,0,0,0,0,0, - 29,0,88,1,77,8,0,0,0,0,0,0,0,0,0,0, + 29,0,89,1,77,8,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,31,0,49,0,0,0,0,0, - 0,0,79,4,2,0,0,0,111,5,79,5,16,0,67,20, - 0,0,111,6,88,2,31,0,79,6,88,6,12,0,79,7, - 88,5,88,6,2,0,0,0,12,0,47,4,49,1,0,0, - 0,0,0,0,29,0,72,22,0,0,9,0,29,0,100,1, + 0,0,79,4,2,0,0,0,112,5,79,5,16,0,67,20, + 0,0,112,6,89,2,31,0,79,6,89,6,12,0,79,7, + 89,5,89,6,2,0,0,0,12,0,47,4,49,1,0,0, + 0,0,0,0,29,0,72,22,0,0,9,0,29,0,101,1, 41,8,233,0,0,0,0,78,122,18,70,114,111,122,101,110, 32,72,101,108,108,111,32,87,111,114,108,100,122,8,115,121, 115,46,97,114,103,118,218,6,99,111,110,102,105,103,41,5, From 9992ab792a0773984b41eeb95aece88fdcb5e506 Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Wed, 9 Oct 2024 12:38:38 +0100 Subject: [PATCH 4/4] Change LOAD_FAST_DEFERRED to LOAD_FAST_TEMP --- Include/internal/pycore_magic_number.h | 2 +- Include/internal/pycore_opcode_metadata.h | 16 ++-- Include/internal/pycore_uop_ids.h | 86 +++++++++++--------- Include/internal/pycore_uop_metadata.h | 39 ++++++++- Include/opcode_ids.h | 4 +- Lib/_opcode_metadata.py | 4 +- Lib/test/test_compiler_codegen.py | 2 +- Lib/test/test_peepholer.py | 44 +++++----- Python/bytecodes.c | 2 +- Python/codegen.c | 2 +- Python/executor_cases.c.h | 98 ++++++++++++++++++++++- Python/flowgraph.c | 3 +- Python/generated_cases.c.h | 26 +++--- Python/opcode_targets.h | 2 +- Python/optimizer_cases.c.h | 2 +- 15 files changed, 235 insertions(+), 97 deletions(-) diff --git a/Include/internal/pycore_magic_number.h b/Include/internal/pycore_magic_number.h index 587e3ad89ed677..c716eb14117972 100644 --- a/Include/internal/pycore_magic_number.h +++ b/Include/internal/pycore_magic_number.h @@ -259,7 +259,7 @@ Known values: Python 3.14a1 3605 (Move ENTER_EXECUTOR to opcode 255) Python 3.14a1 3606 (Specialize CALL_KW) - Python 3.14a1 3607 (LOAD_FAST_DEFERRED) + Python 3.14a1 3607 (LOAD_FAST_TEMP) Python 3.15 will start with 3650 diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h index 0d5b2b5928cff6..38161df5961ecf 100644 --- a/Include/internal/pycore_opcode_metadata.h +++ b/Include/internal/pycore_opcode_metadata.h @@ -319,10 +319,10 @@ int _PyOpcode_num_popped(int opcode, int oparg) { return 0; case LOAD_FAST_CHECK: return 0; - case LOAD_FAST_DEFERRED: - return 0; case LOAD_FAST_LOAD_FAST: return 0; + case LOAD_FAST_TEMP: + return 0; case LOAD_FROM_DICT_OR_DEREF: return 1; case LOAD_FROM_DICT_OR_GLOBALS: @@ -778,10 +778,10 @@ int _PyOpcode_num_pushed(int opcode, int oparg) { return 1; case LOAD_FAST_CHECK: return 1; - case LOAD_FAST_DEFERRED: - return 1; case LOAD_FAST_LOAD_FAST: return 2; + case LOAD_FAST_TEMP: + return 1; case LOAD_FROM_DICT_OR_DEREF: return 1; case LOAD_FROM_DICT_OR_GLOBALS: @@ -1152,8 +1152,8 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[264] = { [LOAD_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_PURE_FLAG }, [LOAD_FAST_AND_CLEAR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG }, [LOAD_FAST_CHECK] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, - [LOAD_FAST_DEFERRED] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG }, [LOAD_FAST_LOAD_FAST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG }, + [LOAD_FAST_TEMP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_PURE_FLAG }, [LOAD_FROM_DICT_OR_DEREF] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_FREE_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [LOAD_FROM_DICT_OR_GLOBALS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG }, [LOAD_GLOBAL] = { true, INSTR_FMT_IBC000, HAS_ARG_FLAG | HAS_NAME_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG }, @@ -1357,8 +1357,8 @@ _PyOpcode_macro_expansion[256] = { [LOAD_FAST] = { .nuops = 1, .uops = { { _LOAD_FAST, 0, 0 } } }, [LOAD_FAST_AND_CLEAR] = { .nuops = 1, .uops = { { _LOAD_FAST_AND_CLEAR, 0, 0 } } }, [LOAD_FAST_CHECK] = { .nuops = 1, .uops = { { _LOAD_FAST_CHECK, 0, 0 } } }, - [LOAD_FAST_DEFERRED] = { .nuops = 1, .uops = { { _LOAD_FAST_DEFERRED, 0, 0 } } }, [LOAD_FAST_LOAD_FAST] = { .nuops = 2, .uops = { { _LOAD_FAST, 5, 0 }, { _LOAD_FAST, 6, 0 } } }, + [LOAD_FAST_TEMP] = { .nuops = 1, .uops = { { _LOAD_FAST_TEMP, 0, 0 } } }, [LOAD_FROM_DICT_OR_DEREF] = { .nuops = 1, .uops = { { _LOAD_FROM_DICT_OR_DEREF, 0, 0 } } }, [LOAD_GLOBAL] = { .nuops = 1, .uops = { { _LOAD_GLOBAL, 0, 0 } } }, [LOAD_GLOBAL_BUILTIN] = { .nuops = 3, .uops = { { _GUARD_GLOBALS_VERSION, 1, 1 }, { _GUARD_BUILTINS_VERSION, 1, 2 }, { _LOAD_GLOBAL_BUILTINS, 1, 3 } } }, @@ -1574,8 +1574,8 @@ const char *_PyOpcode_OpName[264] = { [LOAD_FAST] = "LOAD_FAST", [LOAD_FAST_AND_CLEAR] = "LOAD_FAST_AND_CLEAR", [LOAD_FAST_CHECK] = "LOAD_FAST_CHECK", - [LOAD_FAST_DEFERRED] = "LOAD_FAST_DEFERRED", [LOAD_FAST_LOAD_FAST] = "LOAD_FAST_LOAD_FAST", + [LOAD_FAST_TEMP] = "LOAD_FAST_TEMP", [LOAD_FROM_DICT_OR_DEREF] = "LOAD_FROM_DICT_OR_DEREF", [LOAD_FROM_DICT_OR_GLOBALS] = "LOAD_FROM_DICT_OR_GLOBALS", [LOAD_GLOBAL] = "LOAD_GLOBAL", @@ -1827,8 +1827,8 @@ const uint8_t _PyOpcode_Deopt[256] = { [LOAD_FAST] = LOAD_FAST, [LOAD_FAST_AND_CLEAR] = LOAD_FAST_AND_CLEAR, [LOAD_FAST_CHECK] = LOAD_FAST_CHECK, - [LOAD_FAST_DEFERRED] = LOAD_FAST_DEFERRED, [LOAD_FAST_LOAD_FAST] = LOAD_FAST_LOAD_FAST, + [LOAD_FAST_TEMP] = LOAD_FAST_TEMP, [LOAD_FROM_DICT_OR_DEREF] = LOAD_FROM_DICT_OR_DEREF, [LOAD_FROM_DICT_OR_GLOBALS] = LOAD_FROM_DICT_OR_GLOBALS, [LOAD_GLOBAL] = LOAD_GLOBAL, diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h index a1bc9fb9cb62ea..d7a40ff2028683 100644 --- a/Include/internal/pycore_uop_ids.h +++ b/Include/internal/pycore_uop_ids.h @@ -209,13 +209,21 @@ extern "C" { #define _LOAD_FAST_7 435 #define _LOAD_FAST_AND_CLEAR LOAD_FAST_AND_CLEAR #define _LOAD_FAST_CHECK LOAD_FAST_CHECK -#define _LOAD_FAST_DEFERRED LOAD_FAST_DEFERRED #define _LOAD_FAST_LOAD_FAST LOAD_FAST_LOAD_FAST +#define _LOAD_FAST_TEMP 436 +#define _LOAD_FAST_TEMP_0 437 +#define _LOAD_FAST_TEMP_1 438 +#define _LOAD_FAST_TEMP_2 439 +#define _LOAD_FAST_TEMP_3 440 +#define _LOAD_FAST_TEMP_4 441 +#define _LOAD_FAST_TEMP_5 442 +#define _LOAD_FAST_TEMP_6 443 +#define _LOAD_FAST_TEMP_7 444 #define _LOAD_FROM_DICT_OR_DEREF LOAD_FROM_DICT_OR_DEREF #define _LOAD_FROM_DICT_OR_GLOBALS LOAD_FROM_DICT_OR_GLOBALS -#define _LOAD_GLOBAL 436 -#define _LOAD_GLOBAL_BUILTINS 437 -#define _LOAD_GLOBAL_MODULE 438 +#define _LOAD_GLOBAL 445 +#define _LOAD_GLOBAL_BUILTINS 446 +#define _LOAD_GLOBAL_MODULE 447 #define _LOAD_LOCALS LOAD_LOCALS #define _LOAD_NAME LOAD_NAME #define _LOAD_SPECIAL LOAD_SPECIAL @@ -228,59 +236,59 @@ extern "C" { #define _MATCH_KEYS MATCH_KEYS #define _MATCH_MAPPING MATCH_MAPPING #define _MATCH_SEQUENCE MATCH_SEQUENCE -#define _MAYBE_EXPAND_METHOD 439 -#define _MONITOR_CALL 440 -#define _MONITOR_JUMP_BACKWARD 441 -#define _MONITOR_RESUME 442 +#define _MAYBE_EXPAND_METHOD 448 +#define _MONITOR_CALL 449 +#define _MONITOR_JUMP_BACKWARD 450 +#define _MONITOR_RESUME 451 #define _NOP NOP #define _POP_EXCEPT POP_EXCEPT -#define _POP_JUMP_IF_FALSE 443 -#define _POP_JUMP_IF_TRUE 444 +#define _POP_JUMP_IF_FALSE 452 +#define _POP_JUMP_IF_TRUE 453 #define _POP_TOP POP_TOP -#define _POP_TOP_LOAD_CONST_INLINE_BORROW 445 +#define _POP_TOP_LOAD_CONST_INLINE_BORROW 454 #define _PUSH_EXC_INFO PUSH_EXC_INFO -#define _PUSH_FRAME 446 +#define _PUSH_FRAME 455 #define _PUSH_NULL PUSH_NULL -#define _PY_FRAME_GENERAL 447 -#define _PY_FRAME_KW 448 -#define _QUICKEN_RESUME 449 -#define _REPLACE_WITH_TRUE 450 +#define _PY_FRAME_GENERAL 456 +#define _PY_FRAME_KW 457 +#define _QUICKEN_RESUME 458 +#define _REPLACE_WITH_TRUE 459 #define _RESUME_CHECK RESUME_CHECK #define _RETURN_GENERATOR RETURN_GENERATOR #define _RETURN_VALUE RETURN_VALUE -#define _SAVE_RETURN_OFFSET 451 -#define _SEND 452 -#define _SEND_GEN_FRAME 453 +#define _SAVE_RETURN_OFFSET 460 +#define _SEND 461 +#define _SEND_GEN_FRAME 462 #define _SETUP_ANNOTATIONS SETUP_ANNOTATIONS #define _SET_ADD SET_ADD #define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE #define _SET_UPDATE SET_UPDATE -#define _START_EXECUTOR 454 -#define _STORE_ATTR 455 -#define _STORE_ATTR_INSTANCE_VALUE 456 -#define _STORE_ATTR_SLOT 457 -#define _STORE_ATTR_WITH_HINT 458 +#define _START_EXECUTOR 463 +#define _STORE_ATTR 464 +#define _STORE_ATTR_INSTANCE_VALUE 465 +#define _STORE_ATTR_SLOT 466 +#define _STORE_ATTR_WITH_HINT 467 #define _STORE_DEREF STORE_DEREF -#define _STORE_FAST 459 -#define _STORE_FAST_0 460 -#define _STORE_FAST_1 461 -#define _STORE_FAST_2 462 -#define _STORE_FAST_3 463 -#define _STORE_FAST_4 464 -#define _STORE_FAST_5 465 -#define _STORE_FAST_6 466 -#define _STORE_FAST_7 467 +#define _STORE_FAST 468 +#define _STORE_FAST_0 469 +#define _STORE_FAST_1 470 +#define _STORE_FAST_2 471 +#define _STORE_FAST_3 472 +#define _STORE_FAST_4 473 +#define _STORE_FAST_5 474 +#define _STORE_FAST_6 475 +#define _STORE_FAST_7 476 #define _STORE_FAST_LOAD_FAST STORE_FAST_LOAD_FAST #define _STORE_FAST_STORE_FAST STORE_FAST_STORE_FAST #define _STORE_GLOBAL STORE_GLOBAL #define _STORE_NAME STORE_NAME -#define _STORE_SLICE 468 -#define _STORE_SUBSCR 469 +#define _STORE_SLICE 477 +#define _STORE_SUBSCR 478 #define _STORE_SUBSCR_DICT STORE_SUBSCR_DICT #define _STORE_SUBSCR_LIST_INT STORE_SUBSCR_LIST_INT #define _SWAP SWAP -#define _TIER2_RESUME_CHECK 470 -#define _TO_BOOL 471 +#define _TIER2_RESUME_CHECK 479 +#define _TO_BOOL 480 #define _TO_BOOL_BOOL TO_BOOL_BOOL #define _TO_BOOL_INT TO_BOOL_INT #define _TO_BOOL_LIST TO_BOOL_LIST @@ -290,14 +298,14 @@ extern "C" { #define _UNARY_NEGATIVE UNARY_NEGATIVE #define _UNARY_NOT UNARY_NOT #define _UNPACK_EX UNPACK_EX -#define _UNPACK_SEQUENCE 472 +#define _UNPACK_SEQUENCE 481 #define _UNPACK_SEQUENCE_LIST UNPACK_SEQUENCE_LIST #define _UNPACK_SEQUENCE_TUPLE UNPACK_SEQUENCE_TUPLE #define _UNPACK_SEQUENCE_TWO_TUPLE UNPACK_SEQUENCE_TWO_TUPLE #define _WITH_EXCEPT_START WITH_EXCEPT_START #define _YIELD_VALUE YIELD_VALUE #define __DO_CALL_FUNCTION_EX _DO_CALL_FUNCTION_EX -#define MAX_UOP_ID 472 +#define MAX_UOP_ID 481 #ifdef __cplusplus } diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h index 5b2973d1e9f605..e435e3aa878a65 100644 --- a/Include/internal/pycore_uop_metadata.h +++ b/Include/internal/pycore_uop_metadata.h @@ -33,7 +33,15 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = { [_LOAD_FAST_6] = HAS_LOCAL_FLAG | HAS_PURE_FLAG, [_LOAD_FAST_7] = HAS_LOCAL_FLAG | HAS_PURE_FLAG, [_LOAD_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_PURE_FLAG, - [_LOAD_FAST_DEFERRED] = HAS_ARG_FLAG | HAS_LOCAL_FLAG, + [_LOAD_FAST_TEMP_0] = HAS_LOCAL_FLAG | HAS_PURE_FLAG, + [_LOAD_FAST_TEMP_1] = HAS_LOCAL_FLAG | HAS_PURE_FLAG, + [_LOAD_FAST_TEMP_2] = HAS_LOCAL_FLAG | HAS_PURE_FLAG, + [_LOAD_FAST_TEMP_3] = HAS_LOCAL_FLAG | HAS_PURE_FLAG, + [_LOAD_FAST_TEMP_4] = HAS_LOCAL_FLAG | HAS_PURE_FLAG, + [_LOAD_FAST_TEMP_5] = HAS_LOCAL_FLAG | HAS_PURE_FLAG, + [_LOAD_FAST_TEMP_6] = HAS_LOCAL_FLAG | HAS_PURE_FLAG, + [_LOAD_FAST_TEMP_7] = HAS_LOCAL_FLAG | HAS_PURE_FLAG, + [_LOAD_FAST_TEMP] = HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_PURE_FLAG, [_LOAD_FAST_AND_CLEAR] = HAS_ARG_FLAG | HAS_LOCAL_FLAG, [_LOAD_FAST_LOAD_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG, [_LOAD_CONST] = HAS_ARG_FLAG | HAS_CONST_FLAG | HAS_PURE_FLAG, @@ -284,6 +292,7 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = { const uint8_t _PyUop_Replication[MAX_UOP_ID+1] = { [_LOAD_FAST] = 8, + [_LOAD_FAST_TEMP] = 8, [_STORE_FAST] = 8, [_INIT_CALL_PY_EXACT_ARGS] = 5, }; @@ -470,8 +479,16 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = { [_LOAD_FAST_7] = "_LOAD_FAST_7", [_LOAD_FAST_AND_CLEAR] = "_LOAD_FAST_AND_CLEAR", [_LOAD_FAST_CHECK] = "_LOAD_FAST_CHECK", - [_LOAD_FAST_DEFERRED] = "_LOAD_FAST_DEFERRED", [_LOAD_FAST_LOAD_FAST] = "_LOAD_FAST_LOAD_FAST", + [_LOAD_FAST_TEMP] = "_LOAD_FAST_TEMP", + [_LOAD_FAST_TEMP_0] = "_LOAD_FAST_TEMP_0", + [_LOAD_FAST_TEMP_1] = "_LOAD_FAST_TEMP_1", + [_LOAD_FAST_TEMP_2] = "_LOAD_FAST_TEMP_2", + [_LOAD_FAST_TEMP_3] = "_LOAD_FAST_TEMP_3", + [_LOAD_FAST_TEMP_4] = "_LOAD_FAST_TEMP_4", + [_LOAD_FAST_TEMP_5] = "_LOAD_FAST_TEMP_5", + [_LOAD_FAST_TEMP_6] = "_LOAD_FAST_TEMP_6", + [_LOAD_FAST_TEMP_7] = "_LOAD_FAST_TEMP_7", [_LOAD_FROM_DICT_OR_DEREF] = "_LOAD_FROM_DICT_OR_DEREF", [_LOAD_GLOBAL] = "_LOAD_GLOBAL", [_LOAD_GLOBAL_BUILTINS] = "_LOAD_GLOBAL_BUILTINS", @@ -582,7 +599,23 @@ int _PyUop_num_popped(int opcode, int oparg) return 0; case _LOAD_FAST: return 0; - case _LOAD_FAST_DEFERRED: + case _LOAD_FAST_TEMP_0: + return 0; + case _LOAD_FAST_TEMP_1: + return 0; + case _LOAD_FAST_TEMP_2: + return 0; + case _LOAD_FAST_TEMP_3: + return 0; + case _LOAD_FAST_TEMP_4: + return 0; + case _LOAD_FAST_TEMP_5: + return 0; + case _LOAD_FAST_TEMP_6: + return 0; + case _LOAD_FAST_TEMP_7: + return 0; + case _LOAD_FAST_TEMP: return 0; case _LOAD_FAST_AND_CLEAR: return 0; diff --git a/Include/opcode_ids.h b/Include/opcode_ids.h index 5622be3c9e7d16..7f458338964920 100644 --- a/Include/opcode_ids.h +++ b/Include/opcode_ids.h @@ -94,8 +94,8 @@ extern "C" { #define LOAD_FAST 81 #define LOAD_FAST_AND_CLEAR 82 #define LOAD_FAST_CHECK 83 -#define LOAD_FAST_DEFERRED 84 -#define LOAD_FAST_LOAD_FAST 85 +#define LOAD_FAST_LOAD_FAST 84 +#define LOAD_FAST_TEMP 85 #define LOAD_FROM_DICT_OR_DEREF 86 #define LOAD_FROM_DICT_OR_GLOBALS 87 #define LOAD_GLOBAL 88 diff --git a/Lib/_opcode_metadata.py b/Lib/_opcode_metadata.py index 0e24edecab7888..858a833616f1f7 100644 --- a/Lib/_opcode_metadata.py +++ b/Lib/_opcode_metadata.py @@ -283,8 +283,8 @@ 'LOAD_FAST': 81, 'LOAD_FAST_AND_CLEAR': 82, 'LOAD_FAST_CHECK': 83, - 'LOAD_FAST_DEFERRED': 84, - 'LOAD_FAST_LOAD_FAST': 85, + 'LOAD_FAST_LOAD_FAST': 84, + 'LOAD_FAST_TEMP': 85, 'LOAD_FROM_DICT_OR_DEREF': 86, 'LOAD_FROM_DICT_OR_GLOBALS': 87, 'LOAD_GLOBAL': 88, diff --git a/Lib/test/test_compiler_codegen.py b/Lib/test/test_compiler_codegen.py index d82fb85ed259ab..a6a624aa561dcf 100644 --- a/Lib/test/test_compiler_codegen.py +++ b/Lib/test/test_compiler_codegen.py @@ -81,7 +81,7 @@ def f(x): [ # Function body ('RESUME', 0), - ('LOAD_FAST', 0), + ('LOAD_FAST_TEMP', 0), ('LOAD_CONST', 1), ('BINARY_OP', 0), ('RETURN_VALUE', None), diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py index dd3eaeb39e7fe3..cf662dd4340c18 100644 --- a/Lib/test/test_peepholer.py +++ b/Lib/test/test_peepholer.py @@ -709,27 +709,27 @@ def f(): def test_load_fast_known_because_parameter(self): def f1(x): print(x) - self.assertInBytecode(f1, 'LOAD_FAST') + self.assertInBytecode(f1, 'LOAD_FAST_TEMP') self.assertNotInBytecode(f1, 'LOAD_FAST_CHECK') def f2(*, x): print(x) - self.assertInBytecode(f2, 'LOAD_FAST') + self.assertInBytecode(f2, 'LOAD_FAST_TEMP') self.assertNotInBytecode(f2, 'LOAD_FAST_CHECK') def f3(*args): print(args) - self.assertInBytecode(f3, 'LOAD_FAST') + self.assertInBytecode(f3, 'LOAD_FAST_TEMP') self.assertNotInBytecode(f3, 'LOAD_FAST_CHECK') def f4(**kwargs): print(kwargs) - self.assertInBytecode(f4, 'LOAD_FAST') + self.assertInBytecode(f4, 'LOAD_FAST_TEMP') self.assertNotInBytecode(f4, 'LOAD_FAST_CHECK') def f5(x=0): print(x) - self.assertInBytecode(f5, 'LOAD_FAST') + self.assertInBytecode(f5, 'LOAD_FAST_TEMP') self.assertNotInBytecode(f5, 'LOAD_FAST_CHECK') def test_load_fast_known_because_already_loaded(self): @@ -739,7 +739,7 @@ def f(): print(x) print(x) self.assertInBytecode(f, 'LOAD_FAST_CHECK') - self.assertInBytecode(f, 'LOAD_FAST') + self.assertInBytecode(f, 'LOAD_FAST_TEMP') def test_load_fast_known_multiple_branches(self): def f(): @@ -748,7 +748,7 @@ def f(): else: x = 2 print(x) - self.assertInBytecode(f, 'LOAD_FAST') + self.assertInBytecode(f, 'LOAD_FAST_TEMP') self.assertNotInBytecode(f, 'LOAD_FAST_CHECK') def test_load_fast_unknown_after_error(self): @@ -792,27 +792,27 @@ def f(): print(a00, a01, a62, a63) print(a64, a65, a78, a79) - self.assertInBytecode(f, 'LOAD_FAST_LOAD_FAST', ("a00", "a01")) + self.assertInBytecode(f, 'LOAD_FAST_TEMP', "a00") self.assertNotInBytecode(f, 'LOAD_FAST_CHECK', "a00") self.assertNotInBytecode(f, 'LOAD_FAST_CHECK', "a01") for i in 62, 63: # First 64 locals: analyze completely - self.assertInBytecode(f, 'LOAD_FAST', f"a{i:02}") + self.assertInBytecode(f, 'LOAD_FAST_TEMP', f"a{i:02}") self.assertNotInBytecode(f, 'LOAD_FAST_CHECK', f"a{i:02}") for i in 64, 65, 78, 79: # Locals >=64 not in the same basicblock self.assertInBytecode(f, 'LOAD_FAST_CHECK', f"a{i:02}") - self.assertNotInBytecode(f, 'LOAD_FAST', f"a{i:02}") + self.assertNotInBytecode(f, 'LOAD_FAST_TEMP', f"a{i:02}") for i in 70, 71: # Locals >=64 in the same basicblock - self.assertInBytecode(f, 'LOAD_FAST', f"a{i:02}") + self.assertInBytecode(f, 'LOAD_FAST_TEMP', f"a{i:02}") self.assertNotInBytecode(f, 'LOAD_FAST_CHECK', f"a{i:02}") # del statements should invalidate within basicblocks. self.assertInBytecode(f, 'LOAD_FAST_CHECK', "a72") - self.assertNotInBytecode(f, 'LOAD_FAST', "a72") + self.assertNotInBytecode(f, 'LOAD_FAST_TEMP', "a72") # previous checked loads within a basicblock enable unchecked loads self.assertInBytecode(f, 'LOAD_FAST_CHECK', "a73") - self.assertInBytecode(f, 'LOAD_FAST', "a73") + self.assertInBytecode(f, 'LOAD_FAST_TEMP', "a73") def test_setting_lineno_no_undefined(self): code = textwrap.dedent("""\ @@ -830,7 +830,7 @@ def f(): ns = {} exec(code, ns) f = ns['f'] - self.assertInBytecode(f, "LOAD_FAST") + self.assertInBytecode(f, "LOAD_FAST_TEMP") self.assertNotInBytecode(f, "LOAD_FAST_CHECK") co_code = f.__code__.co_code def trace(frame, event, arg): @@ -842,7 +842,7 @@ def trace(frame, event, arg): sys.settrace(trace) result = f() self.assertIsNone(result) - self.assertInBytecode(f, "LOAD_FAST") + self.assertInBytecode(f, "LOAD_FAST_TEMP") self.assertNotInBytecode(f, "LOAD_FAST_CHECK") self.assertEqual(f.__code__.co_code, co_code) @@ -862,7 +862,7 @@ def f(): ns = {} exec(code, ns) f = ns['f'] - self.assertInBytecode(f, "LOAD_FAST") + self.assertInBytecode(f, "LOAD_FAST_TEMP") self.assertNotInBytecode(f, "LOAD_FAST_CHECK") co_code = f.__code__.co_code def trace(frame, event, arg): @@ -876,7 +876,7 @@ def trace(frame, event, arg): sys.settrace(trace) result = f() self.assertEqual(result, 4) - self.assertInBytecode(f, "LOAD_FAST") + self.assertInBytecode(f, "LOAD_FAST_TEMP") self.assertNotInBytecode(f, "LOAD_FAST_CHECK") self.assertEqual(f.__code__.co_code, co_code) @@ -896,7 +896,7 @@ def f(): ns = {} exec(code, ns) f = ns['f'] - self.assertInBytecode(f, "LOAD_FAST") + self.assertInBytecode(f, "LOAD_FAST_TEMP") self.assertNotInBytecode(f, "LOAD_FAST_CHECK") co_code = f.__code__.co_code def trace(frame, event, arg): @@ -910,7 +910,7 @@ def trace(frame, event, arg): sys.settrace(trace) result = f() self.assertEqual(result, 4) - self.assertInBytecode(f, "LOAD_FAST") + self.assertInBytecode(f, "LOAD_FAST_TEMP") self.assertNotInBytecode(f, "LOAD_FAST_CHECK") self.assertEqual(f.__code__.co_code, co_code) @@ -928,7 +928,7 @@ def f(): ns = {} exec(code, ns) f = ns['f'] - self.assertInBytecode(f, "LOAD_FAST") + self.assertInBytecode(f, "LOAD_FAST_TEMP") self.assertNotInBytecode(f, "LOAD_FAST_CHECK") return f @@ -942,7 +942,7 @@ def trace(frame, event, arg): return trace sys.settrace(trace) f() - self.assertInBytecode(f, "LOAD_FAST") + self.assertInBytecode(f, "LOAD_FAST_TEMP") self.assertNotInBytecode(f, "LOAD_FAST_CHECK") def test_initializing_local_does_not_add_check(self): @@ -955,7 +955,7 @@ def trace(frame, event, arg): return trace sys.settrace(trace) f() - self.assertInBytecode(f, "LOAD_FAST") + self.assertInBytecode(f, "LOAD_FAST_TEMP") self.assertNotInBytecode(f, "LOAD_FAST_CHECK") diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 5f357561dc11fe..6cb2e379a676fc 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -244,7 +244,7 @@ dummy_func( value = PyStackRef_DUP(GETLOCAL(oparg)); } - inst(LOAD_FAST_DEFERRED, (-- value)) { + replicate(8) pure inst(LOAD_FAST_TEMP, (-- value)) { assert(!PyStackRef_IsNull(GETLOCAL(oparg))); value = PyStackRef_DUP(GETLOCAL(oparg)); } diff --git a/Python/codegen.c b/Python/codegen.c index 8100449d9b4e27..1ccba77fd9da07 100644 --- a/Python/codegen.c +++ b/Python/codegen.c @@ -3105,7 +3105,7 @@ codegen_nameop2(compiler *c, location loc, case COMPILE_OP_FAST: switch (ctx) { case Load: - op = ref_consumed ? LOAD_FAST_DEFERRED : LOAD_FAST; + op = ref_consumed ? LOAD_FAST_TEMP : LOAD_FAST; break; case Store: op = STORE_FAST; diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 25d8926b9b77ce..0d19a4e11c970f 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -182,7 +182,103 @@ break; } - case _LOAD_FAST_DEFERRED: { + case _LOAD_FAST_TEMP_0: { + _PyStackRef value; + oparg = 0; + assert(oparg == CURRENT_OPARG()); + assert(!PyStackRef_IsNull(GETLOCAL(oparg))); + value = PyStackRef_DUP(GETLOCAL(oparg)); + stack_pointer[0] = value; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + break; + } + + case _LOAD_FAST_TEMP_1: { + _PyStackRef value; + oparg = 1; + assert(oparg == CURRENT_OPARG()); + assert(!PyStackRef_IsNull(GETLOCAL(oparg))); + value = PyStackRef_DUP(GETLOCAL(oparg)); + stack_pointer[0] = value; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + break; + } + + case _LOAD_FAST_TEMP_2: { + _PyStackRef value; + oparg = 2; + assert(oparg == CURRENT_OPARG()); + assert(!PyStackRef_IsNull(GETLOCAL(oparg))); + value = PyStackRef_DUP(GETLOCAL(oparg)); + stack_pointer[0] = value; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + break; + } + + case _LOAD_FAST_TEMP_3: { + _PyStackRef value; + oparg = 3; + assert(oparg == CURRENT_OPARG()); + assert(!PyStackRef_IsNull(GETLOCAL(oparg))); + value = PyStackRef_DUP(GETLOCAL(oparg)); + stack_pointer[0] = value; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + break; + } + + case _LOAD_FAST_TEMP_4: { + _PyStackRef value; + oparg = 4; + assert(oparg == CURRENT_OPARG()); + assert(!PyStackRef_IsNull(GETLOCAL(oparg))); + value = PyStackRef_DUP(GETLOCAL(oparg)); + stack_pointer[0] = value; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + break; + } + + case _LOAD_FAST_TEMP_5: { + _PyStackRef value; + oparg = 5; + assert(oparg == CURRENT_OPARG()); + assert(!PyStackRef_IsNull(GETLOCAL(oparg))); + value = PyStackRef_DUP(GETLOCAL(oparg)); + stack_pointer[0] = value; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + break; + } + + case _LOAD_FAST_TEMP_6: { + _PyStackRef value; + oparg = 6; + assert(oparg == CURRENT_OPARG()); + assert(!PyStackRef_IsNull(GETLOCAL(oparg))); + value = PyStackRef_DUP(GETLOCAL(oparg)); + stack_pointer[0] = value; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + break; + } + + case _LOAD_FAST_TEMP_7: { + _PyStackRef value; + oparg = 7; + assert(oparg == CURRENT_OPARG()); + assert(!PyStackRef_IsNull(GETLOCAL(oparg))); + value = PyStackRef_DUP(GETLOCAL(oparg)); + stack_pointer[0] = value; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + break; + } + + case _LOAD_FAST_TEMP: { _PyStackRef value; oparg = CURRENT_OPARG(); assert(!PyStackRef_IsNull(GETLOCAL(oparg))); diff --git a/Python/flowgraph.c b/Python/flowgraph.c index c4fa7a500ccabb..0d6579911f2d67 100644 --- a/Python/flowgraph.c +++ b/Python/flowgraph.c @@ -1994,7 +1994,7 @@ scan_block_for_locals(basicblock *b, basicblock ***sp) unsafe_mask &= ~bit; break; case LOAD_FAST: - case LOAD_FAST_DEFERRED: + case LOAD_FAST_TEMP: if (unsafe_mask & bit) { instr->i_opcode = LOAD_FAST_CHECK; } @@ -2046,6 +2046,7 @@ fast_scan_many_locals(basicblock *entryblock, int nlocals) states[arg - 64] = blocknum; break; case LOAD_FAST: + case LOAD_FAST_TEMP: if (states[arg - 64] != blocknum) { instr->i_opcode = LOAD_FAST_CHECK; } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index f1095edc00b1d5..64fd2fb5fbd75d 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -5567,19 +5567,6 @@ DISPATCH(); } - TARGET(LOAD_FAST_DEFERRED) { - frame->instr_ptr = next_instr; - next_instr += 1; - INSTRUCTION_STATS(LOAD_FAST_DEFERRED); - _PyStackRef value; - assert(!PyStackRef_IsNull(GETLOCAL(oparg))); - value = PyStackRef_DUP(GETLOCAL(oparg)); - stack_pointer[0] = value; - stack_pointer += 1; - assert(WITHIN_STACK_BOUNDS()); - DISPATCH(); - } - TARGET(LOAD_FAST_LOAD_FAST) { frame->instr_ptr = next_instr; next_instr += 1; @@ -5597,6 +5584,19 @@ DISPATCH(); } + TARGET(LOAD_FAST_TEMP) { + frame->instr_ptr = next_instr; + next_instr += 1; + INSTRUCTION_STATS(LOAD_FAST_TEMP); + _PyStackRef value; + assert(!PyStackRef_IsNull(GETLOCAL(oparg))); + value = PyStackRef_DUP(GETLOCAL(oparg)); + stack_pointer[0] = value; + stack_pointer += 1; + assert(WITHIN_STACK_BOUNDS()); + DISPATCH(); + } + TARGET(LOAD_FROM_DICT_OR_DEREF) { frame->instr_ptr = next_instr; next_instr += 1; diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h index 8f48a94d19ee9f..ff59e2441b7126 100644 --- a/Python/opcode_targets.h +++ b/Python/opcode_targets.h @@ -83,8 +83,8 @@ static void *opcode_targets[256] = { &&TARGET_LOAD_FAST, &&TARGET_LOAD_FAST_AND_CLEAR, &&TARGET_LOAD_FAST_CHECK, - &&TARGET_LOAD_FAST_DEFERRED, &&TARGET_LOAD_FAST_LOAD_FAST, + &&TARGET_LOAD_FAST_TEMP, &&TARGET_LOAD_FROM_DICT_OR_DEREF, &&TARGET_LOAD_FROM_DICT_OR_GLOBALS, &&TARGET_LOAD_GLOBAL, diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index b3341e502e0a1a..dc69c2282c4ad1 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -45,7 +45,7 @@ break; } - case _LOAD_FAST_DEFERRED: { + case _LOAD_FAST_TEMP: { _Py_UopsSymbol *value; value = sym_new_not_null(ctx); stack_pointer[0] = value;