From 10fbcd6c5dc25bfe14e02fd93ef93498a393860c Mon Sep 17 00:00:00 2001 From: Mark Shannon Date: Tue, 27 Feb 2024 10:51:26 +0000 Subject: GH-115816: Make tier2 optimizer symbols testable, and add a few tests. (GH-115953) --- Include/internal/pycore_optimizer.h | 85 +++++++ Lib/test/test_generated_cases.py | 4 +- Lib/test/test_optimizer.py | 7 + Makefile.pre.in | 1 + Modules/_testinternalcapi.c | 3 +- PCbuild/_freeze_module.vcxproj | 1 + PCbuild/_freeze_module.vcxproj.filters | 3 + PCbuild/pythoncore.vcxproj | 1 + PCbuild/pythoncore.vcxproj.filters | 3 + Python/optimizer_analysis.c | 343 +------------------------ Python/optimizer_bytecodes.c | 170 ++++++------- Python/optimizer_cases.c.h | 366 +++++++++++++-------------- Python/optimizer_symbols.c | 332 ++++++++++++++++++++++++ Tools/c-analyzer/cpython/ignored.tsv | 2 - Tools/cases_generator/optimizer_generator.py | 6 +- 15 files changed, 720 insertions(+), 607 deletions(-) create mode 100644 Python/optimizer_symbols.c diff --git a/Include/internal/pycore_optimizer.h b/Include/internal/pycore_optimizer.h index eee71c7..267cbf1 100644 --- a/Include/internal/pycore_optimizer.h +++ b/Include/internal/pycore_optimizer.h @@ -9,6 +9,7 @@ extern "C" { #endif #include "pycore_uop_ids.h" +#include // This is the length of the trace we project initially. #define UOP_MAX_TRACE_LENGTH 512 @@ -25,6 +26,90 @@ extern PyTypeObject _PyDefaultOptimizer_Type; extern PyTypeObject _PyUOpExecutor_Type; extern PyTypeObject _PyUOpOptimizer_Type; +/* Symbols */ + +struct _Py_UOpsSymType { + int flags; + PyTypeObject *typ; + // constant propagated value (might be NULL) + PyObject *const_val; +}; + +// Holds locals, stack, locals, stack ... co_consts (in that order) +#define MAX_ABSTRACT_INTERP_SIZE 4096 + +#define OVERALLOCATE_FACTOR 5 + +#define TY_ARENA_SIZE (UOP_MAX_TRACE_LENGTH * OVERALLOCATE_FACTOR) + +// Need extras for root frame and for overflow frame (see TRACE_STACK_PUSH()) +#define MAX_ABSTRACT_FRAME_DEPTH (TRACE_STACK_SIZE + 2) + +typedef struct _Py_UOpsSymType _Py_UOpsSymType; + +struct _Py_UOpsAbstractFrame { + // Max stacklen + int stack_len; + int locals_len; + + _Py_UOpsSymType **stack_pointer; + _Py_UOpsSymType **stack; + _Py_UOpsSymType **locals; +}; + +typedef struct _Py_UOpsAbstractFrame _Py_UOpsAbstractFrame; + +typedef struct ty_arena { + int ty_curr_number; + int ty_max_number; + _Py_UOpsSymType arena[TY_ARENA_SIZE]; +} ty_arena; + +struct _Py_UOpsAbstractInterpContext { + PyObject_HEAD + // The current "executing" frame. + _Py_UOpsAbstractFrame *frame; + _Py_UOpsAbstractFrame frames[MAX_ABSTRACT_FRAME_DEPTH]; + int curr_frame_depth; + + // Arena for the symbolic types. + ty_arena t_arena; + + _Py_UOpsSymType **n_consumed; + _Py_UOpsSymType **limit; + _Py_UOpsSymType *locals_and_stack[MAX_ABSTRACT_INTERP_SIZE]; +}; + +typedef struct _Py_UOpsAbstractInterpContext _Py_UOpsAbstractInterpContext; + +extern bool _Py_uop_sym_is_null(_Py_UOpsSymType *sym); +extern bool _Py_uop_sym_is_not_null(_Py_UOpsSymType *sym); +extern bool _Py_uop_sym_is_const(_Py_UOpsSymType *sym); +extern PyObject *_Py_uop_sym_get_const(_Py_UOpsSymType *sym); +extern _Py_UOpsSymType *_Py_uop_sym_new_unknown(_Py_UOpsAbstractInterpContext *ctx); +extern _Py_UOpsSymType *_Py_uop_sym_new_not_null(_Py_UOpsAbstractInterpContext *ctx); +extern _Py_UOpsSymType *_Py_uop_sym_new_type( + _Py_UOpsAbstractInterpContext *ctx, PyTypeObject *typ); +extern _Py_UOpsSymType *_Py_uop_sym_new_const(_Py_UOpsAbstractInterpContext *ctx, PyObject *const_val); +extern _Py_UOpsSymType *_Py_uop_sym_new_null(_Py_UOpsAbstractInterpContext *ctx); +extern bool _Py_uop_sym_matches_type(_Py_UOpsSymType *sym, PyTypeObject *typ); +extern void _Py_uop_sym_set_null(_Py_UOpsSymType *sym); +extern void _Py_uop_sym_set_type(_Py_UOpsSymType *sym, PyTypeObject *tp); + +extern int _Py_uop_abstractcontext_init(_Py_UOpsAbstractInterpContext *ctx); +extern void _Py_uop_abstractcontext_fini(_Py_UOpsAbstractInterpContext *ctx); + +extern _Py_UOpsAbstractFrame *_Py_uop_ctx_frame_new( + _Py_UOpsAbstractInterpContext *ctx, + PyCodeObject *co, + _Py_UOpsSymType **localsplus_start, + int n_locals_already_filled, + int curr_stackentries); +extern int _Py_uop_ctx_frame_pop(_Py_UOpsAbstractInterpContext *ctx); + +PyAPI_FUNC(PyObject *) +_Py_uop_symbols_test(PyObject *self, PyObject *ignored); + #ifdef __cplusplus } #endif diff --git a/Lib/test/test_generated_cases.py b/Lib/test/test_generated_cases.py index 6a55868..6017758 100644 --- a/Lib/test/test_generated_cases.py +++ b/Lib/test/test_generated_cases.py @@ -900,7 +900,7 @@ class TestGeneratedAbstractCases(unittest.TestCase): case OP2: { _Py_UOpsSymType *out; - out = sym_new_unknown(ctx); + out = _Py_uop_sym_new_unknown(ctx); if (out == NULL) goto out_of_space; stack_pointer[-1] = out; break; @@ -925,7 +925,7 @@ class TestGeneratedAbstractCases(unittest.TestCase): output = """ case OP: { _Py_UOpsSymType *out; - out = sym_new_unknown(ctx); + out = _Py_uop_sym_new_unknown(ctx); if (out == NULL) goto out_of_space; stack_pointer[-1] = out; break; diff --git a/Lib/test/test_optimizer.py b/Lib/test/test_optimizer.py index dfea8be..899a450 100644 --- a/Lib/test/test_optimizer.py +++ b/Lib/test/test_optimizer.py @@ -77,5 +77,12 @@ class TestRareEventCounters(unittest.TestCase): _testinternalcapi.get_rare_event_counters()["func_modification"] ) + +class TestOptimizerSymbols(unittest.TestCase): + + def test_optimizer_symbols(self): + _testinternalcapi.uop_symbols_test() + + if __name__ == "__main__": unittest.main() diff --git a/Makefile.pre.in b/Makefile.pre.in index e4c64ae..7533a49 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -446,6 +446,7 @@ PYTHON_OBJS= \ Python/object_stack.o \ Python/optimizer.o \ Python/optimizer_analysis.o \ + Python/optimizer_symbols.o \ Python/parking_lot.o \ Python/pathconfig.o \ Python/preconfig.o \ diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index 5b714ca..9c6970d 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -24,6 +24,7 @@ #include "pycore_interp.h" // _PyInterpreterState_GetConfigCopy() #include "pycore_long.h" // _PyLong_Sign() #include "pycore_object.h" // _PyObject_IsFreed() +#include "pycore_optimizer.h" // _Py_UOpsSymType, etc. #include "pycore_pathconfig.h" // _PyPathConfig_ClearGlobal() #include "pycore_pyerrors.h" // _PyErr_ChainExceptions1() #include "pycore_pystate.h" // _PyThreadState_GET() @@ -1677,7 +1678,6 @@ get_py_thread_id(PyObject *self, PyObject *Py_UNUSED(ignored)) } #endif - static PyMethodDef module_functions[] = { {"get_configs", get_configs, METH_NOARGS}, {"get_recursion_depth", get_recursion_depth, METH_NOARGS}, @@ -1747,6 +1747,7 @@ static PyMethodDef module_functions[] = { #ifdef Py_GIL_DISABLED {"py_thread_id", get_py_thread_id, METH_NOARGS}, #endif + {"uop_symbols_test", _Py_uop_symbols_test, METH_NOARGS}, {NULL, NULL} /* sentinel */ }; diff --git a/PCbuild/_freeze_module.vcxproj b/PCbuild/_freeze_module.vcxproj index 00ad3e2..3a8a417 100644 --- a/PCbuild/_freeze_module.vcxproj +++ b/PCbuild/_freeze_module.vcxproj @@ -235,6 +235,7 @@ + diff --git a/PCbuild/_freeze_module.vcxproj.filters b/PCbuild/_freeze_module.vcxproj.filters index aea5f73..5b34440 100644 --- a/PCbuild/_freeze_module.vcxproj.filters +++ b/PCbuild/_freeze_module.vcxproj.filters @@ -310,6 +310,9 @@ Source Files + + Python + Source Files diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index ef21f85..88a4a7c 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -601,6 +601,7 @@ + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index ffe93dc..27bd112 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -1382,6 +1382,9 @@ Python + + Python + Python diff --git a/Python/optimizer_analysis.c b/Python/optimizer_analysis.c index e975129..6b2aec8 100644 --- a/Python/optimizer_analysis.c +++ b/Python/optimizer_analysis.c @@ -33,16 +33,6 @@ #include #include -// Holds locals, stack, locals, stack ... co_consts (in that order) -#define MAX_ABSTRACT_INTERP_SIZE 4096 - -#define OVERALLOCATE_FACTOR 5 - -#define TY_ARENA_SIZE (UOP_MAX_TRACE_LENGTH * OVERALLOCATE_FACTOR) - -// Need extras for root frame and for overflow frame (see TRACE_STACK_PUSH()) -#define MAX_ABSTRACT_FRAME_DEPTH (TRACE_STACK_SIZE + 2) - #ifdef Py_DEBUG extern const char *_PyUOpName(int index); static const char *const DEBUG_ENV = "PYTHON_OPT_DEBUG"; @@ -61,318 +51,6 @@ #endif -// Flags for below. -#define KNOWN 1 << 0 -#define TRUE_CONST 1 << 1 -#define IS_NULL 1 << 2 -#define NOT_NULL 1 << 3 - -typedef struct { - int flags; - PyTypeObject *typ; - // constant propagated value (might be NULL) - PyObject *const_val; -} _Py_UOpsSymType; - - -typedef struct _Py_UOpsAbstractFrame { - // Max stacklen - int stack_len; - int locals_len; - - _Py_UOpsSymType **stack_pointer; - _Py_UOpsSymType **stack; - _Py_UOpsSymType **locals; -} _Py_UOpsAbstractFrame; - - -typedef struct ty_arena { - int ty_curr_number; - int ty_max_number; - _Py_UOpsSymType arena[TY_ARENA_SIZE]; -} ty_arena; - -// Tier 2 types meta interpreter -typedef struct _Py_UOpsAbstractInterpContext { - PyObject_HEAD - // The current "executing" frame. - _Py_UOpsAbstractFrame *frame; - _Py_UOpsAbstractFrame frames[MAX_ABSTRACT_FRAME_DEPTH]; - int curr_frame_depth; - - // Arena for the symbolic types. - ty_arena t_arena; - - _Py_UOpsSymType **n_consumed; - _Py_UOpsSymType **limit; - _Py_UOpsSymType *locals_and_stack[MAX_ABSTRACT_INTERP_SIZE]; -} _Py_UOpsAbstractInterpContext; - -static inline _Py_UOpsSymType* sym_new_unknown(_Py_UOpsAbstractInterpContext *ctx); - -// 0 on success, -1 on error. -static _Py_UOpsAbstractFrame * -ctx_frame_new( - _Py_UOpsAbstractInterpContext *ctx, - PyCodeObject *co, - _Py_UOpsSymType **localsplus_start, - int n_locals_already_filled, - int curr_stackentries -) -{ - assert(ctx->curr_frame_depth < MAX_ABSTRACT_FRAME_DEPTH); - _Py_UOpsAbstractFrame *frame = &ctx->frames[ctx->curr_frame_depth]; - - frame->stack_len = co->co_stacksize; - frame->locals_len = co->co_nlocalsplus; - - frame->locals = localsplus_start; - frame->stack = frame->locals + co->co_nlocalsplus; - frame->stack_pointer = frame->stack + curr_stackentries; - ctx->n_consumed = localsplus_start + (co->co_nlocalsplus + co->co_stacksize); - if (ctx->n_consumed >= ctx->limit) { - return NULL; - } - - - // Initialize with the initial state of all local variables - for (int i = n_locals_already_filled; i < co->co_nlocalsplus; i++) { - _Py_UOpsSymType *local = sym_new_unknown(ctx); - if (local == NULL) { - return NULL; - } - frame->locals[i] = local; - } - - - // Initialize the stack as well - for (int i = 0; i < curr_stackentries; i++) { - _Py_UOpsSymType *stackvar = sym_new_unknown(ctx); - if (stackvar == NULL) { - return NULL; - } - frame->stack[i] = stackvar; - } - - return frame; -} - -static void -abstractcontext_fini(_Py_UOpsAbstractInterpContext *ctx) -{ - if (ctx == NULL) { - return; - } - ctx->curr_frame_depth = 0; - int tys = ctx->t_arena.ty_curr_number; - for (int i = 0; i < tys; i++) { - Py_CLEAR(ctx->t_arena.arena[i].const_val); - } -} - -static int -abstractcontext_init( - _Py_UOpsAbstractInterpContext *ctx, - PyCodeObject *co, - int curr_stacklen, - int ir_entries -) -{ - ctx->limit = ctx->locals_and_stack + MAX_ABSTRACT_INTERP_SIZE; - ctx->n_consumed = ctx->locals_and_stack; -#ifdef Py_DEBUG // Aids debugging a little. There should never be NULL in the abstract interpreter. - for (int i = 0 ; i < MAX_ABSTRACT_INTERP_SIZE; i++) { - ctx->locals_and_stack[i] = NULL; - } -#endif - - // Setup the arena for sym expressions. - ctx->t_arena.ty_curr_number = 0; - ctx->t_arena.ty_max_number = TY_ARENA_SIZE; - - // Frame setup - ctx->curr_frame_depth = 0; - _Py_UOpsAbstractFrame *frame = ctx_frame_new(ctx, co, ctx->n_consumed, 0, curr_stacklen); - if (frame == NULL) { - return -1; - } - ctx->curr_frame_depth++; - ctx->frame = frame; - return 0; -} - - -static int -ctx_frame_pop( - _Py_UOpsAbstractInterpContext *ctx -) -{ - _Py_UOpsAbstractFrame *frame = ctx->frame; - - ctx->n_consumed = frame->locals; - ctx->curr_frame_depth--; - assert(ctx->curr_frame_depth >= 1); - ctx->frame = &ctx->frames[ctx->curr_frame_depth - 1]; - - return 0; -} - - -// Takes a borrowed reference to const_val, turns that into a strong reference. -static _Py_UOpsSymType* -sym_new(_Py_UOpsAbstractInterpContext *ctx, - PyObject *const_val) -{ - _Py_UOpsSymType *self = &ctx->t_arena.arena[ctx->t_arena.ty_curr_number]; - if (ctx->t_arena.ty_curr_number >= ctx->t_arena.ty_max_number) { - OPT_STAT_INC(optimizer_failure_reason_no_memory); - DPRINTF(1, "out of space for symbolic expression type\n"); - return NULL; - } - ctx->t_arena.ty_curr_number++; - self->const_val = NULL; - self->typ = NULL; - self->flags = 0; - - if (const_val != NULL) { - self->const_val = Py_NewRef(const_val); - } - - return self; -} - -static inline void -sym_set_flag(_Py_UOpsSymType *sym, int flag) -{ - sym->flags |= flag; -} - -static inline bool -sym_has_flag(_Py_UOpsSymType *sym, int flag) -{ - return (sym->flags & flag) != 0; -} - -static inline bool -sym_is_known(_Py_UOpsSymType *sym) -{ - return sym_has_flag(sym, KNOWN); -} - -static inline bool -sym_is_not_null(_Py_UOpsSymType *sym) -{ - return (sym->flags & (IS_NULL | NOT_NULL)) == NOT_NULL; -} - -static inline bool -sym_is_null(_Py_UOpsSymType *sym) -{ - return (sym->flags & (IS_NULL | NOT_NULL)) == IS_NULL; -} - -static inline bool -sym_is_const(_Py_UOpsSymType *sym) -{ - return (sym->flags & TRUE_CONST) != 0; -} - -static inline PyObject * -sym_get_const(_Py_UOpsSymType *sym) -{ - assert(sym_is_const(sym)); - assert(sym->const_val); - return sym->const_val; -} - -static inline void -sym_set_type(_Py_UOpsSymType *sym, PyTypeObject *tp) -{ - assert(PyType_Check(tp)); - sym->typ = tp; - sym_set_flag(sym, KNOWN); - sym_set_flag(sym, NOT_NULL); -} - -static inline void -sym_set_null(_Py_UOpsSymType *sym) -{ - sym_set_flag(sym, IS_NULL); - sym_set_flag(sym, KNOWN); -} - - -static inline _Py_UOpsSymType* -sym_new_unknown(_Py_UOpsAbstractInterpContext *ctx) -{ - return sym_new(ctx,NULL); -} - -static inline _Py_UOpsSymType* -sym_new_known_notnull(_Py_UOpsAbstractInterpContext *ctx) -{ - _Py_UOpsSymType *res = sym_new_unknown(ctx); - if (res == NULL) { - return NULL; - } - sym_set_flag(res, KNOWN); - sym_set_flag(res, NOT_NULL); - return res; -} - -static inline _Py_UOpsSymType* -sym_new_known_type(_Py_UOpsAbstractInterpContext *ctx, - PyTypeObject *typ) -{ - _Py_UOpsSymType *res = sym_new(ctx,NULL); - if (res == NULL) { - return NULL; - } - sym_set_type(res, typ); - return res; -} - -// Takes a borrowed reference to const_val. -static inline _Py_UOpsSymType* -sym_new_const(_Py_UOpsAbstractInterpContext *ctx, PyObject *const_val) -{ - assert(const_val != NULL); - _Py_UOpsSymType *temp = sym_new( - ctx, - const_val - ); - if (temp == NULL) { - return NULL; - } - sym_set_type(temp, Py_TYPE(const_val)); - sym_set_flag(temp, TRUE_CONST); - sym_set_flag(temp, KNOWN); - sym_set_flag(temp, NOT_NULL); - return temp; -} - -static _Py_UOpsSymType* -sym_new_null(_Py_UOpsAbstractInterpContext *ctx) -{ - _Py_UOpsSymType *null_sym = sym_new_unknown(ctx); - if (null_sym == NULL) { - return NULL; - } - sym_set_null(null_sym); - return null_sym; -} - - -static inline bool -sym_matches_type(_Py_UOpsSymType *sym, PyTypeObject *typ) -{ - assert(typ == NULL || PyType_Check(typ)); - if (!sym_has_flag(sym, KNOWN)) { - return false; - } - return sym->typ == typ; -} - static inline bool op_is_end(uint32_t opcode) @@ -599,8 +277,8 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer, #define _LOAD_ATTR_NOT_NULL \ do { \ - OUT_OF_SPACE_IF_NULL(attr = sym_new_known_notnull(ctx)); \ - OUT_OF_SPACE_IF_NULL(null = sym_new_null(ctx)); \ + OUT_OF_SPACE_IF_NULL(attr = _Py_uop_sym_new_not_null(ctx)); \ + OUT_OF_SPACE_IF_NULL(null = _Py_uop_sym_new_null(ctx)); \ } while (0); @@ -618,12 +296,15 @@ optimize_uops( _Py_UOpsAbstractInterpContext context; _Py_UOpsAbstractInterpContext *ctx = &context; - if (abstractcontext_init( - ctx, - co, curr_stacklen, - trace_len) < 0) { + if (_Py_uop_abstractcontext_init(ctx) < 0) { goto out_of_space; } + _Py_UOpsAbstractFrame *frame = _Py_uop_ctx_frame_new(ctx, co, ctx->n_consumed, 0, curr_stacklen); + if (frame == NULL) { + return -1; + } + ctx->curr_frame_depth++; + ctx->frame = frame; for (_PyUOpInstruction *this_instr = trace; this_instr < trace + trace_len && !op_is_end(this_instr->opcode); @@ -650,17 +331,17 @@ optimize_uops( assert(STACK_LEVEL() >= 0); } - abstractcontext_fini(ctx); + _Py_uop_abstractcontext_fini(ctx); return 1; out_of_space: DPRINTF(1, "Out of space in abstract interpreter\n"); - abstractcontext_fini(ctx); + _Py_uop_abstractcontext_fini(ctx); return 0; error: DPRINTF(1, "Encountered error in abstract interpreter\n"); - abstractcontext_fini(ctx); + _Py_uop_abstractcontext_fini(ctx); return 0; } diff --git a/Python/optimizer_bytecodes.c b/Python/optimizer_bytecodes.c index b9afd30..e6e41f8 100644 --- a/Python/optimizer_bytecodes.c +++ b/Python/optimizer_bytecodes.c @@ -33,7 +33,7 @@ dummy_func(void) { op(_LOAD_FAST_CHECK, (-- value)) { value = GETLOCAL(oparg); // We guarantee this will error - just bail and don't optimize it. - if (sym_is_null(value)) { + if (_Py_uop_sym_is_null(value)) { goto out_of_space; } } @@ -45,7 +45,7 @@ dummy_func(void) { op(_LOAD_FAST_AND_CLEAR, (-- value)) { value = GETLOCAL(oparg); _Py_UOpsSymType *temp; - OUT_OF_SPACE_IF_NULL(temp = sym_new_null(ctx)); + OUT_OF_SPACE_IF_NULL(temp = _Py_uop_sym_new_null(ctx)); GETLOCAL(oparg) = temp; } @@ -54,147 +54,147 @@ dummy_func(void) { } op(_PUSH_NULL, (-- res)) { - res = sym_new_null(ctx); + res = _Py_uop_sym_new_null(ctx); if (res == NULL) { goto out_of_space; }; } op(_GUARD_BOTH_INT, (left, right -- left, right)) { - if (sym_matches_type(left, &PyLong_Type) && - sym_matches_type(right, &PyLong_Type)) { + if (_Py_uop_sym_matches_type(left, &PyLong_Type) && + _Py_uop_sym_matches_type(right, &PyLong_Type)) { REPLACE_OP(this_instr, _NOP, 0, 0); } - sym_set_type(left, &PyLong_Type); - sym_set_type(right, &PyLong_Type); + _Py_uop_sym_set_type(left, &PyLong_Type); + _Py_uop_sym_set_type(right, &PyLong_Type); } op(_GUARD_BOTH_FLOAT, (left, right -- left, right)) { - if (sym_matches_type(left, &PyFloat_Type) && - sym_matches_type(right, &PyFloat_Type)) { + if (_Py_uop_sym_matches_type(left, &PyFloat_Type) && + _Py_uop_sym_matches_type(right, &PyFloat_Type)) { REPLACE_OP(this_instr, _NOP, 0 ,0); } - sym_set_type(left, &PyFloat_Type); - sym_set_type(right, &PyFloat_Type); + _Py_uop_sym_set_type(left, &PyFloat_Type); + _Py_uop_sym_set_type(right, &PyFloat_Type); } op(_GUARD_BOTH_UNICODE, (left, right -- left, right)) { - if (sym_matches_type(left, &PyUnicode_Type) && - sym_matches_type(right, &PyUnicode_Type)) { + if (_Py_uop_sym_matches_type(left, &PyUnicode_Type) && + _Py_uop_sym_matches_type(right, &PyUnicode_Type)) { REPLACE_OP(this_instr, _NOP, 0 ,0); } - sym_set_type(left, &PyUnicode_Type); - sym_set_type(right, &PyUnicode_Type); + _Py_uop_sym_set_type(left, &PyUnicode_Type); + _Py_uop_sym_set_type(right, &PyUnicode_Type); } op(_BINARY_OP_ADD_INT, (left, right -- res)) { - if (sym_is_const(left) && sym_is_const(right)) { - assert(PyLong_CheckExact(sym_get_const(left))); - assert(PyLong_CheckExact(sym_get_const(right))); - PyObject *temp = _PyLong_Add((PyLongObject *)sym_get_const(left), - (PyLongObject *)sym_get_const(right)); + if (_Py_uop_sym_is_const(left) && _Py_uop_sym_is_const(right)) { + assert(PyLong_CheckExact(_Py_uop_sym_get_const(left))); + assert(PyLong_CheckExact(_Py_uop_sym_get_const(right))); + PyObject *temp = _PyLong_Add((PyLongObject *)_Py_uop_sym_get_const(left), + (PyLongObject *)_Py_uop_sym_get_const(right)); if (temp == NULL) { goto error; } - OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, temp)); + OUT_OF_SPACE_IF_NULL(res = _Py_uop_sym_new_const(ctx, temp)); // TODO gh-115506: // replace opcode with constant propagated one and add tests! } else { - OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyLong_Type)); + OUT_OF_SPACE_IF_NULL(res = _Py_uop_sym_new_type(ctx, &PyLong_Type)); } } op(_BINARY_OP_SUBTRACT_INT, (left, right -- res)) { - if (sym_is_const(left) && sym_is_const(right)) { - assert(PyLong_CheckExact(sym_get_const(left))); - assert(PyLong_CheckExact(sym_get_const(right))); - PyObject *temp = _PyLong_Subtract((PyLongObject *)sym_get_const(left), - (PyLongObject *)sym_get_const(right)); + if (_Py_uop_sym_is_const(left) && _Py_uop_sym_is_const(right)) { + assert(PyLong_CheckExact(_Py_uop_sym_get_const(left))); + assert(PyLong_CheckExact(_Py_uop_sym_get_const(right))); + PyObject *temp = _PyLong_Subtract((PyLongObject *)_Py_uop_sym_get_const(left), + (PyLongObject *)_Py_uop_sym_get_const(right)); if (temp == NULL) { goto error; } - OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, temp)); + OUT_OF_SPACE_IF_NULL(res = _Py_uop_sym_new_const(ctx, temp)); // TODO gh-115506: // replace opcode with constant propagated one and add tests! } else { - OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyLong_Type)); + OUT_OF_SPACE_IF_NULL(res = _Py_uop_sym_new_type(ctx, &PyLong_Type)); } } op(_BINARY_OP_MULTIPLY_INT, (left, right -- res)) { - if (sym_is_const(left) && sym_is_const(right)) { - assert(PyLong_CheckExact(sym_get_const(left))); - assert(PyLong_CheckExact(sym_get_const(right))); - PyObject *temp = _PyLong_Multiply((PyLongObject *)sym_get_const(left), - (PyLongObject *)sym_get_const(right)); + if (_Py_uop_sym_is_const(left) && _Py_uop_sym_is_const(right)) { + assert(PyLong_CheckExact(_Py_uop_sym_get_const(left))); + assert(PyLong_CheckExact(_Py_uop_sym_get_const(right))); + PyObject *temp = _PyLong_Multiply((PyLongObject *)_Py_uop_sym_get_const(left), + (PyLongObject *)_Py_uop_sym_get_const(right)); if (temp == NULL) { goto error; } - OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, temp)); + OUT_OF_SPACE_IF_NULL(res = _Py_uop_sym_new_const(ctx, temp)); // TODO gh-115506: // replace opcode with constant propagated one and add tests! } else { - OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyLong_Type)); + OUT_OF_SPACE_IF_NULL(res = _Py_uop_sym_new_type(ctx, &PyLong_Type)); } } op(_BINARY_OP_ADD_FLOAT, (left, right -- res)) { - if (sym_is_const(left) && sym_is_const(right)) { - assert(PyFloat_CheckExact(sym_get_const(left))); - assert(PyFloat_CheckExact(sym_get_const(right))); + if (_Py_uop_sym_is_const(left) && _Py_uop_sym_is_const(right)) { + assert(PyFloat_CheckExact(_Py_uop_sym_get_const(left))); + assert(PyFloat_CheckExact(_Py_uop_sym_get_const(right))); PyObject *temp = PyFloat_FromDouble( - PyFloat_AS_DOUBLE(sym_get_const(left)) + - PyFloat_AS_DOUBLE(sym_get_const(right))); + PyFloat_AS_DOUBLE(_Py_uop_sym_get_const(left)) + + PyFloat_AS_DOUBLE(_Py_uop_sym_get_const(right))); if (temp == NULL) { goto error; } - res = sym_new_const(ctx, temp); + res = _Py_uop_sym_new_const(ctx, temp); // TODO gh-115506: // replace opcode with constant propagated one and update tests! } else { - OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyFloat_Type)); + OUT_OF_SPACE_IF_NULL(res = _Py_uop_sym_new_type(ctx, &PyFloat_Type)); } } op(_BINARY_OP_SUBTRACT_FLOAT, (left, right -- res)) { - if (sym_is_const(left) && sym_is_const(right)) { - assert(PyFloat_CheckExact(sym_get_const(left))); - assert(PyFloat_CheckExact(sym_get_const(right))); + if (_Py_uop_sym_is_const(left) && _Py_uop_sym_is_const(right)) { + assert(PyFloat_CheckExact(_Py_uop_sym_get_const(left))); + assert(PyFloat_CheckExact(_Py_uop_sym_get_const(right))); PyObject *temp = PyFloat_FromDouble( - PyFloat_AS_DOUBLE(sym_get_const(left)) - - PyFloat_AS_DOUBLE(sym_get_const(right))); + PyFloat_AS_DOUBLE(_Py_uop_sym_get_const(left)) - + PyFloat_AS_DOUBLE(_Py_uop_sym_get_const(right))); if (temp == NULL) { goto error; } - res = sym_new_const(ctx, temp); + res = _Py_uop_sym_new_const(ctx, temp); // TODO gh-115506: // replace opcode with constant propagated one and update tests! } else { - OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyFloat_Type)); + OUT_OF_SPACE_IF_NULL(res = _Py_uop_sym_new_type(ctx, &PyFloat_Type)); } } op(_BINARY_OP_MULTIPLY_FLOAT, (left, right -- res)) { - if (sym_is_const(left) && sym_is_const(right)) { - assert(PyFloat_CheckExact(sym_get_const(left))); - assert(PyFloat_CheckExact(sym_get_const(right))); + if (_Py_uop_sym_is_const(left) && _Py_uop_sym_is_const(right)) { + assert(PyFloat_CheckExact(_Py_uop_sym_get_const(left))); + assert(PyFloat_CheckExact(_Py_uop_sym_get_const(right))); PyObject *temp = PyFloat_FromDouble( - PyFloat_AS_DOUBLE(sym_get_const(left)) * - PyFloat_AS_DOUBLE(sym_get_const(right))); + PyFloat_AS_DOUBLE(_Py_uop_sym_get_const(left)) * + PyFloat_AS_DOUBLE(_Py_uop_sym_get_const(right))); if (temp == NULL) { goto error; } - res = sym_new_const(ctx, temp); + res = _Py_uop_sym_new_const(ctx, temp); // TODO gh-115506: // replace opcode with constant propagated one and update tests! } else { - OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyFloat_Type)); + OUT_OF_SPACE_IF_NULL(res = _Py_uop_sym_new_type(ctx, &PyFloat_Type)); } } @@ -205,21 +205,21 @@ dummy_func(void) { } op(_LOAD_CONST_INLINE, (ptr/4 -- value)) { - OUT_OF_SPACE_IF_NULL(value = sym_new_const(ctx, ptr)); + OUT_OF_SPACE_IF_NULL(value = _Py_uop_sym_new_const(ctx, ptr)); } op(_LOAD_CONST_INLINE_BORROW, (ptr/4 -- value)) { - OUT_OF_SPACE_IF_NULL(value = sym_new_const(ctx, ptr)); + OUT_OF_SPACE_IF_NULL(value = _Py_uop_sym_new_const(ctx, ptr)); } op(_LOAD_CONST_INLINE_WITH_NULL, (ptr/4 -- value, null)) { - OUT_OF_SPACE_IF_NULL(value = sym_new_const(ctx, ptr)); - OUT_OF_SPACE_IF_NULL(null = sym_new_null(ctx)); + OUT_OF_SPACE_IF_NULL(value = _Py_uop_sym_new_const(ctx, ptr)); + OUT_OF_SPACE_IF_NULL(null = _Py_uop_sym_new_null(ctx)); } op(_LOAD_CONST_INLINE_BORROW_WITH_NULL, (ptr/4 -- value, null)) { - OUT_OF_SPACE_IF_NULL(value = sym_new_const(ctx, ptr)); - OUT_OF_SPACE_IF_NULL(null = sym_new_null(ctx)); + OUT_OF_SPACE_IF_NULL(value = _Py_uop_sym_new_const(ctx, ptr)); + OUT_OF_SPACE_IF_NULL(null = _Py_uop_sym_new_null(ctx)); } @@ -240,8 +240,8 @@ dummy_func(void) { op(_CHECK_ATTR_MODULE, (dict_version/2, owner -- owner)) { (void)dict_version; - if (sym_is_const(owner)) { - PyObject *cnst = sym_get_const(owner); + if (_Py_uop_sym_is_const(owner)) { + PyObject *cnst = _Py_uop_sym_get_const(owner); if (PyModule_CheckExact(cnst)) { PyModuleObject *mod = (PyModuleObject *)cnst; PyObject *dict = mod->md_dict; @@ -257,23 +257,23 @@ dummy_func(void) { op(_LOAD_ATTR_MODULE, (index/1, owner -- attr, null if (oparg & 1))) { (void)index; - OUT_OF_SPACE_IF_NULL(null = sym_new_null(ctx)); + OUT_OF_SPACE_IF_NULL(null = _Py_uop_sym_new_null(ctx)); attr = NULL; if (this_instr[-1].opcode == _NOP) { // Preceding _CHECK_ATTR_MODULE was removed: mod is const and dict is watched. - assert(sym_is_const(owner)); - PyModuleObject *mod = (PyModuleObject *)sym_get_const(owner); + assert(_Py_uop_sym_is_const(owner)); + PyModuleObject *mod = (PyModuleObject *)_Py_uop_sym_get_const(owner); assert(PyModule_CheckExact(mod)); PyObject *dict = mod->md_dict; PyObject *res = convert_global_to_const(this_instr, dict); if (res != NULL) { this_instr[-1].opcode = _POP_TOP; - OUT_OF_SPACE_IF_NULL(attr = sym_new_const(ctx, res)); + OUT_OF_SPACE_IF_NULL(attr = _Py_uop_sym_new_const(ctx, res)); } } if (attr == NULL) { /* No conversion made. We don't know what `attr` is. */ - OUT_OF_SPACE_IF_NULL(attr = sym_new_known_notnull(ctx)); + OUT_OF_SPACE_IF_NULL(attr = _Py_uop_sym_new_not_null(ctx)); } } @@ -297,38 +297,38 @@ dummy_func(void) { op(_LOAD_ATTR_METHOD_WITH_VALUES, (descr/4, owner -- attr, self if (1))) { (void)descr; - OUT_OF_SPACE_IF_NULL(attr = sym_new_known_notnull(ctx)); + OUT_OF_SPACE_IF_NULL(attr = _Py_uop_sym_new_not_null(ctx)); self = owner; } op(_LOAD_ATTR_METHOD_NO_DICT, (descr/4, owner -- attr, self if (1))) { (void)descr; - OUT_OF_SPACE_IF_NULL(attr = sym_new_known_notnull(ctx)); + OUT_OF_SPACE_IF_NULL(attr = _Py_uop_sym_new_not_null(ctx)); self = owner; } op(_LOAD_ATTR_METHOD_LAZY_DICT, (descr/4, owner -- attr, self if (1))) { (void)descr; - OUT_OF_SPACE_IF_NULL(attr = sym_new_known_notnull(ctx)); + OUT_OF_SPACE_IF_NULL(attr = _Py_uop_sym_new_not_null(ctx)); self = owner; } op(_INIT_CALL_BOUND_METHOD_EXACT_ARGS, (callable, unused, unused[oparg] -- func, self, unused[oparg])) { (void)callable; - OUT_OF_SPACE_IF_NULL(func = sym_new_known_notnull(ctx)); - OUT_OF_SPACE_IF_NULL(self = sym_new_known_notnull(ctx)); + OUT_OF_SPACE_IF_NULL(func = _Py_uop_sym_new_not_null(ctx)); + OUT_OF_SPACE_IF_NULL(self = _Py_uop_sym_new_not_null(ctx)); } 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); + _Py_uop_sym_set_type(callable, &PyFunction_Type); (void)self_or_null; (void)func_version; } op(_CHECK_CALL_BOUND_METHOD_EXACT_ARGS, (callable, null, unused[oparg] -- callable, null, unused[oparg])) { - sym_set_null(null); - sym_set_type(callable, &PyMethod_Type); + _Py_uop_sym_set_null(null); + _Py_uop_sym_set_type(callable, &PyMethod_Type); } op(_INIT_CALL_PY_EXACT_ARGS, (callable, self_or_null, args[oparg] -- new_frame: _Py_UOpsAbstractFrame *)) { @@ -344,7 +344,7 @@ dummy_func(void) { assert(self_or_null != NULL); assert(args != NULL); - if (sym_is_not_null(self_or_null)) { + if (_Py_uop_sym_is_not_null(self_or_null)) { // Bound method fiddling, same as _INIT_CALL_PY_EXACT_ARGS in VM args--; argcount++; @@ -355,18 +355,18 @@ dummy_func(void) { // Can determine statically, so we interleave the new locals // and make the current stack the new locals. // This also sets up for true call inlining. - if (sym_is_known(self_or_null)) { + if (_Py_uop_sym_is_null(self_or_null) || _Py_uop_sym_is_not_null(self_or_null)) { localsplus_start = args; n_locals_already_filled = argcount; } OUT_OF_SPACE_IF_NULL(new_frame = - ctx_frame_new(ctx, co, localsplus_start, n_locals_already_filled, 0)); + _Py_uop_ctx_frame_new(ctx, co, localsplus_start, n_locals_already_filled, 0)); } op(_POP_FRAME, (retval -- res)) { SYNC_SP(); ctx->frame->stack_pointer = stack_pointer; - ctx_frame_pop(ctx); + _Py_uop_ctx_frame_pop(ctx); stack_pointer = ctx->frame->stack_pointer; res = retval; } @@ -383,7 +383,7 @@ dummy_func(void) { /* This has to be done manually */ (void)seq; for (int i = 0; i < oparg; i++) { - OUT_OF_SPACE_IF_NULL(values[i] = sym_new_unknown(ctx)); + OUT_OF_SPACE_IF_NULL(values[i] = _Py_uop_sym_new_unknown(ctx)); } } @@ -392,12 +392,12 @@ dummy_func(void) { (void)seq; int totalargs = (oparg & 0xFF) + (oparg >> 8) + 1; for (int i = 0; i < totalargs; i++) { - OUT_OF_SPACE_IF_NULL(values[i] = sym_new_unknown(ctx)); + OUT_OF_SPACE_IF_NULL(values[i] = _Py_uop_sym_new_unknown(ctx)); } } op(_ITER_NEXT_RANGE, (iter -- iter, next)) { - OUT_OF_SPACE_IF_NULL(next = sym_new_known_type(ctx, &PyLong_Type)); + OUT_OF_SPACE_IF_NULL(next = _Py_uop_sym_new_type(ctx, &PyLong_Type)); (void)iter; } diff --git a/Python/optimizer_cases.c.h b/Python/optimizer_cases.c.h index e8146dc..3051588 100644 --- a/Python/optimizer_cases.c.h +++ b/Python/optimizer_cases.c.h @@ -17,7 +17,7 @@ _Py_UOpsSymType *value; value = GETLOCAL(oparg); // We guarantee this will error - just bail and don't optimize it. - if (sym_is_null(value)) { + if (_Py_uop_sym_is_null(value)) { goto out_of_space; } stack_pointer[0] = value; @@ -37,7 +37,7 @@ _Py_UOpsSymType *value; value = GETLOCAL(oparg); _Py_UOpsSymType *temp; - OUT_OF_SPACE_IF_NULL(temp = sym_new_null(ctx)); + OUT_OF_SPACE_IF_NULL(temp = _Py_uop_sym_new_null(ctx)); GETLOCAL(oparg) = temp; stack_pointer[0] = value; stack_pointer += 1; @@ -69,7 +69,7 @@ case _PUSH_NULL: { _Py_UOpsSymType *res; - res = sym_new_null(ctx); + res = _Py_uop_sym_new_null(ctx); if (res == NULL) { goto out_of_space; }; @@ -80,7 +80,7 @@ case _END_SEND: { _Py_UOpsSymType *value; - value = sym_new_unknown(ctx); + value = _Py_uop_sym_new_unknown(ctx); if (value == NULL) goto out_of_space; stack_pointer[-2] = value; stack_pointer += -1; @@ -89,7 +89,7 @@ case _UNARY_NEGATIVE: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-1] = res; break; @@ -97,7 +97,7 @@ case _UNARY_NOT: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-1] = res; break; @@ -105,7 +105,7 @@ case _TO_BOOL: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-1] = res; break; @@ -117,7 +117,7 @@ case _TO_BOOL_INT: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-1] = res; break; @@ -125,7 +125,7 @@ case _TO_BOOL_LIST: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-1] = res; break; @@ -133,7 +133,7 @@ case _TO_BOOL_NONE: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-1] = res; break; @@ -141,7 +141,7 @@ case _TO_BOOL_STR: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-1] = res; break; @@ -149,7 +149,7 @@ case _TO_BOOL_ALWAYS_TRUE: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-1] = res; break; @@ -157,7 +157,7 @@ case _UNARY_INVERT: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-1] = res; break; @@ -168,12 +168,12 @@ _Py_UOpsSymType *left; right = stack_pointer[-1]; left = stack_pointer[-2]; - if (sym_matches_type(left, &PyLong_Type) && - sym_matches_type(right, &PyLong_Type)) { + if (_Py_uop_sym_matches_type(left, &PyLong_Type) && + _Py_uop_sym_matches_type(right, &PyLong_Type)) { REPLACE_OP(this_instr, _NOP, 0, 0); } - sym_set_type(left, &PyLong_Type); - sym_set_type(right, &PyLong_Type); + _Py_uop_sym_set_type(left, &PyLong_Type); + _Py_uop_sym_set_type(right, &PyLong_Type); break; } @@ -183,20 +183,20 @@ _Py_UOpsSymType *res; right = stack_pointer[-1]; left = stack_pointer[-2]; - if (sym_is_const(left) && sym_is_const(right)) { - assert(PyLong_CheckExact(sym_get_const(left))); - assert(PyLong_CheckExact(sym_get_const(right))); - PyObject *temp = _PyLong_Multiply((PyLongObject *)sym_get_const(left), - (PyLongObject *)sym_get_const(right)); + if (_Py_uop_sym_is_const(left) && _Py_uop_sym_is_const(right)) { + assert(PyLong_CheckExact(_Py_uop_sym_get_const(left))); + assert(PyLong_CheckExact(_Py_uop_sym_get_const(right))); + PyObject *temp = _PyLong_Multiply((PyLongObject *)_Py_uop_sym_get_const(left), + (PyLongObject *)_Py_uop_sym_get_const(right)); if (temp == NULL) { goto error; } - OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, temp)); + OUT_OF_SPACE_IF_NULL(res = _Py_uop_sym_new_const(ctx, temp)); // TODO gh-115506: // replace opcode with constant propagated one and add tests! } else { - OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyLong_Type)); + OUT_OF_SPACE_IF_NULL(res = _Py_uop_sym_new_type(ctx, &PyLong_Type)); } stack_pointer[-2] = res; stack_pointer += -1; @@ -209,20 +209,20 @@ _Py_UOpsSymType *res; right = stack_pointer[-1]; left = stack_pointer[-2]; - if (sym_is_const(left) && sym_is_const(right)) { - assert(PyLong_CheckExact(sym_get_const(left))); - assert(PyLong_CheckExact(sym_get_const(right))); - PyObject *temp = _PyLong_Add((PyLongObject *)sym_get_const(left), - (PyLongObject *)sym_get_const(right)); + if (_Py_uop_sym_is_const(left) && _Py_uop_sym_is_const(right)) { + assert(PyLong_CheckExact(_Py_uop_sym_get_const(left))); + assert(PyLong_CheckExact(_Py_uop_sym_get_const(right))); + PyObject *temp = _PyLong_Add((PyLongObject *)_Py_uop_sym_get_const(left), + (PyLongObject *)_Py_uop_sym_get_const(right)); if (temp == NULL) { goto error; } - OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, temp)); + OUT_OF_SPACE_IF_NULL(res = _Py_uop_sym_new_const(ctx, temp)); // TODO gh-115506: // replace opcode with constant propagated one and add tests! } else { - OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyLong_Type)); + OUT_OF_SPACE_IF_NULL(res = _Py_uop_sym_new_type(ctx, &PyLong_Type)); } stack_pointer[-2] = res; stack_pointer += -1; @@ -235,20 +235,20 @@ _Py_UOpsSymType *res; right = stack_pointer[-1]; left = stack_pointer[-2]; - if (sym_is_const(left) && sym_is_const(right)) { - assert(PyLong_CheckExact(sym_get_const(left))); - assert(PyLong_CheckExact(sym_get_const(right))); - PyObject *temp = _PyLong_Subtract((PyLongObject *)sym_get_const(left), - (PyLongObject *)sym_get_const(right)); + if (_Py_uop_sym_is_const(left) && _Py_uop_sym_is_const(right)) { + assert(PyLong_CheckExact(_Py_uop_sym_get_const(left))); + assert(PyLong_CheckExact(_Py_uop_sym_get_const(right))); + PyObject *temp = _PyLong_Subtract((PyLongObject *)_Py_uop_sym_get_const(left), + (PyLongObject *)_Py_uop_sym_get_const(right)); if (temp == NULL) { goto error; } - OUT_OF_SPACE_IF_NULL(res = sym_new_const(ctx, temp)); + OUT_OF_SPACE_IF_NULL(res = _Py_uop_sym_new_const(ctx, temp)); // TODO gh-115506: // replace opcode with constant propagated one and add tests! } else { - OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyLong_Type)); + OUT_OF_SPACE_IF_NULL(res = _Py_uop_sym_new_type(ctx, &PyLong_Type)); } stack_pointer[-2] = res; stack_pointer += -1; @@ -260,12 +260,12 @@ _Py_UOpsSymType *left; right = stack_pointer[-1]; left = stack_pointer[-2]; - if (sym_matches_type(left, &PyFloat_Type) && - sym_matches_type(right, &PyFloat_Type)) { + if (_Py_uop_sym_matches_type(left, &PyFloat_Type) && + _Py_uop_sym_matches_type(right, &PyFloat_Type)) { REPLACE_OP(this_instr, _NOP, 0 ,0); } - sym_set_type(left, &PyFloat_Type); - sym_set_type(right, &PyFloat_Type); + _Py_uop_sym_set_type(left, &PyFloat_Type); + _Py_uop_sym_set_type(right, &PyFloat_Type); break; } @@ -275,21 +275,21 @@ _Py_UOpsSymType *res; right = stack_pointer[-1]; left = stack_pointer[-2]; - if (sym_is_const(left) && sym_is_const(right)) { - assert(PyFloat_CheckExact(sym_get_const(left))); - assert(PyFloat_CheckExact(sym_get_const(right))); + if (_Py_uop_sym_is_const(left) && _Py_uop_sym_is_const(right)) { + assert(PyFloat_CheckExact(_Py_uop_sym_get_const(left))); + assert(PyFloat_CheckExact(_Py_uop_sym_get_const(right))); PyObject *temp = PyFloat_FromDouble( - PyFloat_AS_DOUBLE(sym_get_const(left)) * - PyFloat_AS_DOUBLE(sym_get_const(right))); + PyFloat_AS_DOUBLE(_Py_uop_sym_get_const(left)) * + PyFloat_AS_DOUBLE(_Py_uop_sym_get_const(right))); if (temp == NULL) { goto error; } - res = sym_new_const(ctx, temp); + res = _Py_uop_sym_new_const(ctx, temp); // TODO gh-115506: // replace opcode with constant propagated one and update tests! } else { - OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyFloat_Type)); + OUT_OF_SPACE_IF_NULL(res = _Py_uop_sym_new_type(ctx, &PyFloat_Type)); } stack_pointer[-2] = res; stack_pointer += -1; @@ -302,21 +302,21 @@ _Py_UOpsSymType *res; right = stack_pointer[-1]; left = stack_pointer[-2]; - if (sym_is_const(left) && sym_is_const(right)) { - assert(PyFloat_CheckExact(sym_get_const(left))); - assert(PyFloat_CheckExact(sym_get_const(right))); + if (_Py_uop_sym_is_const(left) && _Py_uop_sym_is_const(right)) { + assert(PyFloat_CheckExact(_Py_uop_sym_get_const(left))); + assert(PyFloat_CheckExact(_Py_uop_sym_get_const(right))); PyObject *temp = PyFloat_FromDouble( - PyFloat_AS_DOUBLE(sym_get_const(left)) + - PyFloat_AS_DOUBLE(sym_get_const(right))); + PyFloat_AS_DOUBLE(_Py_uop_sym_get_const(left)) + + PyFloat_AS_DOUBLE(_Py_uop_sym_get_const(right))); if (temp == NULL) { goto error; } - res = sym_new_const(ctx, temp); + res = _Py_uop_sym_new_const(ctx, temp); // TODO gh-115506: // replace opcode with constant propagated one and update tests! } else { - OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyFloat_Type)); + OUT_OF_SPACE_IF_NULL(res = _Py_uop_sym_new_type(ctx, &PyFloat_Type)); } stack_pointer[-2] = res; stack_pointer += -1; @@ -329,21 +329,21 @@ _Py_UOpsSymType *res; right = stack_pointer[-1]; left = stack_pointer[-2]; - if (sym_is_const(left) && sym_is_const(right)) { - assert(PyFloat_CheckExact(sym_get_const(left))); - assert(PyFloat_CheckExact(sym_get_const(right))); + if (_Py_uop_sym_is_const(left) && _Py_uop_sym_is_const(right)) { + assert(PyFloat_CheckExact(_Py_uop_sym_get_const(left))); + assert(PyFloat_CheckExact(_Py_uop_sym_get_const(right))); PyObject *temp = PyFloat_FromDouble( - PyFloat_AS_DOUBLE(sym_get_const(left)) - - PyFloat_AS_DOUBLE(sym_get_const(right))); + PyFloat_AS_DOUBLE(_Py_uop_sym_get_const(left)) - + PyFloat_AS_DOUBLE(_Py_uop_sym_get_const(right))); if (temp == NULL) { goto error; } - res = sym_new_const(ctx, temp); + res = _Py_uop_sym_new_const(ctx, temp); // TODO gh-115506: // replace opcode with constant propagated one and update tests! } else { - OUT_OF_SPACE_IF_NULL(res = sym_new_known_type(ctx, &PyFloat_Type)); + OUT_OF_SPACE_IF_NULL(res = _Py_uop_sym_new_type(ctx, &PyFloat_Type)); } stack_pointer[-2] = res; stack_pointer += -1; @@ -355,18 +355,18 @@ _Py_UOpsSymType *left; right = stack_pointer[-1]; left = stack_pointer[-2]; - if (sym_matches_type(left, &PyUnicode_Type) && - sym_matches_type(right, &PyUnicode_Type)) { + if (_Py_uop_sym_matches_type(left, &PyUnicode_Type) && + _Py_uop_sym_matches_type(right, &PyUnicode_Type)) { REPLACE_OP(this_instr, _NOP, 0 ,0); } - sym_set_type(left, &PyUnicode_Type); - sym_set_type(right, &PyUnicode_Type); + _Py_uop_sym_set_type(left, &PyUnicode_Type); + _Py_uop_sym_set_type(right, &PyUnicode_Type); break; } case _BINARY_OP_ADD_UNICODE: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-2] = res; stack_pointer += -1; @@ -375,7 +375,7 @@ case _BINARY_SUBSCR: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-2] = res; stack_pointer += -1; @@ -384,7 +384,7 @@ case _BINARY_SLICE: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-3] = res; stack_pointer += -2; @@ -398,7 +398,7 @@ case _BINARY_SUBSCR_LIST_INT: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-2] = res; stack_pointer += -1; @@ -407,7 +407,7 @@ case _BINARY_SUBSCR_STR_INT: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-2] = res; stack_pointer += -1; @@ -416,7 +416,7 @@ case _BINARY_SUBSCR_TUPLE_INT: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-2] = res; stack_pointer += -1; @@ -425,7 +425,7 @@ case _BINARY_SUBSCR_DICT: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-2] = res; stack_pointer += -1; @@ -466,7 +466,7 @@ case _CALL_INTRINSIC_1: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-1] = res; break; @@ -474,7 +474,7 @@ case _CALL_INTRINSIC_2: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-2] = res; stack_pointer += -1; @@ -487,7 +487,7 @@ retval = stack_pointer[-1]; stack_pointer += -1; ctx->frame->stack_pointer = stack_pointer; - ctx_frame_pop(ctx); + _Py_uop_ctx_frame_pop(ctx); stack_pointer = ctx->frame->stack_pointer; res = retval; stack_pointer[0] = res; @@ -501,7 +501,7 @@ case _GET_AITER: { _Py_UOpsSymType *iter; - iter = sym_new_unknown(ctx); + iter = _Py_uop_sym_new_unknown(ctx); if (iter == NULL) goto out_of_space; stack_pointer[-1] = iter; break; @@ -509,7 +509,7 @@ case _GET_ANEXT: { _Py_UOpsSymType *awaitable; - awaitable = sym_new_unknown(ctx); + awaitable = _Py_uop_sym_new_unknown(ctx); if (awaitable == NULL) goto out_of_space; stack_pointer[0] = awaitable; stack_pointer += 1; @@ -518,7 +518,7 @@ case _GET_AWAITABLE: { _Py_UOpsSymType *iter; - iter = sym_new_unknown(ctx); + iter = _Py_uop_sym_new_unknown(ctx); if (iter == NULL) goto out_of_space; stack_pointer[-1] = iter; break; @@ -537,7 +537,7 @@ case _LOAD_ASSERTION_ERROR: { _Py_UOpsSymType *value; - value = sym_new_unknown(ctx); + value = _Py_uop_sym_new_unknown(ctx); if (value == NULL) goto out_of_space; stack_pointer[0] = value; stack_pointer += 1; @@ -546,7 +546,7 @@ case _LOAD_BUILD_CLASS: { _Py_UOpsSymType *bc; - bc = sym_new_unknown(ctx); + bc = _Py_uop_sym_new_unknown(ctx); if (bc == NULL) goto out_of_space; stack_pointer[0] = bc; stack_pointer += 1; @@ -570,7 +570,7 @@ /* This has to be done manually */ (void)seq; for (int i = 0; i < oparg; i++) { - OUT_OF_SPACE_IF_NULL(values[i] = sym_new_unknown(ctx)); + OUT_OF_SPACE_IF_NULL(values[i] = _Py_uop_sym_new_unknown(ctx)); } stack_pointer += -1 + oparg; break; @@ -580,7 +580,7 @@ _Py_UOpsSymType **values; values = &stack_pointer[-1]; for (int _i = oparg; --_i >= 0;) { - values[_i] = sym_new_unknown(ctx); + values[_i] = _Py_uop_sym_new_unknown(ctx); if (values[_i] == NULL) goto out_of_space; } stack_pointer += -1 + oparg; @@ -591,7 +591,7 @@ _Py_UOpsSymType **values; values = &stack_pointer[-1]; for (int _i = oparg; --_i >= 0;) { - values[_i] = sym_new_unknown(ctx); + values[_i] = _Py_uop_sym_new_unknown(ctx); if (values[_i] == NULL) goto out_of_space; } stack_pointer += -1 + oparg; @@ -602,7 +602,7 @@ _Py_UOpsSymType **values; values = &stack_pointer[-1]; for (int _i = oparg; --_i >= 0;) { - values[_i] = sym_new_unknown(ctx); + values[_i] = _Py_uop_sym_new_unknown(ctx); if (values[_i] == NULL) goto out_of_space; } stack_pointer += -1 + oparg; @@ -618,7 +618,7 @@ (void)seq; int totalargs = (oparg & 0xFF) + (oparg >> 8) + 1; for (int i = 0; i < totalargs; i++) { - OUT_OF_SPACE_IF_NULL(values[i] = sym_new_unknown(ctx)); + OUT_OF_SPACE_IF_NULL(values[i] = _Py_uop_sym_new_unknown(ctx)); } stack_pointer += (oparg >> 8) + (oparg & 0xFF); break; @@ -645,7 +645,7 @@ case _LOAD_LOCALS: { _Py_UOpsSymType *locals; - locals = sym_new_unknown(ctx); + locals = _Py_uop_sym_new_unknown(ctx); if (locals == NULL) goto out_of_space; stack_pointer[0] = locals; stack_pointer += 1; @@ -654,7 +654,7 @@ case _LOAD_FROM_DICT_OR_GLOBALS: { _Py_UOpsSymType *v; - v = sym_new_unknown(ctx); + v = _Py_uop_sym_new_unknown(ctx); if (v == NULL) goto out_of_space; stack_pointer[-1] = v; break; @@ -662,7 +662,7 @@ case _LOAD_NAME: { _Py_UOpsSymType *v; - v = sym_new_unknown(ctx); + v = _Py_uop_sym_new_unknown(ctx); if (v == NULL) goto out_of_space; stack_pointer[0] = v; stack_pointer += 1; @@ -672,9 +672,9 @@ case _LOAD_GLOBAL: { _Py_UOpsSymType *res; _Py_UOpsSymType *null = NULL; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; - null = sym_new_null(ctx); + null = _Py_uop_sym_new_null(ctx); if (null == NULL) goto out_of_space; stack_pointer[0] = res; if (oparg & 1) stack_pointer[1] = null; @@ -693,9 +693,9 @@ case _LOAD_GLOBAL_MODULE: { _Py_UOpsSymType *res; _Py_UOpsSymType *null = NULL; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; - null = sym_new_null(ctx); + null = _Py_uop_sym_new_null(ctx); if (null == NULL) goto out_of_space; stack_pointer[0] = res; if (oparg & 1) stack_pointer[1] = null; @@ -706,9 +706,9 @@ case _LOAD_GLOBAL_BUILTINS: { _Py_UOpsSymType *res; _Py_UOpsSymType *null = NULL; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; - null = sym_new_null(ctx); + null = _Py_uop_sym_new_null(ctx); if (null == NULL) goto out_of_space; stack_pointer[0] = res; if (oparg & 1) stack_pointer[1] = null; @@ -730,7 +730,7 @@ case _LOAD_FROM_DICT_OR_DEREF: { _Py_UOpsSymType *value; - value = sym_new_unknown(ctx); + value = _Py_uop_sym_new_unknown(ctx); if (value == NULL) goto out_of_space; stack_pointer[-1] = value; break; @@ -738,7 +738,7 @@ case _LOAD_DEREF: { _Py_UOpsSymType *value; - value = sym_new_unknown(ctx); + value = _Py_uop_sym_new_unknown(ctx); if (value == NULL) goto out_of_space; stack_pointer[0] = value; stack_pointer += 1; @@ -756,7 +756,7 @@ case _BUILD_STRING: { _Py_UOpsSymType *str; - str = sym_new_unknown(ctx); + str = _Py_uop_sym_new_unknown(ctx); if (str == NULL) goto out_of_space; stack_pointer[-oparg] = str; stack_pointer += 1 - oparg; @@ -765,7 +765,7 @@ case _BUILD_TUPLE: { _Py_UOpsSymType *tup; - tup = sym_new_unknown(ctx); + tup = _Py_uop_sym_new_unknown(ctx); if (tup == NULL) goto out_of_space; stack_pointer[-oparg] = tup; stack_pointer += 1 - oparg; @@ -774,7 +774,7 @@ case _BUILD_LIST: { _Py_UOpsSymType *list; - list = sym_new_unknown(ctx); + list = _Py_uop_sym_new_unknown(ctx); if (list == NULL) goto out_of_space; stack_pointer[-oparg] = list; stack_pointer += 1 - oparg; @@ -793,7 +793,7 @@ case _BUILD_SET: { _Py_UOpsSymType *set; - set = sym_new_unknown(ctx); + set = _Py_uop_sym_new_unknown(ctx); if (set == NULL) goto out_of_space; stack_pointer[-oparg] = set; stack_pointer += 1 - oparg; @@ -802,7 +802,7 @@ case _BUILD_MAP: { _Py_UOpsSymType *map; - map = sym_new_unknown(ctx); + map = _Py_uop_sym_new_unknown(ctx); if (map == NULL) goto out_of_space; stack_pointer[-oparg*2] = map; stack_pointer += 1 - oparg*2; @@ -815,7 +815,7 @@ case _BUILD_CONST_KEY_MAP: { _Py_UOpsSymType *map; - map = sym_new_unknown(ctx); + map = _Py_uop_sym_new_unknown(ctx); if (map == NULL) goto out_of_space; stack_pointer[-1 - oparg] = map; stack_pointer += -oparg; @@ -841,7 +841,7 @@ case _LOAD_SUPER_ATTR_ATTR: { _Py_UOpsSymType *attr; - attr = sym_new_unknown(ctx); + attr = _Py_uop_sym_new_unknown(ctx); if (attr == NULL) goto out_of_space; stack_pointer[-3] = attr; stack_pointer += -2; @@ -851,9 +851,9 @@ case _LOAD_SUPER_ATTR_METHOD: { _Py_UOpsSymType *attr; _Py_UOpsSymType *self_or_null; - attr = sym_new_unknown(ctx); + attr = _Py_uop_sym_new_unknown(ctx); if (attr == NULL) goto out_of_space; - self_or_null = sym_new_unknown(ctx); + self_or_null = _Py_uop_sym_new_unknown(ctx); if (self_or_null == NULL) goto out_of_space; stack_pointer[-3] = attr; stack_pointer[-2] = self_or_null; @@ -864,9 +864,9 @@ case _LOAD_ATTR: { _Py_UOpsSymType *attr; _Py_UOpsSymType *self_or_null = NULL; - attr = sym_new_unknown(ctx); + attr = _Py_uop_sym_new_unknown(ctx); if (attr == NULL) goto out_of_space; - self_or_null = sym_new_unknown(ctx); + self_or_null = _Py_uop_sym_new_unknown(ctx); if (self_or_null == NULL) goto out_of_space; stack_pointer[-1] = attr; if (oparg & 1) stack_pointer[0] = self_or_null; @@ -902,8 +902,8 @@ owner = stack_pointer[-1]; uint32_t dict_version = (uint32_t)this_instr->operand; (void)dict_version; - if (sym_is_const(owner)) { - PyObject *cnst = sym_get_const(owner); + if (_Py_uop_sym_is_const(owner)) { + PyObject *cnst = _Py_uop_sym_get_const(owner); if (PyModule_CheckExact(cnst)) { PyModuleObject *mod = (PyModuleObject *)cnst; PyObject *dict = mod->md_dict; @@ -925,23 +925,23 @@ owner = stack_pointer[-1]; uint16_t index = (uint16_t)this_instr->operand; (void)index; - OUT_OF_SPACE_IF_NULL(null = sym_new_null(ctx)); + OUT_OF_SPACE_IF_NULL(null = _Py_uop_sym_new_null(ctx)); attr = NULL; if (this_instr[-1].opcode == _NOP) { // Preceding _CHECK_ATTR_MODULE was removed: mod is const and dict is watched. - assert(sym_is_const(owner)); - PyModuleObject *mod = (PyModuleObject *)sym_get_const(owner); + assert(_Py_uop_sym_is_const(owner)); + PyModuleObject *mod = (PyModuleObject *)_Py_uop_sym_get_const(owner); assert(PyModule_CheckExact(mod)); PyObject *dict = mod->md_dict; PyObject *res = convert_global_to_const(this_instr, dict); if (res != NULL) { this_instr[-1].opcode = _POP_TOP; - OUT_OF_SPACE_IF_NULL(attr = sym_new_const(ctx, res)); + OUT_OF_SPACE_IF_NULL(attr = _Py_uop_sym_new_const(ctx, res)); } } if (attr == NULL) { /* No conversion made. We don't know what `attr` is. */ - OUT_OF_SPACE_IF_NULL(attr = sym_new_known_notnull(ctx)); + OUT_OF_SPACE_IF_NULL(attr = _Py_uop_sym_new_not_null(ctx)); } stack_pointer[-1] = attr; if (oparg & 1) stack_pointer[0] = null; @@ -1024,7 +1024,7 @@ case _COMPARE_OP: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-2] = res; stack_pointer += -1; @@ -1033,7 +1033,7 @@ case _COMPARE_OP_FLOAT: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-2] = res; stack_pointer += -1; @@ -1042,7 +1042,7 @@ case _COMPARE_OP_INT: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-2] = res; stack_pointer += -1; @@ -1051,7 +1051,7 @@ case _COMPARE_OP_STR: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-2] = res; stack_pointer += -1; @@ -1060,7 +1060,7 @@ case _IS_OP: { _Py_UOpsSymType *b; - b = sym_new_unknown(ctx); + b = _Py_uop_sym_new_unknown(ctx); if (b == NULL) goto out_of_space; stack_pointer[-2] = b; stack_pointer += -1; @@ -1069,7 +1069,7 @@ case _CONTAINS_OP: { _Py_UOpsSymType *b; - b = sym_new_unknown(ctx); + b = _Py_uop_sym_new_unknown(ctx); if (b == NULL) goto out_of_space; stack_pointer[-2] = b; stack_pointer += -1; @@ -1079,9 +1079,9 @@ case _CHECK_EG_MATCH: { _Py_UOpsSymType *rest; _Py_UOpsSymType *match; - rest = sym_new_unknown(ctx); + rest = _Py_uop_sym_new_unknown(ctx); if (rest == NULL) goto out_of_space; - match = sym_new_unknown(ctx); + match = _Py_uop_sym_new_unknown(ctx); if (match == NULL) goto out_of_space; stack_pointer[-2] = rest; stack_pointer[-1] = match; @@ -1090,7 +1090,7 @@ case _CHECK_EXC_MATCH: { _Py_UOpsSymType *b; - b = sym_new_unknown(ctx); + b = _Py_uop_sym_new_unknown(ctx); if (b == NULL) goto out_of_space; stack_pointer[-1] = b; break; @@ -1102,7 +1102,7 @@ case _IS_NONE: { _Py_UOpsSymType *b; - b = sym_new_unknown(ctx); + b = _Py_uop_sym_new_unknown(ctx); if (b == NULL) goto out_of_space; stack_pointer[-1] = b; break; @@ -1110,7 +1110,7 @@ case _GET_LEN: { _Py_UOpsSymType *len_o; - len_o = sym_new_unknown(ctx); + len_o = _Py_uop_sym_new_unknown(ctx); if (len_o == NULL) goto out_of_space; stack_pointer[0] = len_o; stack_pointer += 1; @@ -1119,7 +1119,7 @@ case _MATCH_CLASS: { _Py_UOpsSymType *attrs; - attrs = sym_new_unknown(ctx); + attrs = _Py_uop_sym_new_unknown(ctx); if (attrs == NULL) goto out_of_space; stack_pointer[-3] = attrs; stack_pointer += -2; @@ -1128,7 +1128,7 @@ case _MATCH_MAPPING: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[0] = res; stack_pointer += 1; @@ -1137,7 +1137,7 @@ case _MATCH_SEQUENCE: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[0] = res; stack_pointer += 1; @@ -1146,7 +1146,7 @@ case _MATCH_KEYS: { _Py_UOpsSymType *values_or_none; - values_or_none = sym_new_unknown(ctx); + values_or_none = _Py_uop_sym_new_unknown(ctx); if (values_or_none == NULL) goto out_of_space; stack_pointer[0] = values_or_none; stack_pointer += 1; @@ -1155,7 +1155,7 @@ case _GET_ITER: { _Py_UOpsSymType *iter; - iter = sym_new_unknown(ctx); + iter = _Py_uop_sym_new_unknown(ctx); if (iter == NULL) goto out_of_space; stack_pointer[-1] = iter; break; @@ -1163,7 +1163,7 @@ case _GET_YIELD_FROM_ITER: { _Py_UOpsSymType *iter; - iter = sym_new_unknown(ctx); + iter = _Py_uop_sym_new_unknown(ctx); if (iter == NULL) goto out_of_space; stack_pointer[-1] = iter; break; @@ -1173,7 +1173,7 @@ case _FOR_ITER_TIER_TWO: { _Py_UOpsSymType *next; - next = sym_new_unknown(ctx); + next = _Py_uop_sym_new_unknown(ctx); if (next == NULL) goto out_of_space; stack_pointer[0] = next; stack_pointer += 1; @@ -1194,7 +1194,7 @@ case _ITER_NEXT_LIST: { _Py_UOpsSymType *next; - next = sym_new_unknown(ctx); + next = _Py_uop_sym_new_unknown(ctx); if (next == NULL) goto out_of_space; stack_pointer[0] = next; stack_pointer += 1; @@ -1213,7 +1213,7 @@ case _ITER_NEXT_TUPLE: { _Py_UOpsSymType *next; - next = sym_new_unknown(ctx); + next = _Py_uop_sym_new_unknown(ctx); if (next == NULL) goto out_of_space; stack_pointer[0] = next; stack_pointer += 1; @@ -1234,7 +1234,7 @@ _Py_UOpsSymType *iter; _Py_UOpsSymType *next; iter = stack_pointer[-1]; - OUT_OF_SPACE_IF_NULL(next = sym_new_known_type(ctx, &PyLong_Type)); + OUT_OF_SPACE_IF_NULL(next = _Py_uop_sym_new_type(ctx, &PyLong_Type)); (void)iter; stack_pointer[0] = next; stack_pointer += 1; @@ -1246,9 +1246,9 @@ case _BEFORE_ASYNC_WITH: { _Py_UOpsSymType *exit; _Py_UOpsSymType *res; - exit = sym_new_unknown(ctx); + exit = _Py_uop_sym_new_unknown(ctx); if (exit == NULL) goto out_of_space; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-1] = exit; stack_pointer[0] = res; @@ -1259,9 +1259,9 @@ case _BEFORE_WITH: { _Py_UOpsSymType *exit; _Py_UOpsSymType *res; - exit = sym_new_unknown(ctx); + exit = _Py_uop_sym_new_unknown(ctx); if (exit == NULL) goto out_of_space; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-1] = exit; stack_pointer[0] = res; @@ -1271,7 +1271,7 @@ case _WITH_EXCEPT_START: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[0] = res; stack_pointer += 1; @@ -1281,9 +1281,9 @@ case _PUSH_EXC_INFO: { _Py_UOpsSymType *prev_exc; _Py_UOpsSymType *new_exc; - prev_exc = sym_new_unknown(ctx); + prev_exc = _Py_uop_sym_new_unknown(ctx); if (prev_exc == NULL) goto out_of_space; - new_exc = sym_new_unknown(ctx); + new_exc = _Py_uop_sym_new_unknown(ctx); if (new_exc == NULL) goto out_of_space; stack_pointer[-1] = prev_exc; stack_pointer[0] = new_exc; @@ -1306,7 +1306,7 @@ owner = stack_pointer[-1]; PyObject *descr = (PyObject *)this_instr->operand; (void)descr; - OUT_OF_SPACE_IF_NULL(attr = sym_new_known_notnull(ctx)); + OUT_OF_SPACE_IF_NULL(attr = _Py_uop_sym_new_not_null(ctx)); self = owner; stack_pointer[-1] = attr; stack_pointer[0] = self; @@ -1321,7 +1321,7 @@ owner = stack_pointer[-1]; PyObject *descr = (PyObject *)this_instr->operand; (void)descr; - OUT_OF_SPACE_IF_NULL(attr = sym_new_known_notnull(ctx)); + OUT_OF_SPACE_IF_NULL(attr = _Py_uop_sym_new_not_null(ctx)); self = owner; stack_pointer[-1] = attr; stack_pointer[0] = self; @@ -1331,7 +1331,7 @@ case _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES: { _Py_UOpsSymType *attr; - attr = sym_new_unknown(ctx); + attr = _Py_uop_sym_new_unknown(ctx); if (attr == NULL) goto out_of_space; stack_pointer[-1] = attr; break; @@ -1339,7 +1339,7 @@ case _LOAD_ATTR_NONDESCRIPTOR_NO_DICT: { _Py_UOpsSymType *attr; - attr = sym_new_unknown(ctx); + attr = _Py_uop_sym_new_unknown(ctx); if (attr == NULL) goto out_of_space; stack_pointer[-1] = attr; break; @@ -1356,7 +1356,7 @@ owner = stack_pointer[-1]; PyObject *descr = (PyObject *)this_instr->operand; (void)descr; - OUT_OF_SPACE_IF_NULL(attr = sym_new_known_notnull(ctx)); + OUT_OF_SPACE_IF_NULL(attr = _Py_uop_sym_new_not_null(ctx)); self = owner; stack_pointer[-1] = attr; stack_pointer[0] = self; @@ -1373,8 +1373,8 @@ _Py_UOpsSymType *callable; null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; - sym_set_null(null); - sym_set_type(callable, &PyMethod_Type); + _Py_uop_sym_set_null(null); + _Py_uop_sym_set_type(callable, &PyMethod_Type); break; } @@ -1384,8 +1384,8 @@ _Py_UOpsSymType *self; callable = stack_pointer[-2 - oparg]; (void)callable; - OUT_OF_SPACE_IF_NULL(func = sym_new_known_notnull(ctx)); - OUT_OF_SPACE_IF_NULL(self = sym_new_known_notnull(ctx)); + OUT_OF_SPACE_IF_NULL(func = _Py_uop_sym_new_not_null(ctx)); + OUT_OF_SPACE_IF_NULL(self = _Py_uop_sym_new_not_null(ctx)); stack_pointer[-2 - oparg] = func; stack_pointer[-1 - oparg] = self; break; @@ -1401,7 +1401,7 @@ self_or_null = stack_pointer[-1 - oparg]; callable = stack_pointer[-2 - oparg]; uint32_t func_version = (uint32_t)this_instr->operand; - sym_set_type(callable, &PyFunction_Type); + _Py_uop_sym_set_type(callable, &PyFunction_Type); (void)self_or_null; (void)func_version; break; @@ -1428,7 +1428,7 @@ PyCodeObject *co = (PyCodeObject *)func->func_code; assert(self_or_null != NULL); assert(args != NULL); - if (sym_is_not_null(self_or_null)) { + if (_Py_uop_sym_is_not_null(self_or_null)) { // Bound method fiddling, same as _INIT_CALL_PY_EXACT_ARGS in VM args--; argcount++; @@ -1438,12 +1438,12 @@ // Can determine statically, so we interleave the new locals // and make the current stack the new locals. // This also sets up for true call inlining. - if (sym_is_known(self_or_null)) { + if (_Py_uop_sym_is_null(self_or_null) || _Py_uop_sym_is_not_null(self_or_null)) { localsplus_start = args; n_locals_already_filled = argcount; } OUT_OF_SPACE_IF_NULL(new_frame = - ctx_frame_new(ctx, co, localsplus_start, n_locals_already_filled, 0)); + _Py_uop_ctx_frame_new(ctx, co, localsplus_start, n_locals_already_filled, 0)); stack_pointer[-2 - oparg] = (_Py_UOpsSymType *)new_frame; stack_pointer += -1 - oparg; break; @@ -1464,7 +1464,7 @@ case _CALL_TYPE_1: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-2 - oparg] = res; stack_pointer += -1 - oparg; @@ -1473,7 +1473,7 @@ case _CALL_STR_1: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-2 - oparg] = res; stack_pointer += -1 - oparg; @@ -1482,7 +1482,7 @@ case _CALL_TUPLE_1: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-2 - oparg] = res; stack_pointer += -1 - oparg; @@ -1498,7 +1498,7 @@ case _CALL_BUILTIN_CLASS: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-2 - oparg] = res; stack_pointer += -1 - oparg; @@ -1507,7 +1507,7 @@ case _CALL_BUILTIN_O: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-2 - oparg] = res; stack_pointer += -1 - oparg; @@ -1516,7 +1516,7 @@ case _CALL_BUILTIN_FAST: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-2 - oparg] = res; stack_pointer += -1 - oparg; @@ -1525,7 +1525,7 @@ case _CALL_BUILTIN_FAST_WITH_KEYWORDS: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-2 - oparg] = res; stack_pointer += -1 - oparg; @@ -1534,7 +1534,7 @@ case _CALL_LEN: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-2 - oparg] = res; stack_pointer += -1 - oparg; @@ -1543,7 +1543,7 @@ case _CALL_ISINSTANCE: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-2 - oparg] = res; stack_pointer += -1 - oparg; @@ -1552,7 +1552,7 @@ case _CALL_METHOD_DESCRIPTOR_O: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-2 - oparg] = res; stack_pointer += -1 - oparg; @@ -1561,7 +1561,7 @@ case _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-2 - oparg] = res; stack_pointer += -1 - oparg; @@ -1570,7 +1570,7 @@ case _CALL_METHOD_DESCRIPTOR_NOARGS: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-2 - oparg] = res; stack_pointer += -1 - oparg; @@ -1579,7 +1579,7 @@ case _CALL_METHOD_DESCRIPTOR_FAST: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-2 - oparg] = res; stack_pointer += -1 - oparg; @@ -1596,7 +1596,7 @@ case _MAKE_FUNCTION: { _Py_UOpsSymType *func; - func = sym_new_unknown(ctx); + func = _Py_uop_sym_new_unknown(ctx); if (func == NULL) goto out_of_space; stack_pointer[-1] = func; break; @@ -1604,7 +1604,7 @@ case _SET_FUNCTION_ATTRIBUTE: { _Py_UOpsSymType *func; - func = sym_new_unknown(ctx); + func = _Py_uop_sym_new_unknown(ctx); if (func == NULL) goto out_of_space; stack_pointer[-2] = func; stack_pointer += -1; @@ -1613,7 +1613,7 @@ case _BUILD_SLICE: { _Py_UOpsSymType *slice; - slice = sym_new_unknown(ctx); + slice = _Py_uop_sym_new_unknown(ctx); if (slice == NULL) goto out_of_space; stack_pointer[-2 - ((oparg == 3) ? 1 : 0)] = slice; stack_pointer += -1 - ((oparg == 3) ? 1 : 0); @@ -1622,7 +1622,7 @@ case _CONVERT_VALUE: { _Py_UOpsSymType *result; - result = sym_new_unknown(ctx); + result = _Py_uop_sym_new_unknown(ctx); if (result == NULL) goto out_of_space; stack_pointer[-1] = result; break; @@ -1630,7 +1630,7 @@ case _FORMAT_SIMPLE: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-1] = res; break; @@ -1638,7 +1638,7 @@ case _FORMAT_WITH_SPEC: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-2] = res; stack_pointer += -1; @@ -1658,7 +1658,7 @@ case _BINARY_OP: { _Py_UOpsSymType *res; - res = sym_new_unknown(ctx); + res = _Py_uop_sym_new_unknown(ctx); if (res == NULL) goto out_of_space; stack_pointer[-2] = res; stack_pointer += -1; @@ -1732,7 +1732,7 @@ case _LOAD_CONST_INLINE: { _Py_UOpsSymType *value; PyObject *ptr = (PyObject *)this_instr->operand; - OUT_OF_SPACE_IF_NULL(value = sym_new_const(ctx, ptr)); + OUT_OF_SPACE_IF_NULL(value = _Py_uop_sym_new_const(ctx, ptr)); stack_pointer[0] = value; stack_pointer += 1; break; @@ -1741,7 +1741,7 @@ case _LOAD_CONST_INLINE_BORROW: { _Py_UOpsSymType *value; PyObject *ptr = (PyObject *)this_instr->operand; - OUT_OF_SPACE_IF_NULL(value = sym_new_const(ctx, ptr)); + OUT_OF_SPACE_IF_NULL(value = _Py_uop_sym_new_const(ctx, ptr)); stack_pointer[0] = value; stack_pointer += 1; break; @@ -1751,8 +1751,8 @@ _Py_UOpsSymType *value; _Py_UOpsSymType *null; PyObject *ptr = (PyObject *)this_instr->operand; - OUT_OF_SPACE_IF_NULL(value = sym_new_const(ctx, ptr)); - OUT_OF_SPACE_IF_NULL(null = sym_new_null(ctx)); + OUT_OF_SPACE_IF_NULL(value = _Py_uop_sym_new_const(ctx, ptr)); + OUT_OF_SPACE_IF_NULL(null = _Py_uop_sym_new_null(ctx)); stack_pointer[0] = value; stack_pointer[1] = null; stack_pointer += 2; @@ -1763,8 +1763,8 @@ _Py_UOpsSymType *value; _Py_UOpsSymType *null; PyObject *ptr = (PyObject *)this_instr->operand; - OUT_OF_SPACE_IF_NULL(value = sym_new_const(ctx, ptr)); - OUT_OF_SPACE_IF_NULL(null = sym_new_null(ctx)); + OUT_OF_SPACE_IF_NULL(value = _Py_uop_sym_new_const(ctx, ptr)); + OUT_OF_SPACE_IF_NULL(null = _Py_uop_sym_new_null(ctx)); stack_pointer[0] = value; stack_pointer[1] = null; stack_pointer += 2; diff --git a/Python/optimizer_symbols.c b/Python/optimizer_symbols.c new file mode 100644 index 0000000..1b7c88c --- /dev/null +++ b/Python/optimizer_symbols.c @@ -0,0 +1,332 @@ + +#include "Python.h" + +#include "cpython/optimizer.h" +#include "pycore_code.h" +#include "pycore_frame.h" +#include "pycore_optimizer.h" + +#include +#include +#include + +// Flags for below. +#define KNOWN 1 << 0 +#define TRUE_CONST 1 << 1 +#define IS_NULL 1 << 2 +#define NOT_NULL 1 << 3 + +#ifdef Py_DEBUG +static inline int get_lltrace(void) { + char *uop_debug = Py_GETENV("PYTHON_OPT_DEBUG"); + int lltrace = 0; + if (uop_debug != NULL && *uop_debug >= '0') { + lltrace = *uop_debug - '0'; // TODO: Parse an int and all that + } + return lltrace; +} +#define DPRINTF(level, ...) \ + if (get_lltrace() >= (level)) { printf(__VA_ARGS__); } +#else +#define DPRINTF(level, ...) +#endif + +// Takes a borrowed reference to const_val, turns that into a strong reference. +static _Py_UOpsSymType* +sym_new(_Py_UOpsAbstractInterpContext *ctx, PyObject *const_val) +{ + _Py_UOpsSymType *self = &ctx->t_arena.arena[ctx->t_arena.ty_curr_number]; + if (ctx->t_arena.ty_curr_number >= ctx->t_arena.ty_max_number) { + OPT_STAT_INC(optimizer_failure_reason_no_memory); + DPRINTF(1, "out of space for symbolic expression type\n"); + return NULL; + } + ctx->t_arena.ty_curr_number++; + self->const_val = NULL; + self->typ = NULL; + self->flags = 0; + + if (const_val != NULL) { + self->const_val = Py_NewRef(const_val); + } + + return self; +} + +static inline void +sym_set_flag(_Py_UOpsSymType *sym, int flag) +{ + sym->flags |= flag; +} + +static inline bool +sym_has_flag(_Py_UOpsSymType *sym, int flag) +{ + return (sym->flags & flag) != 0; +} + +bool +_Py_uop_sym_is_not_null(_Py_UOpsSymType *sym) +{ + return (sym->flags & (IS_NULL | NOT_NULL)) == NOT_NULL; +} + +bool +_Py_uop_sym_is_null(_Py_UOpsSymType *sym) +{ + return (sym->flags & (IS_NULL | NOT_NULL)) == IS_NULL; +} + +bool +_Py_uop_sym_is_const(_Py_UOpsSymType *sym) +{ + return (sym->flags & TRUE_CONST) != 0; +} + +PyObject * +_Py_uop_sym_get_const(_Py_UOpsSymType *sym) +{ + assert(_Py_uop_sym_is_const(sym)); + assert(sym->const_val); + return sym->const_val; +} + +void +_Py_uop_sym_set_type(_Py_UOpsSymType *sym, PyTypeObject *tp) +{ + assert(PyType_Check(tp)); + sym->typ = tp; + sym_set_flag(sym, KNOWN); + sym_set_flag(sym, NOT_NULL); +} + +void +_Py_uop_sym_set_null(_Py_UOpsSymType *sym) +{ + sym_set_flag(sym, IS_NULL); + sym_set_flag(sym, KNOWN); +} + + +_Py_UOpsSymType * +_Py_uop_sym_new_unknown(_Py_UOpsAbstractInterpContext *ctx) +{ + return sym_new(ctx,NULL); +} + +_Py_UOpsSymType * +_Py_uop_sym_new_not_null(_Py_UOpsAbstractInterpContext *ctx) +{ + _Py_UOpsSymType *res = _Py_uop_sym_new_unknown(ctx); + if (res == NULL) { + return NULL; + } + sym_set_flag(res, KNOWN); + sym_set_flag(res, NOT_NULL); + return res; +} + +_Py_UOpsSymType * +_Py_uop_sym_new_type(_Py_UOpsAbstractInterpContext *ctx, + PyTypeObject *typ) +{ + _Py_UOpsSymType *res = sym_new(ctx,NULL); + if (res == NULL) { + return NULL; + } + _Py_uop_sym_set_type(res, typ); + return res; +} + +// Takes a borrowed reference to const_val. +_Py_UOpsSymType* +_Py_uop_sym_new_const(_Py_UOpsAbstractInterpContext *ctx, PyObject *const_val) +{ + assert(const_val != NULL); + _Py_UOpsSymType *temp = sym_new( + ctx, + const_val + ); + if (temp == NULL) { + return NULL; + } + _Py_uop_sym_set_type(temp, Py_TYPE(const_val)); + sym_set_flag(temp, TRUE_CONST); + sym_set_flag(temp, KNOWN); + sym_set_flag(temp, NOT_NULL); + return temp; +} + +_Py_UOpsSymType* +_Py_uop_sym_new_null(_Py_UOpsAbstractInterpContext *ctx) +{ + _Py_UOpsSymType *null_sym = _Py_uop_sym_new_unknown(ctx); + if (null_sym == NULL) { + return NULL; + } + _Py_uop_sym_set_null(null_sym); + return null_sym; +} + +bool +_Py_uop_sym_matches_type(_Py_UOpsSymType *sym, PyTypeObject *typ) +{ + assert(typ == NULL || PyType_Check(typ)); + if (!sym_has_flag(sym, KNOWN)) { + return false; + } + return sym->typ == typ; +} + +// 0 on success, -1 on error. +_Py_UOpsAbstractFrame * +_Py_uop_ctx_frame_new( + _Py_UOpsAbstractInterpContext *ctx, + PyCodeObject *co, + _Py_UOpsSymType **localsplus_start, + int n_locals_already_filled, + int curr_stackentries +) +{ + assert(ctx->curr_frame_depth < MAX_ABSTRACT_FRAME_DEPTH); + _Py_UOpsAbstractFrame *frame = &ctx->frames[ctx->curr_frame_depth]; + + frame->stack_len = co->co_stacksize; + frame->locals_len = co->co_nlocalsplus; + + frame->locals = localsplus_start; + frame->stack = frame->locals + co->co_nlocalsplus; + frame->stack_pointer = frame->stack + curr_stackentries; + ctx->n_consumed = localsplus_start + (co->co_nlocalsplus + co->co_stacksize); + if (ctx->n_consumed >= ctx->limit) { + return NULL; + } + + + // Initialize with the initial state of all local variables + for (int i = n_locals_already_filled; i < co->co_nlocalsplus; i++) { + _Py_UOpsSymType *local = _Py_uop_sym_new_unknown(ctx); + if (local == NULL) { + return NULL; + } + frame->locals[i] = local; + } + + + // Initialize the stack as well + for (int i = 0; i < curr_stackentries; i++) { + _Py_UOpsSymType *stackvar = _Py_uop_sym_new_unknown(ctx); + if (stackvar == NULL) { + return NULL; + } + frame->stack[i] = stackvar; + } + + return frame; +} + +void +_Py_uop_abstractcontext_fini(_Py_UOpsAbstractInterpContext *ctx) +{ + if (ctx == NULL) { + return; + } + ctx->curr_frame_depth = 0; + int tys = ctx->t_arena.ty_curr_number; + for (int i = 0; i < tys; i++) { + Py_CLEAR(ctx->t_arena.arena[i].const_val); + } +} + +int +_Py_uop_abstractcontext_init( + _Py_UOpsAbstractInterpContext *ctx +) +{ + ctx->limit = ctx->locals_and_stack + MAX_ABSTRACT_INTERP_SIZE; + ctx->n_consumed = ctx->locals_and_stack; +#ifdef Py_DEBUG // Aids debugging a little. There should never be NULL in the abstract interpreter. + for (int i = 0 ; i < MAX_ABSTRACT_INTERP_SIZE; i++) { + ctx->locals_and_stack[i] = NULL; + } +#endif + + // Setup the arena for sym expressions. + ctx->t_arena.ty_curr_number = 0; + ctx->t_arena.ty_max_number = TY_ARENA_SIZE; + + // Frame setup + ctx->curr_frame_depth = 0; + + return 0; +} + +int +_Py_uop_ctx_frame_pop( + _Py_UOpsAbstractInterpContext *ctx +) +{ + _Py_UOpsAbstractFrame *frame = ctx->frame; + + ctx->n_consumed = frame->locals; + ctx->curr_frame_depth--; + assert(ctx->curr_frame_depth >= 1); + ctx->frame = &ctx->frames[ctx->curr_frame_depth - 1]; + + return 0; +} + +#define TEST_PREDICATE(PRED, MSG) \ +do { \ + if (!(PRED)) { \ + PyErr_SetString( \ + PyExc_AssertionError, \ + (MSG)); \ + goto fail; \ + } \ +} while (0) + +/* +static _Py_UOpsSymType * +make_bottom(_Py_UOpsAbstractInterpContext *ctx) +{ + _Py_UOpsSymType *sym = _Py_uop_sym_new_unknown(ctx); + _Py_uop_sym_set_null(sym); + _Py_uop_sym_set_type(sym, &PyLong_Type); + return sym; +}*/ + +PyObject * +_Py_uop_symbols_test(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(ignored)) +{ + _Py_UOpsAbstractInterpContext context; + _Py_UOpsAbstractInterpContext *ctx = &context; + _Py_uop_abstractcontext_init(ctx); + + _Py_UOpsSymType *top = _Py_uop_sym_new_unknown(ctx); + if (top == NULL) { + return NULL; + } + TEST_PREDICATE(!_Py_uop_sym_is_null(top), "unknown is NULL"); + TEST_PREDICATE(!_Py_uop_sym_is_not_null(top), "unknown is not NULL"); + TEST_PREDICATE(!_Py_uop_sym_is_const(top), "unknown is a constant"); + // TEST_PREDICATE(_Py_uop_sym_get_const(top) == NULL, "unknown as constant is not NULL"); + + // _Py_UOpsSymType *bottom = make_bottom(ctx); + // TEST_PREDICATE(_Py_uop_sym_is_null(bottom), "bottom is NULL is not true"); + // TEST_PREDICATE(_Py_uop_sym_is_not_null(bottom), "bottom is not NULL is not true"); + // TEST_PREDICATE(_Py_uop_sym_is_const(bottom), "bottom is a constant is not true"); + + _Py_UOpsSymType *int_type = _Py_uop_sym_new_type(ctx, &PyLong_Type); + TEST_PREDICATE(_Py_uop_sym_matches_type(int_type, &PyLong_Type), "inconsistent type"); + _Py_uop_sym_set_type(int_type, &PyLong_Type); + TEST_PREDICATE(_Py_uop_sym_matches_type(int_type, &PyLong_Type), "inconsistent type"); + _Py_uop_sym_set_type(int_type, &PyFloat_Type); + // TEST_PREDICATE(_Py_uop_sym_matches_type(int_type, &PyLong_Type), "bottom doesn't match int"); + + _Py_uop_abstractcontext_fini(ctx); + Py_RETURN_NONE; +fail: + _Py_uop_abstractcontext_fini(ctx); + return NULL; +} diff --git a/Tools/c-analyzer/cpython/ignored.tsv b/Tools/c-analyzer/cpython/ignored.tsv index e9b81cf..0f212ec 100644 --- a/Tools/c-analyzer/cpython/ignored.tsv +++ b/Tools/c-analyzer/cpython/ignored.tsv @@ -740,6 +740,4 @@ Modules/expat/xmlrole.c - error - ## other Modules/_io/_iomodule.c - _PyIO_Module - Modules/_sqlite/module.c - _sqlite3module - -Python/optimizer_analysis.c - _Py_UOpsAbstractFrame_Type - -Python/optimizer_analysis.c - _Py_UOpsAbstractInterpContext_Type - Modules/clinic/md5module.c.h _md5_md5 _keywords - diff --git a/Tools/cases_generator/optimizer_generator.py b/Tools/cases_generator/optimizer_generator.py index aa3f4ec..f110a74 100644 --- a/Tools/cases_generator/optimizer_generator.py +++ b/Tools/cases_generator/optimizer_generator.py @@ -87,14 +87,14 @@ def emit_default(out: CWriter, uop: Uop) -> None: if var.name != "unused" and not var.peek: if var.is_array(): out.emit(f"for (int _i = {var.size}; --_i >= 0;) {{\n") - out.emit(f"{var.name}[_i] = sym_new_unknown(ctx);\n") + out.emit(f"{var.name}[_i] = _Py_uop_sym_new_unknown(ctx);\n") out.emit(f"if ({var.name}[_i] == NULL) goto out_of_space;\n") out.emit("}\n") elif var.name == "null": - out.emit(f"{var.name} = sym_new_null(ctx);\n") + out.emit(f"{var.name} = _Py_uop_sym_new_null(ctx);\n") out.emit(f"if ({var.name} == NULL) goto out_of_space;\n") else: - out.emit(f"{var.name} = sym_new_unknown(ctx);\n") + out.emit(f"{var.name} = _Py_uop_sym_new_unknown(ctx);\n") out.emit(f"if ({var.name} == NULL) goto out_of_space;\n") -- cgit v0.12