mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
GH-138378: Move globals-to-consts pass into main optimizer pass (GH-138379)
This commit is contained in:
parent
d22b25081b
commit
3b83257366
12 changed files with 486 additions and 490 deletions
|
|
@ -470,6 +470,7 @@ dummy_func(void) {
|
|||
}
|
||||
|
||||
op(_LOAD_CONST, (-- value)) {
|
||||
PyCodeObject *co = get_current_code_object(ctx);
|
||||
PyObject *val = PyTuple_GET_ITEM(co->co_consts, oparg);
|
||||
REPLACE_OP(this_instr, _LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)val);
|
||||
value = PyJitRef_Borrow(sym_new_const(ctx, val));
|
||||
|
|
@ -606,7 +607,7 @@ dummy_func(void) {
|
|||
op(_LOAD_ATTR_CLASS, (descr/4, owner -- attr)) {
|
||||
(void)descr;
|
||||
PyTypeObject *type = (PyTypeObject *)sym_get_const(ctx, owner);
|
||||
PyObject *name = PyTuple_GET_ITEM(co->co_names, oparg >> 1);
|
||||
PyObject *name = get_co_name(ctx, oparg >> 1);
|
||||
attr = lookup_attr(ctx, this_instr, type, name,
|
||||
_POP_TOP_LOAD_CONST_INLINE_BORROW,
|
||||
_POP_TOP_LOAD_CONST_INLINE);
|
||||
|
|
@ -615,7 +616,7 @@ dummy_func(void) {
|
|||
op(_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, (descr/4, owner -- attr)) {
|
||||
(void)descr;
|
||||
PyTypeObject *type = sym_get_type(owner);
|
||||
PyObject *name = PyTuple_GET_ITEM(co->co_names, oparg >> 1);
|
||||
PyObject *name = get_co_name(ctx, oparg >> 1);
|
||||
attr = lookup_attr(ctx, this_instr, type, name,
|
||||
_POP_TOP_LOAD_CONST_INLINE_BORROW,
|
||||
_POP_TOP_LOAD_CONST_INLINE);
|
||||
|
|
@ -624,7 +625,7 @@ dummy_func(void) {
|
|||
op(_LOAD_ATTR_NONDESCRIPTOR_NO_DICT, (descr/4, owner -- attr)) {
|
||||
(void)descr;
|
||||
PyTypeObject *type = sym_get_type(owner);
|
||||
PyObject *name = PyTuple_GET_ITEM(co->co_names, oparg >> 1);
|
||||
PyObject *name = get_co_name(ctx, oparg >> 1);
|
||||
attr = lookup_attr(ctx, this_instr, type, name,
|
||||
_POP_TOP_LOAD_CONST_INLINE_BORROW,
|
||||
_POP_TOP_LOAD_CONST_INLINE);
|
||||
|
|
@ -633,7 +634,7 @@ dummy_func(void) {
|
|||
op(_LOAD_ATTR_METHOD_WITH_VALUES, (descr/4, owner -- attr, self)) {
|
||||
(void)descr;
|
||||
PyTypeObject *type = sym_get_type(owner);
|
||||
PyObject *name = PyTuple_GET_ITEM(co->co_names, oparg >> 1);
|
||||
PyObject *name = get_co_name(ctx, oparg >> 1);
|
||||
attr = lookup_attr(ctx, this_instr, type, name,
|
||||
_LOAD_CONST_UNDER_INLINE_BORROW,
|
||||
_LOAD_CONST_UNDER_INLINE);
|
||||
|
|
@ -643,7 +644,7 @@ dummy_func(void) {
|
|||
op(_LOAD_ATTR_METHOD_NO_DICT, (descr/4, owner -- attr, self)) {
|
||||
(void)descr;
|
||||
PyTypeObject *type = sym_get_type(owner);
|
||||
PyObject *name = PyTuple_GET_ITEM(co->co_names, oparg >> 1);
|
||||
PyObject *name = get_co_name(ctx, oparg >> 1);
|
||||
attr = lookup_attr(ctx, this_instr, type, name,
|
||||
_LOAD_CONST_UNDER_INLINE_BORROW,
|
||||
_LOAD_CONST_UNDER_INLINE);
|
||||
|
|
@ -653,7 +654,7 @@ dummy_func(void) {
|
|||
op(_LOAD_ATTR_METHOD_LAZY_DICT, (descr/4, owner -- attr, self)) {
|
||||
(void)descr;
|
||||
PyTypeObject *type = sym_get_type(owner);
|
||||
PyObject *name = PyTuple_GET_ITEM(co->co_names, oparg >> 1);
|
||||
PyObject *name = get_co_name(ctx, oparg >> 1);
|
||||
attr = lookup_attr(ctx, this_instr, type, name,
|
||||
_LOAD_CONST_UNDER_INLINE_BORROW,
|
||||
_LOAD_CONST_UNDER_INLINE);
|
||||
|
|
@ -711,15 +712,13 @@ dummy_func(void) {
|
|||
op(_INIT_CALL_PY_EXACT_ARGS, (callable, self_or_null, args[oparg] -- new_frame)) {
|
||||
int argcount = oparg;
|
||||
|
||||
PyCodeObject *co = NULL;
|
||||
assert((this_instr + 2)->opcode == _PUSH_FRAME);
|
||||
co = get_code_with_logging((this_instr + 2));
|
||||
PyCodeObject *co = get_code_with_logging((this_instr + 2));
|
||||
if (co == NULL) {
|
||||
ctx->done = true;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
assert(!PyJitRef_IsNull(self_or_null));
|
||||
assert(args != NULL);
|
||||
if (sym_is_not_null(self_or_null)) {
|
||||
|
|
@ -742,9 +741,8 @@ dummy_func(void) {
|
|||
}
|
||||
|
||||
op(_PY_FRAME_GENERAL, (callable, self_or_null, args[oparg] -- new_frame)) {
|
||||
PyCodeObject *co = NULL;
|
||||
assert((this_instr + 2)->opcode == _PUSH_FRAME);
|
||||
co = get_code_with_logging((this_instr + 2));
|
||||
PyCodeObject *co = get_code_with_logging((this_instr + 2));
|
||||
if (co == NULL) {
|
||||
ctx->done = true;
|
||||
break;
|
||||
|
|
@ -775,6 +773,7 @@ dummy_func(void) {
|
|||
JitOptRef temp = PyJitRef_StripReferenceInfo(retval);
|
||||
DEAD(retval);
|
||||
SAVE_STACK();
|
||||
PyCodeObject *co = get_current_code_object(ctx);
|
||||
ctx->frame->stack_pointer = stack_pointer;
|
||||
frame_pop(ctx);
|
||||
stack_pointer = ctx->frame->stack_pointer;
|
||||
|
|
@ -787,17 +786,13 @@ dummy_func(void) {
|
|||
assert(framesize <= curr_space);
|
||||
curr_space -= framesize;
|
||||
|
||||
co = get_code(this_instr);
|
||||
if (co == NULL) {
|
||||
// might be impossible, but bailing is still safe
|
||||
ctx->done = true;
|
||||
}
|
||||
RELOAD_STACK();
|
||||
res = temp;
|
||||
}
|
||||
|
||||
op(_RETURN_GENERATOR, ( -- res)) {
|
||||
SYNC_SP();
|
||||
PyCodeObject *co = get_current_code_object(ctx);
|
||||
ctx->frame->stack_pointer = stack_pointer;
|
||||
frame_pop(ctx);
|
||||
stack_pointer = ctx->frame->stack_pointer;
|
||||
|
|
@ -810,12 +805,6 @@ dummy_func(void) {
|
|||
assert(framesize > 0);
|
||||
assert(framesize <= curr_space);
|
||||
curr_space -= framesize;
|
||||
|
||||
co = get_code(this_instr);
|
||||
if (co == NULL) {
|
||||
// might be impossible, but bailing is still safe
|
||||
ctx->done = true;
|
||||
}
|
||||
}
|
||||
|
||||
op(_YIELD_VALUE, (unused -- value)) {
|
||||
|
|
@ -863,13 +852,16 @@ dummy_func(void) {
|
|||
ctx->frame = (_Py_UOpsAbstractFrame *)PyJitRef_Unwrap(new_frame);
|
||||
ctx->curr_frame_depth++;
|
||||
stack_pointer = ctx->frame->stack_pointer;
|
||||
co = get_code(this_instr);
|
||||
if (co == NULL) {
|
||||
// should be about to _EXIT_TRACE anyway
|
||||
uint64_t operand = this_instr->operand0;
|
||||
if (operand == 0 || (operand & 1)) {
|
||||
// It's either a code object or NULL
|
||||
ctx->done = true;
|
||||
break;
|
||||
}
|
||||
|
||||
PyFunctionObject *func = (PyFunctionObject *)operand;
|
||||
PyCodeObject *co = (PyCodeObject *)func->func_code;
|
||||
assert(PyFunction_Check(func));
|
||||
ctx->frame->func = func;
|
||||
/* Stack space handling */
|
||||
int framesize = co->co_framesize;
|
||||
assert(framesize > 0);
|
||||
|
|
@ -1250,6 +1242,96 @@ dummy_func(void) {
|
|||
}
|
||||
}
|
||||
|
||||
op(_GUARD_GLOBALS_VERSION, (version/1 --)) {
|
||||
if (ctx->frame->func != NULL) {
|
||||
PyObject *globals = ctx->frame->func->func_globals;
|
||||
if (incorrect_keys(globals, version)) {
|
||||
OPT_STAT_INC(remove_globals_incorrect_keys);
|
||||
ctx->done = true;
|
||||
}
|
||||
else if (get_mutations(globals) >= _Py_MAX_ALLOWED_GLOBALS_MODIFICATIONS) {
|
||||
/* Do nothing */
|
||||
}
|
||||
else {
|
||||
if (!ctx->frame->globals_watched) {
|
||||
PyDict_Watch(GLOBALS_WATCHER_ID, globals);
|
||||
_Py_BloomFilter_Add(dependencies, globals);
|
||||
ctx->frame->globals_watched = true;
|
||||
}
|
||||
if (ctx->frame->globals_checked_version == version) {
|
||||
REPLACE_OP(this_instr, _NOP, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
ctx->frame->globals_checked_version = version;
|
||||
}
|
||||
|
||||
op(_LOAD_GLOBAL_BUILTINS, (version/1, index/1 -- res)) {
|
||||
(void)version;
|
||||
(void)index;
|
||||
PyObject *cnst = NULL;
|
||||
PyInterpreterState *interp = _PyInterpreterState_GET();
|
||||
PyObject *builtins = interp->builtins;
|
||||
if (incorrect_keys(builtins, version)) {
|
||||
OPT_STAT_INC(remove_globals_incorrect_keys);
|
||||
ctx->done = true;
|
||||
}
|
||||
else if (interp->rare_events.builtin_dict >= _Py_MAX_ALLOWED_BUILTINS_MODIFICATIONS) {
|
||||
/* Do nothing */
|
||||
}
|
||||
else {
|
||||
if (!ctx->builtins_watched) {
|
||||
PyDict_Watch(BUILTINS_WATCHER_ID, builtins);
|
||||
ctx->builtins_watched = true;
|
||||
}
|
||||
if (ctx->frame->globals_checked_version != 0 && ctx->frame->globals_watched) {
|
||||
cnst = convert_global_to_const(this_instr, builtins, false);
|
||||
}
|
||||
}
|
||||
if (cnst == NULL) {
|
||||
res = sym_new_not_null(ctx);
|
||||
}
|
||||
else {
|
||||
res = sym_new_const(ctx, cnst);
|
||||
}
|
||||
}
|
||||
|
||||
op(_LOAD_GLOBAL_MODULE, (version/1, unused/1, index/1 -- res)) {
|
||||
(void)index;
|
||||
PyObject *cnst = NULL;
|
||||
if (ctx->frame->func != NULL) {
|
||||
PyObject *globals = ctx->frame->func->func_globals;
|
||||
if (incorrect_keys(globals, version)) {
|
||||
OPT_STAT_INC(remove_globals_incorrect_keys);
|
||||
ctx->done = true;
|
||||
}
|
||||
else if (get_mutations(globals) >= _Py_MAX_ALLOWED_GLOBALS_MODIFICATIONS) {
|
||||
/* Do nothing */
|
||||
}
|
||||
else {
|
||||
if (!ctx->frame->globals_watched) {
|
||||
PyDict_Watch(GLOBALS_WATCHER_ID, globals);
|
||||
_Py_BloomFilter_Add(dependencies, globals);
|
||||
ctx->frame->globals_watched = true;
|
||||
}
|
||||
if (ctx->frame->globals_checked_version != version && this_instr[-1].opcode == _NOP) {
|
||||
REPLACE_OP(this_instr-1, _GUARD_GLOBALS_VERSION, 0, version);
|
||||
ctx->frame->globals_checked_version = version;
|
||||
}
|
||||
if (ctx->frame->globals_checked_version == version) {
|
||||
cnst = convert_global_to_const(this_instr, globals, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cnst == NULL) {
|
||||
res = sym_new_not_null(ctx);
|
||||
}
|
||||
else {
|
||||
res = sym_new_const(ctx, cnst);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// END BYTECODES //
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue