mirror of
https://github.com/python/cpython.git
synced 2025-08-25 03:04:55 +00:00
GH-131729: Code-gen better liveness analysis (GH-131732)
* Rename 'defined' attribute to 'in_local' to more accurately reflect how it is used * Make death of variables explicit even for array variables. * Convert in_memory from boolean to stack offset * Don't apply liveness analysis to optimizer generated code * Fix RETURN_VALUE in optimizer
This commit is contained in:
parent
b9ca438daa
commit
1b8bb1ed0c
12 changed files with 344 additions and 399 deletions
|
@ -1927,6 +1927,7 @@ dummy_func(
|
|||
PyStackRef_CLOSE(value);
|
||||
}
|
||||
}
|
||||
DEAD(values);
|
||||
if (err) {
|
||||
Py_DECREF(set_o);
|
||||
ERROR_IF(true, error);
|
||||
|
@ -3583,15 +3584,15 @@ dummy_func(
|
|||
#endif /* ENABLE_SPECIALIZATION_FT */
|
||||
}
|
||||
|
||||
op(_MAYBE_EXPAND_METHOD, (callable[1], self_or_null[1], args[oparg] -- func[1], maybe_self[1], args[oparg])) {
|
||||
op(_MAYBE_EXPAND_METHOD, (callable[1], self_or_null[1], args[oparg] -- callable[1], self_or_null[1], args[oparg])) {
|
||||
(void)args;
|
||||
if (PyStackRef_TYPE(callable[0]) == &PyMethod_Type && PyStackRef_IsNull(self_or_null[0])) {
|
||||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
|
||||
PyObject *self = ((PyMethodObject *)callable_o)->im_self;
|
||||
maybe_self[0] = PyStackRef_FromPyObjectNew(self);
|
||||
self_or_null[0] = PyStackRef_FromPyObjectNew(self);
|
||||
PyObject *method = ((PyMethodObject *)callable_o)->im_func;
|
||||
_PyStackRef temp = callable[0];
|
||||
func[0] = PyStackRef_FromPyObjectNew(method);
|
||||
callable[0] = PyStackRef_FromPyObjectNew(method);
|
||||
PyStackRef_CLOSE(temp);
|
||||
}
|
||||
}
|
||||
|
@ -3618,6 +3619,9 @@ dummy_func(
|
|||
tstate, callable[0], locals,
|
||||
arguments, total_args, NULL, frame
|
||||
);
|
||||
DEAD(args);
|
||||
DEAD(self_or_null);
|
||||
DEAD(callable);
|
||||
// Manipulate stack directly since we leave using DISPATCH_INLINED().
|
||||
SYNC_SP();
|
||||
// The frame has stolen all the arguments from the stack,
|
||||
|
@ -3950,10 +3954,10 @@ dummy_func(
|
|||
_CALL_TUPLE_1 +
|
||||
_CHECK_PERIODIC;
|
||||
|
||||
op(_CHECK_AND_ALLOCATE_OBJECT, (type_version/2, callable[1], null[1], args[oparg] -- init[1], self[1], args[oparg])) {
|
||||
op(_CHECK_AND_ALLOCATE_OBJECT, (type_version/2, callable[1], self_or_null[1], args[oparg] -- callable[1], self_or_null[1], args[oparg])) {
|
||||
(void)args;
|
||||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
|
||||
DEOPT_IF(!PyStackRef_IsNull(null[0]));
|
||||
DEOPT_IF(!PyStackRef_IsNull(self_or_null[0]));
|
||||
DEOPT_IF(!PyType_Check(callable_o));
|
||||
PyTypeObject *tp = (PyTypeObject *)callable_o;
|
||||
DEOPT_IF(FT_ATOMIC_LOAD_UINT32_RELAXED(tp->tp_version_tag) != type_version);
|
||||
|
@ -3969,9 +3973,9 @@ dummy_func(
|
|||
if (self_o == NULL) {
|
||||
ERROR_NO_POP();
|
||||
}
|
||||
self[0] = PyStackRef_FromPyObjectSteal(self_o);
|
||||
self_or_null[0] = PyStackRef_FromPyObjectSteal(self_o);
|
||||
_PyStackRef temp = callable[0];
|
||||
init[0] = PyStackRef_FromPyObjectNew(init_func);
|
||||
callable[0] = PyStackRef_FromPyObjectNew(init_func);
|
||||
PyStackRef_CLOSE(temp);
|
||||
}
|
||||
|
||||
|
@ -3982,10 +3986,11 @@ dummy_func(
|
|||
assert(_PyFrame_GetBytecode(shim)[1].op.code == RETURN_VALUE);
|
||||
/* Push self onto stack of shim */
|
||||
shim->localsplus[0] = PyStackRef_DUP(self[0]);
|
||||
DEAD(init);
|
||||
DEAD(self);
|
||||
_PyInterpreterFrame *temp = _PyEvalFramePushAndInit(
|
||||
tstate, init[0], NULL, args-1, oparg+1, NULL, shim);
|
||||
DEAD(init);
|
||||
DEAD(self);
|
||||
DEAD(args);
|
||||
SYNC_SP();
|
||||
if (temp == NULL) {
|
||||
_PyEval_FrameClearAndPop(tstate, shim);
|
||||
|
@ -4187,9 +4192,9 @@ dummy_func(
|
|||
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||
}
|
||||
|
||||
inst(CALL_ISINSTANCE, (unused/1, unused/2, callable[1], self_or_null[1], args[oparg] -- res)) {
|
||||
inst(CALL_ISINSTANCE, (unused/1, unused/2, callable, self_or_null[1], args[oparg] -- res)) {
|
||||
/* isinstance(o, o2) */
|
||||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
|
||||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable);
|
||||
|
||||
int total_args = oparg;
|
||||
_PyStackRef *arguments = args;
|
||||
|
@ -4420,15 +4425,15 @@ dummy_func(
|
|||
ERROR_IF(err, error);
|
||||
}
|
||||
|
||||
op(_MAYBE_EXPAND_METHOD_KW, (callable[1], self_or_null[1], args[oparg], kwnames_in -- func[1], maybe_self[1], args[oparg], kwnames_out)) {
|
||||
op(_MAYBE_EXPAND_METHOD_KW, (callable[1], self_or_null[1], args[oparg], kwnames_in -- callable[1], self_or_null[1], args[oparg], kwnames_out)) {
|
||||
(void)args;
|
||||
if (PyStackRef_TYPE(callable[0]) == &PyMethod_Type && PyStackRef_IsNull(self_or_null[0])) {
|
||||
PyObject *callable_o = PyStackRef_AsPyObjectBorrow(callable[0]);
|
||||
PyObject *self = ((PyMethodObject *)callable_o)->im_self;
|
||||
maybe_self[0] = PyStackRef_FromPyObjectNew(self);
|
||||
self_or_null[0] = PyStackRef_FromPyObjectNew(self);
|
||||
PyObject *method = ((PyMethodObject *)callable_o)->im_func;
|
||||
_PyStackRef temp = callable[0];
|
||||
func[0] = PyStackRef_FromPyObjectNew(method);
|
||||
callable[0] = PyStackRef_FromPyObjectNew(method);
|
||||
PyStackRef_CLOSE(temp);
|
||||
}
|
||||
kwnames_out = kwnames_in;
|
||||
|
@ -4458,6 +4463,9 @@ dummy_func(
|
|||
tstate, callable[0], locals,
|
||||
arguments, positional_args, kwnames_o, frame
|
||||
);
|
||||
DEAD(args);
|
||||
DEAD(self_or_null);
|
||||
DEAD(callable);
|
||||
PyStackRef_CLOSE(kwnames);
|
||||
// Sync stack explicitly since we leave using DISPATCH_INLINED().
|
||||
SYNC_SP();
|
||||
|
@ -4525,6 +4533,9 @@ dummy_func(
|
|||
PyStackRef_CLOSE(kwnames);
|
||||
// The frame has stolen all the arguments from the stack,
|
||||
// so there is no need to clean them up.
|
||||
DEAD(args);
|
||||
DEAD(self_or_null);
|
||||
DEAD(callable);
|
||||
SYNC_SP();
|
||||
ERROR_IF(temp == NULL, error);
|
||||
new_frame = temp;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue