Skip to content

Commit 10fbcd6

Browse files
authored
GH-115816: Make tier2 optimizer symbols testable, and add a few tests. (GH-115953)
1 parent af5f9d6 commit 10fbcd6

15 files changed

+720
-607
lines changed

Include/internal/pycore_optimizer.h

+85
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ extern "C" {
99
#endif
1010

1111
#include "pycore_uop_ids.h"
12+
#include <stdbool.h>
1213

1314
// This is the length of the trace we project initially.
1415
#define UOP_MAX_TRACE_LENGTH 512
@@ -25,6 +26,90 @@ extern PyTypeObject _PyDefaultOptimizer_Type;
2526
extern PyTypeObject _PyUOpExecutor_Type;
2627
extern PyTypeObject _PyUOpOptimizer_Type;
2728

29+
/* Symbols */
30+
31+
struct _Py_UOpsSymType {
32+
int flags;
33+
PyTypeObject *typ;
34+
// constant propagated value (might be NULL)
35+
PyObject *const_val;
36+
};
37+
38+
// Holds locals, stack, locals, stack ... co_consts (in that order)
39+
#define MAX_ABSTRACT_INTERP_SIZE 4096
40+
41+
#define OVERALLOCATE_FACTOR 5
42+
43+
#define TY_ARENA_SIZE (UOP_MAX_TRACE_LENGTH * OVERALLOCATE_FACTOR)
44+
45+
// Need extras for root frame and for overflow frame (see TRACE_STACK_PUSH())
46+
#define MAX_ABSTRACT_FRAME_DEPTH (TRACE_STACK_SIZE + 2)
47+
48+
typedef struct _Py_UOpsSymType _Py_UOpsSymType;
49+
50+
struct _Py_UOpsAbstractFrame {
51+
// Max stacklen
52+
int stack_len;
53+
int locals_len;
54+
55+
_Py_UOpsSymType **stack_pointer;
56+
_Py_UOpsSymType **stack;
57+
_Py_UOpsSymType **locals;
58+
};
59+
60+
typedef struct _Py_UOpsAbstractFrame _Py_UOpsAbstractFrame;
61+
62+
typedef struct ty_arena {
63+
int ty_curr_number;
64+
int ty_max_number;
65+
_Py_UOpsSymType arena[TY_ARENA_SIZE];
66+
} ty_arena;
67+
68+
struct _Py_UOpsAbstractInterpContext {
69+
PyObject_HEAD
70+
// The current "executing" frame.
71+
_Py_UOpsAbstractFrame *frame;
72+
_Py_UOpsAbstractFrame frames[MAX_ABSTRACT_FRAME_DEPTH];
73+
int curr_frame_depth;
74+
75+
// Arena for the symbolic types.
76+
ty_arena t_arena;
77+
78+
_Py_UOpsSymType **n_consumed;
79+
_Py_UOpsSymType **limit;
80+
_Py_UOpsSymType *locals_and_stack[MAX_ABSTRACT_INTERP_SIZE];
81+
};
82+
83+
typedef struct _Py_UOpsAbstractInterpContext _Py_UOpsAbstractInterpContext;
84+
85+
extern bool _Py_uop_sym_is_null(_Py_UOpsSymType *sym);
86+
extern bool _Py_uop_sym_is_not_null(_Py_UOpsSymType *sym);
87+
extern bool _Py_uop_sym_is_const(_Py_UOpsSymType *sym);
88+
extern PyObject *_Py_uop_sym_get_const(_Py_UOpsSymType *sym);
89+
extern _Py_UOpsSymType *_Py_uop_sym_new_unknown(_Py_UOpsAbstractInterpContext *ctx);
90+
extern _Py_UOpsSymType *_Py_uop_sym_new_not_null(_Py_UOpsAbstractInterpContext *ctx);
91+
extern _Py_UOpsSymType *_Py_uop_sym_new_type(
92+
_Py_UOpsAbstractInterpContext *ctx, PyTypeObject *typ);
93+
extern _Py_UOpsSymType *_Py_uop_sym_new_const(_Py_UOpsAbstractInterpContext *ctx, PyObject *const_val);
94+
extern _Py_UOpsSymType *_Py_uop_sym_new_null(_Py_UOpsAbstractInterpContext *ctx);
95+
extern bool _Py_uop_sym_matches_type(_Py_UOpsSymType *sym, PyTypeObject *typ);
96+
extern void _Py_uop_sym_set_null(_Py_UOpsSymType *sym);
97+
extern void _Py_uop_sym_set_type(_Py_UOpsSymType *sym, PyTypeObject *tp);
98+
99+
extern int _Py_uop_abstractcontext_init(_Py_UOpsAbstractInterpContext *ctx);
100+
extern void _Py_uop_abstractcontext_fini(_Py_UOpsAbstractInterpContext *ctx);
101+
102+
extern _Py_UOpsAbstractFrame *_Py_uop_ctx_frame_new(
103+
_Py_UOpsAbstractInterpContext *ctx,
104+
PyCodeObject *co,
105+
_Py_UOpsSymType **localsplus_start,
106+
int n_locals_already_filled,
107+
int curr_stackentries);
108+
extern int _Py_uop_ctx_frame_pop(_Py_UOpsAbstractInterpContext *ctx);
109+
110+
PyAPI_FUNC(PyObject *)
111+
_Py_uop_symbols_test(PyObject *self, PyObject *ignored);
112+
28113
#ifdef __cplusplus
29114
}
30115
#endif

Lib/test/test_generated_cases.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -900,7 +900,7 @@ def test_overridden_abstract_args(self):
900900
901901
case OP2: {
902902
_Py_UOpsSymType *out;
903-
out = sym_new_unknown(ctx);
903+
out = _Py_uop_sym_new_unknown(ctx);
904904
if (out == NULL) goto out_of_space;
905905
stack_pointer[-1] = out;
906906
break;
@@ -925,7 +925,7 @@ def test_no_overridden_case(self):
925925
output = """
926926
case OP: {
927927
_Py_UOpsSymType *out;
928-
out = sym_new_unknown(ctx);
928+
out = _Py_uop_sym_new_unknown(ctx);
929929
if (out == NULL) goto out_of_space;
930930
stack_pointer[-1] = out;
931931
break;

Lib/test/test_optimizer.py

+7
Original file line numberDiff line numberDiff line change
@@ -77,5 +77,12 @@ def func(x=0):
7777
_testinternalcapi.get_rare_event_counters()["func_modification"]
7878
)
7979

80+
81+
class TestOptimizerSymbols(unittest.TestCase):
82+
83+
def test_optimizer_symbols(self):
84+
_testinternalcapi.uop_symbols_test()
85+
86+
8087
if __name__ == "__main__":
8188
unittest.main()

Makefile.pre.in

+1
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,7 @@ PYTHON_OBJS= \
446446
Python/object_stack.o \
447447
Python/optimizer.o \
448448
Python/optimizer_analysis.o \
449+
Python/optimizer_symbols.o \
449450
Python/parking_lot.o \
450451
Python/pathconfig.o \
451452
Python/preconfig.o \

Modules/_testinternalcapi.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "pycore_interp.h" // _PyInterpreterState_GetConfigCopy()
2525
#include "pycore_long.h" // _PyLong_Sign()
2626
#include "pycore_object.h" // _PyObject_IsFreed()
27+
#include "pycore_optimizer.h" // _Py_UOpsSymType, etc.
2728
#include "pycore_pathconfig.h" // _PyPathConfig_ClearGlobal()
2829
#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1()
2930
#include "pycore_pystate.h" // _PyThreadState_GET()
@@ -1677,7 +1678,6 @@ get_py_thread_id(PyObject *self, PyObject *Py_UNUSED(ignored))
16771678
}
16781679
#endif
16791680

1680-
16811681
static PyMethodDef module_functions[] = {
16821682
{"get_configs", get_configs, METH_NOARGS},
16831683
{"get_recursion_depth", get_recursion_depth, METH_NOARGS},
@@ -1747,6 +1747,7 @@ static PyMethodDef module_functions[] = {
17471747
#ifdef Py_GIL_DISABLED
17481748
{"py_thread_id", get_py_thread_id, METH_NOARGS},
17491749
#endif
1750+
{"uop_symbols_test", _Py_uop_symbols_test, METH_NOARGS},
17501751
{NULL, NULL} /* sentinel */
17511752
};
17521753

PCbuild/_freeze_module.vcxproj

+1
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@
235235
<ClCompile Include="..\Python\object_stack.c" />
236236
<ClCompile Include="..\Python\optimizer.c" />
237237
<ClCompile Include="..\Python\optimizer_analysis.c" />
238+
<ClCompile Include="..\Python\optimizer_symbols.c" />
238239
<ClCompile Include="..\Python\parking_lot.c" />
239240
<ClCompile Include="..\Python\pathconfig.c" />
240241
<ClCompile Include="..\Python\perf_trampoline.c" />

PCbuild/_freeze_module.vcxproj.filters

+3
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,9 @@
310310
<ClCompile Include="..\Python\optimizer_analysis.c">
311311
<Filter>Source Files</Filter>
312312
</ClCompile>
313+
<ClCompile Include="..\Python\optimizer_symbols.c">
314+
<Filter>Python</Filter>
315+
</ClCompile>
313316
<ClCompile Include="..\Parser\parser.c">
314317
<Filter>Source Files</Filter>
315318
</ClCompile>

PCbuild/pythoncore.vcxproj

+1
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,7 @@
601601
<ClCompile Include="..\Python\object_stack.c" />
602602
<ClCompile Include="..\Python\optimizer.c" />
603603
<ClCompile Include="..\Python\optimizer_analysis.c" />
604+
<ClCompile Include="..\Python\optimizer_symbols.c" />
604605
<ClCompile Include="..\Python\parking_lot.c" />
605606
<ClCompile Include="..\Python\pathconfig.c" />
606607
<ClCompile Include="..\Python\perf_trampoline.c" />

PCbuild/pythoncore.vcxproj.filters

+3
Original file line numberDiff line numberDiff line change
@@ -1382,6 +1382,9 @@
13821382
<ClCompile Include="..\Python\optimizer_analysis.c">
13831383
<Filter>Python</Filter>
13841384
</ClCompile>
1385+
<ClCompile Include="..\Python\optimizer_symbols.c">
1386+
<Filter>Python</Filter>
1387+
</ClCompile>
13851388
<ClCompile Include="..\Python\parking_lot.c">
13861389
<Filter>Python</Filter>
13871390
</ClCompile>

0 commit comments

Comments
 (0)