From 370f8065b5c9e74a2a3abf29b83bdde861628240 Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Thu, 22 Feb 2024 01:27:45 +0800 Subject: [PATCH 1/3] More robust method handling in redundancy eliminator --- Python/optimizer_analysis.c | 7 ++++++ .../tier2_redundancy_eliminator_bytecodes.c | 24 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c index 5d2df9aca4e77f..d7f54ab383ac42 100644 --- a/Python/optimizer_analysis.c +++ b/Python/optimizer_analysis.c @@ -301,6 +301,7 @@ sym_new_known_notnull(_Py_UOpsAbstractInterpContext *ctx) if (res == NULL) { return NULL; } + sym_set_flag(res, KNOWN); sym_set_flag(res, NOT_NULL); return res; } @@ -596,6 +597,12 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer, OUT_OF_SPACE_IF_NULL(null = sym_new_null(ctx)); \ } while (0); +#define _LOAD_ATTR_NOT_NULL_SELF \ + do { \ + OUT_OF_SPACE_IF_NULL(attr = sym_new_known_notnull(ctx)); \ + OUT_OF_SPACE_IF_NULL(self = sym_new_known_notnull(ctx)); \ + } while (0); + /* 1 for success, 0 for not ready, cannot error at the moment. */ static int diff --git a/Python/tier2_redundancy_eliminator_bytecodes.c b/Python/tier2_redundancy_eliminator_bytecodes.c index e9b556d16c3702..784fe035306cb8 100644 --- a/Python/tier2_redundancy_eliminator_bytecodes.c +++ b/Python/tier2_redundancy_eliminator_bytecodes.c @@ -261,6 +261,30 @@ dummy_func(void) { (void)owner; } + op(_LOAD_ATTR_METHOD_WITH_VALUES, (descr/4, owner -- attr, self if (oparg & 1))) { + _LOAD_ATTR_NOT_NULL_SELF + (void)descr; + (void)owner; + } + + op(_LOAD_ATTR_METHOD_NO_DICT, (descr/4, owner -- attr, self if (oparg & 1))) { + _LOAD_ATTR_NOT_NULL_SELF + (void)descr; + (void)owner; + } + + op(_LOAD_ATTR_METHOD_LAZY_DICT, (descr/4, owner -- attr, self if (oparg & 1))) { + _LOAD_ATTR_NOT_NULL_SELF + (void)descr; + (void)owner; + } + + op(_INIT_CALL_BOUND_METHOD_EXACT_ARGS, (callable, unused, unused[oparg] -- attr, self, unused[oparg])) { + _LOAD_ATTR_NOT_NULL_SELF + (void)callable; + } + + op(_CHECK_FUNCTION_EXACT_ARGS, (func_version/2, callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) { sym_set_type(callable, &PyFunction_Type); (void)self_or_null; From 453c934f739b7e2777e6089b967b549d0525c0aa Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Thu, 22 Feb 2024 01:33:19 +0800 Subject: [PATCH 2/3] Regenerate cases --- Python/tier2_redundancy_eliminator_cases.c.h | 54 +++++++++++--------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/Python/tier2_redundancy_eliminator_cases.c.h b/Python/tier2_redundancy_eliminator_cases.c.h index f41fe328195b4d..3c1e1b4bc1e33c 100644 --- a/Python/tier2_redundancy_eliminator_cases.c.h +++ b/Python/tier2_redundancy_eliminator_cases.c.h @@ -1267,28 +1267,32 @@ } case _LOAD_ATTR_METHOD_WITH_VALUES: { + _Py_UOpsSymType *owner; _Py_UOpsSymType *attr; _Py_UOpsSymType *self = NULL; - attr = sym_new_unknown(ctx); - if (attr == NULL) goto out_of_space; - self = sym_new_unknown(ctx); - if (self == NULL) goto out_of_space; + owner = stack_pointer[-1]; + PyObject *descr = (PyObject *)this_instr->operand; + _LOAD_ATTR_NOT_NULL_SELF + (void)descr; + (void)owner; stack_pointer[-1] = attr; - stack_pointer[0] = self; - stack_pointer += 1; + if (oparg & 1) stack_pointer[0] = self; + stack_pointer += (oparg & 1); break; } case _LOAD_ATTR_METHOD_NO_DICT: { + _Py_UOpsSymType *owner; _Py_UOpsSymType *attr; _Py_UOpsSymType *self = NULL; - attr = sym_new_unknown(ctx); - if (attr == NULL) goto out_of_space; - self = sym_new_unknown(ctx); - if (self == NULL) goto out_of_space; + owner = stack_pointer[-1]; + PyObject *descr = (PyObject *)this_instr->operand; + _LOAD_ATTR_NOT_NULL_SELF + (void)descr; + (void)owner; stack_pointer[-1] = attr; - stack_pointer[0] = self; - stack_pointer += 1; + if (oparg & 1) stack_pointer[0] = self; + stack_pointer += (oparg & 1); break; } @@ -1313,15 +1317,17 @@ } case _LOAD_ATTR_METHOD_LAZY_DICT: { + _Py_UOpsSymType *owner; _Py_UOpsSymType *attr; _Py_UOpsSymType *self = NULL; - attr = sym_new_unknown(ctx); - if (attr == NULL) goto out_of_space; - self = sym_new_unknown(ctx); - if (self == NULL) goto out_of_space; + owner = stack_pointer[-1]; + PyObject *descr = (PyObject *)this_instr->operand; + _LOAD_ATTR_NOT_NULL_SELF + (void)descr; + (void)owner; stack_pointer[-1] = attr; - stack_pointer[0] = self; - stack_pointer += 1; + if (oparg & 1) stack_pointer[0] = self; + stack_pointer += (oparg & 1); break; } @@ -1340,13 +1346,13 @@ } case _INIT_CALL_BOUND_METHOD_EXACT_ARGS: { - _Py_UOpsSymType *func; + _Py_UOpsSymType *callable; + _Py_UOpsSymType *attr; _Py_UOpsSymType *self; - func = sym_new_unknown(ctx); - if (func == NULL) goto out_of_space; - self = sym_new_unknown(ctx); - if (self == NULL) goto out_of_space; - stack_pointer[-2 - oparg] = func; + callable = stack_pointer[-2 - oparg]; + _LOAD_ATTR_NOT_NULL_SELF + (void)callable; + stack_pointer[-2 - oparg] = attr; stack_pointer[-1 - oparg] = self; break; } From a236d58036b21630c2449970fd0146a3319e2dee Mon Sep 17 00:00:00 2001 From: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Date: Thu, 22 Feb 2024 16:53:46 +0800 Subject: [PATCH 3/3] address review --- Python/optimizer_analysis.c | 6 ---- .../tier2_redundancy_eliminator_bytecodes.c | 27 +++++++------- Python/tier2_redundancy_eliminator_cases.c.h | 35 +++++++++---------- 3 files changed, 28 insertions(+), 40 deletions(-) diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c index d7f54ab383ac42..ee538f32e9e757 100644 --- a/Python/optimizer_analysis.c +++ b/Python/optimizer_analysis.c @@ -597,12 +597,6 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer, OUT_OF_SPACE_IF_NULL(null = sym_new_null(ctx)); \ } while (0); -#define _LOAD_ATTR_NOT_NULL_SELF \ - do { \ - OUT_OF_SPACE_IF_NULL(attr = sym_new_known_notnull(ctx)); \ - OUT_OF_SPACE_IF_NULL(self = sym_new_known_notnull(ctx)); \ - } while (0); - /* 1 for success, 0 for not ready, cannot error at the moment. */ static int diff --git a/Python/tier2_redundancy_eliminator_bytecodes.c b/Python/tier2_redundancy_eliminator_bytecodes.c index 784fe035306cb8..25c8756fbd73e9 100644 --- a/Python/tier2_redundancy_eliminator_bytecodes.c +++ b/Python/tier2_redundancy_eliminator_bytecodes.c @@ -261,27 +261,24 @@ dummy_func(void) { (void)owner; } - op(_LOAD_ATTR_METHOD_WITH_VALUES, (descr/4, owner -- attr, self if (oparg & 1))) { - _LOAD_ATTR_NOT_NULL_SELF - (void)descr; - (void)owner; + op(_LOAD_ATTR_METHOD_WITH_VALUES, (descr/4, owner -- attr, self if (1))) { + OUT_OF_SPACE_IF_NULL(attr = sym_new_known_notnull(ctx)); + OUT_OF_SPACE_IF_NULL(self = sym_new_known_notnull(ctx)); } - op(_LOAD_ATTR_METHOD_NO_DICT, (descr/4, owner -- attr, self if (oparg & 1))) { - _LOAD_ATTR_NOT_NULL_SELF - (void)descr; - (void)owner; + op(_LOAD_ATTR_METHOD_NO_DICT, (descr/4, owner -- attr, self if (1))) { + OUT_OF_SPACE_IF_NULL(attr = sym_new_known_notnull(ctx)); + OUT_OF_SPACE_IF_NULL(self = sym_new_known_notnull(ctx)); } - op(_LOAD_ATTR_METHOD_LAZY_DICT, (descr/4, owner -- attr, self if (oparg & 1))) { - _LOAD_ATTR_NOT_NULL_SELF - (void)descr; - (void)owner; + op(_LOAD_ATTR_METHOD_LAZY_DICT, (descr/4, owner -- attr, self if (1))) { + OUT_OF_SPACE_IF_NULL(attr = sym_new_known_notnull(ctx)); + OUT_OF_SPACE_IF_NULL(self = sym_new_known_notnull(ctx)); } - op(_INIT_CALL_BOUND_METHOD_EXACT_ARGS, (callable, unused, unused[oparg] -- attr, self, unused[oparg])) { - _LOAD_ATTR_NOT_NULL_SELF - (void)callable; + op(_INIT_CALL_BOUND_METHOD_EXACT_ARGS, (callable, unused, unused[oparg] -- func, self, unused[oparg])) { + OUT_OF_SPACE_IF_NULL(func = sym_new_known_notnull(ctx)); + OUT_OF_SPACE_IF_NULL(self = sym_new_known_notnull(ctx)); } diff --git a/Python/tier2_redundancy_eliminator_cases.c.h b/Python/tier2_redundancy_eliminator_cases.c.h index 3c1e1b4bc1e33c..a704454725da20 100644 --- a/Python/tier2_redundancy_eliminator_cases.c.h +++ b/Python/tier2_redundancy_eliminator_cases.c.h @@ -1272,12 +1272,11 @@ _Py_UOpsSymType *self = NULL; owner = stack_pointer[-1]; PyObject *descr = (PyObject *)this_instr->operand; - _LOAD_ATTR_NOT_NULL_SELF - (void)descr; - (void)owner; + OUT_OF_SPACE_IF_NULL(attr = sym_new_known_notnull(ctx)); + OUT_OF_SPACE_IF_NULL(self = sym_new_known_notnull(ctx)); stack_pointer[-1] = attr; - if (oparg & 1) stack_pointer[0] = self; - stack_pointer += (oparg & 1); + stack_pointer[0] = self; + stack_pointer += 1; break; } @@ -1287,12 +1286,11 @@ _Py_UOpsSymType *self = NULL; owner = stack_pointer[-1]; PyObject *descr = (PyObject *)this_instr->operand; - _LOAD_ATTR_NOT_NULL_SELF - (void)descr; - (void)owner; + OUT_OF_SPACE_IF_NULL(attr = sym_new_known_notnull(ctx)); + OUT_OF_SPACE_IF_NULL(self = sym_new_known_notnull(ctx)); stack_pointer[-1] = attr; - if (oparg & 1) stack_pointer[0] = self; - stack_pointer += (oparg & 1); + stack_pointer[0] = self; + stack_pointer += 1; break; } @@ -1322,12 +1320,11 @@ _Py_UOpsSymType *self = NULL; owner = stack_pointer[-1]; PyObject *descr = (PyObject *)this_instr->operand; - _LOAD_ATTR_NOT_NULL_SELF - (void)descr; - (void)owner; + OUT_OF_SPACE_IF_NULL(attr = sym_new_known_notnull(ctx)); + OUT_OF_SPACE_IF_NULL(self = sym_new_known_notnull(ctx)); stack_pointer[-1] = attr; - if (oparg & 1) stack_pointer[0] = self; - stack_pointer += (oparg & 1); + stack_pointer[0] = self; + stack_pointer += 1; break; } @@ -1347,12 +1344,12 @@ case _INIT_CALL_BOUND_METHOD_EXACT_ARGS: { _Py_UOpsSymType *callable; - _Py_UOpsSymType *attr; + _Py_UOpsSymType *func; _Py_UOpsSymType *self; callable = stack_pointer[-2 - oparg]; - _LOAD_ATTR_NOT_NULL_SELF - (void)callable; - stack_pointer[-2 - oparg] = attr; + OUT_OF_SPACE_IF_NULL(func = sym_new_known_notnull(ctx)); + OUT_OF_SPACE_IF_NULL(self = sym_new_known_notnull(ctx)); + stack_pointer[-2 - oparg] = func; stack_pointer[-1 - oparg] = self; break; }