Skip to content

Commit 7929a57

Browse files
committed
Add "truth" symbols
1 parent d0f236a commit 7929a57

File tree

5 files changed

+209
-136
lines changed

5 files changed

+209
-136
lines changed

Include/internal/pycore_optimizer.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ typedef enum _JitSymType {
172172
JIT_SYM_KNOWN_CLASS_TAG = 6,
173173
JIT_SYM_KNOWN_VALUE_TAG = 7,
174174
JIT_SYM_TUPLE_TAG = 8,
175+
JIT_SYM_TRUTH_TAG = 9,
175176
} JitSymType;
176177

177178
typedef struct _jit_opt_known_class {
@@ -198,12 +199,19 @@ typedef struct _jit_opt_tuple {
198199
uint16_t items[MAX_SYMBOLIC_TUPLE_SIZE];
199200
} JitOptTuple;
200201

202+
typedef struct {
203+
uint8_t tag;
204+
bool not;
205+
uint16_t value;
206+
} JitOptTruth;
207+
201208
typedef union _jit_opt_symbol {
202209
uint8_t tag;
203210
JitOptKnownClass cls;
204211
JitOptKnownValue value;
205212
JitOptKnownVersion version;
206213
JitOptTuple tuple;
214+
JitOptTruth truth;
207215
} JitOptSymbol;
208216

209217

@@ -245,8 +253,8 @@ typedef struct _JitOptContext {
245253

246254
extern bool _Py_uop_sym_is_null(JitOptSymbol *sym);
247255
extern bool _Py_uop_sym_is_not_null(JitOptSymbol *sym);
248-
extern bool _Py_uop_sym_is_const(JitOptSymbol *sym);
249-
extern PyObject *_Py_uop_sym_get_const(JitOptSymbol *sym);
256+
extern bool _Py_uop_sym_is_const(JitOptContext *ctx, JitOptSymbol *sym);
257+
extern PyObject *_Py_uop_sym_get_const(JitOptContext *ctx, JitOptSymbol *sym);
250258
extern JitOptSymbol *_Py_uop_sym_new_unknown(JitOptContext *ctx);
251259
extern JitOptSymbol *_Py_uop_sym_new_not_null(JitOptContext *ctx);
252260
extern JitOptSymbol *_Py_uop_sym_new_type(
@@ -262,7 +270,7 @@ extern void _Py_uop_sym_set_type(JitOptContext *ctx, JitOptSymbol *sym, PyTypeOb
262270
extern bool _Py_uop_sym_set_type_version(JitOptContext *ctx, JitOptSymbol *sym, unsigned int version);
263271
extern void _Py_uop_sym_set_const(JitOptContext *ctx, JitOptSymbol *sym, PyObject *const_val);
264272
extern bool _Py_uop_sym_is_bottom(JitOptSymbol *sym);
265-
extern int _Py_uop_sym_truthiness(JitOptSymbol *sym);
273+
extern int _Py_uop_sym_truthiness(JitOptContext *ctx, JitOptSymbol *sym);
266274
extern PyTypeObject *_Py_uop_sym_get_type(JitOptSymbol *sym);
267275
extern bool _Py_uop_sym_is_immortal(JitOptSymbol *sym);
268276
extern JitOptSymbol *_Py_uop_sym_new_tuple(JitOptContext *ctx, int size, JitOptSymbol **args);

Python/optimizer_analysis.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ optimize_to_bool(
389389
*result_ptr = value;
390390
return 1;
391391
}
392-
int truthiness = sym_truthiness(value);
392+
int truthiness = sym_truthiness(ctx, value);
393393
if (truthiness >= 0) {
394394
PyObject *load = truthiness ? Py_True : Py_False;
395395
REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)load);

Python/optimizer_bytecodes.c

Lines changed: 56 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -198,11 +198,11 @@ dummy_func(void) {
198198
// Case C:
199199
res = sym_new_type(ctx, &PyFloat_Type);
200200
}
201-
else if (!sym_is_const(right)) {
201+
else if (!sym_is_const(ctx, right)) {
202202
// Case A or B... can't know without the sign of the RHS:
203203
res = sym_new_unknown(ctx);
204204
}
205-
else if (_PyLong_IsNegative((PyLongObject *)sym_get_const(right))) {
205+
else if (_PyLong_IsNegative((PyLongObject *)sym_get_const(ctx, right))) {
206206
// Case B:
207207
res = sym_new_type(ctx, &PyFloat_Type);
208208
}
@@ -223,13 +223,13 @@ dummy_func(void) {
223223
}
224224

225225
op(_BINARY_OP_ADD_INT, (left, right -- res)) {
226-
if (sym_is_const(left) && sym_is_const(right) &&
226+
if (sym_is_const(ctx, left) && sym_is_const(ctx, right) &&
227227
sym_matches_type(left, &PyLong_Type) && sym_matches_type(right, &PyLong_Type))
228228
{
229-
assert(PyLong_CheckExact(sym_get_const(left)));
230-
assert(PyLong_CheckExact(sym_get_const(right)));
231-
PyObject *temp = _PyLong_Add((PyLongObject *)sym_get_const(left),
232-
(PyLongObject *)sym_get_const(right));
229+
assert(PyLong_CheckExact(sym_get_const(ctx, left)));
230+
assert(PyLong_CheckExact(sym_get_const(ctx, right)));
231+
PyObject *temp = _PyLong_Add((PyLongObject *)sym_get_const(ctx, left),
232+
(PyLongObject *)sym_get_const(ctx, right));
233233
if (temp == NULL) {
234234
goto error;
235235
}
@@ -244,13 +244,13 @@ dummy_func(void) {
244244
}
245245

246246
op(_BINARY_OP_SUBTRACT_INT, (left, right -- res)) {
247-
if (sym_is_const(left) && sym_is_const(right) &&
247+
if (sym_is_const(ctx, left) && sym_is_const(ctx, right) &&
248248
sym_matches_type(left, &PyLong_Type) && sym_matches_type(right, &PyLong_Type))
249249
{
250-
assert(PyLong_CheckExact(sym_get_const(left)));
251-
assert(PyLong_CheckExact(sym_get_const(right)));
252-
PyObject *temp = _PyLong_Subtract((PyLongObject *)sym_get_const(left),
253-
(PyLongObject *)sym_get_const(right));
250+
assert(PyLong_CheckExact(sym_get_const(ctx, left)));
251+
assert(PyLong_CheckExact(sym_get_const(ctx, right)));
252+
PyObject *temp = _PyLong_Subtract((PyLongObject *)sym_get_const(ctx, left),
253+
(PyLongObject *)sym_get_const(ctx, right));
254254
if (temp == NULL) {
255255
goto error;
256256
}
@@ -265,13 +265,13 @@ dummy_func(void) {
265265
}
266266

267267
op(_BINARY_OP_MULTIPLY_INT, (left, right -- res)) {
268-
if (sym_is_const(left) && sym_is_const(right) &&
268+
if (sym_is_const(ctx, left) && sym_is_const(ctx, right) &&
269269
sym_matches_type(left, &PyLong_Type) && sym_matches_type(right, &PyLong_Type))
270270
{
271-
assert(PyLong_CheckExact(sym_get_const(left)));
272-
assert(PyLong_CheckExact(sym_get_const(right)));
273-
PyObject *temp = _PyLong_Multiply((PyLongObject *)sym_get_const(left),
274-
(PyLongObject *)sym_get_const(right));
271+
assert(PyLong_CheckExact(sym_get_const(ctx, left)));
272+
assert(PyLong_CheckExact(sym_get_const(ctx, right)));
273+
PyObject *temp = _PyLong_Multiply((PyLongObject *)sym_get_const(ctx, left),
274+
(PyLongObject *)sym_get_const(ctx, right));
275275
if (temp == NULL) {
276276
goto error;
277277
}
@@ -286,14 +286,14 @@ dummy_func(void) {
286286
}
287287

288288
op(_BINARY_OP_ADD_FLOAT, (left, right -- res)) {
289-
if (sym_is_const(left) && sym_is_const(right) &&
289+
if (sym_is_const(ctx, left) && sym_is_const(ctx, right) &&
290290
sym_matches_type(left, &PyFloat_Type) && sym_matches_type(right, &PyFloat_Type))
291291
{
292-
assert(PyFloat_CheckExact(sym_get_const(left)));
293-
assert(PyFloat_CheckExact(sym_get_const(right)));
292+
assert(PyFloat_CheckExact(sym_get_const(ctx, left)));
293+
assert(PyFloat_CheckExact(sym_get_const(ctx, right)));
294294
PyObject *temp = PyFloat_FromDouble(
295-
PyFloat_AS_DOUBLE(sym_get_const(left)) +
296-
PyFloat_AS_DOUBLE(sym_get_const(right)));
295+
PyFloat_AS_DOUBLE(sym_get_const(ctx, left)) +
296+
PyFloat_AS_DOUBLE(sym_get_const(ctx, right)));
297297
if (temp == NULL) {
298298
goto error;
299299
}
@@ -308,14 +308,14 @@ dummy_func(void) {
308308
}
309309

310310
op(_BINARY_OP_SUBTRACT_FLOAT, (left, right -- res)) {
311-
if (sym_is_const(left) && sym_is_const(right) &&
311+
if (sym_is_const(ctx, left) && sym_is_const(ctx, right) &&
312312
sym_matches_type(left, &PyFloat_Type) && sym_matches_type(right, &PyFloat_Type))
313313
{
314-
assert(PyFloat_CheckExact(sym_get_const(left)));
315-
assert(PyFloat_CheckExact(sym_get_const(right)));
314+
assert(PyFloat_CheckExact(sym_get_const(ctx, left)));
315+
assert(PyFloat_CheckExact(sym_get_const(ctx, right)));
316316
PyObject *temp = PyFloat_FromDouble(
317-
PyFloat_AS_DOUBLE(sym_get_const(left)) -
318-
PyFloat_AS_DOUBLE(sym_get_const(right)));
317+
PyFloat_AS_DOUBLE(sym_get_const(ctx, left)) -
318+
PyFloat_AS_DOUBLE(sym_get_const(ctx, right)));
319319
if (temp == NULL) {
320320
goto error;
321321
}
@@ -330,14 +330,14 @@ dummy_func(void) {
330330
}
331331

332332
op(_BINARY_OP_MULTIPLY_FLOAT, (left, right -- res)) {
333-
if (sym_is_const(left) && sym_is_const(right) &&
333+
if (sym_is_const(ctx, left) && sym_is_const(ctx, right) &&
334334
sym_matches_type(left, &PyFloat_Type) && sym_matches_type(right, &PyFloat_Type))
335335
{
336-
assert(PyFloat_CheckExact(sym_get_const(left)));
337-
assert(PyFloat_CheckExact(sym_get_const(right)));
336+
assert(PyFloat_CheckExact(sym_get_const(ctx, left)));
337+
assert(PyFloat_CheckExact(sym_get_const(ctx, right)));
338338
PyObject *temp = PyFloat_FromDouble(
339-
PyFloat_AS_DOUBLE(sym_get_const(left)) *
340-
PyFloat_AS_DOUBLE(sym_get_const(right)));
339+
PyFloat_AS_DOUBLE(sym_get_const(ctx, left)) *
340+
PyFloat_AS_DOUBLE(sym_get_const(ctx, right)));
341341
if (temp == NULL) {
342342
goto error;
343343
}
@@ -352,9 +352,9 @@ dummy_func(void) {
352352
}
353353

354354
op(_BINARY_OP_ADD_UNICODE, (left, right -- res)) {
355-
if (sym_is_const(left) && sym_is_const(right) &&
355+
if (sym_is_const(ctx, left) && sym_is_const(ctx, right) &&
356356
sym_matches_type(left, &PyUnicode_Type) && sym_matches_type(right, &PyUnicode_Type)) {
357-
PyObject *temp = PyUnicode_Concat(sym_get_const(left), sym_get_const(right));
357+
PyObject *temp = PyUnicode_Concat(sym_get_const(ctx, left), sym_get_const(ctx, right));
358358
if (temp == NULL) {
359359
goto error;
360360
}
@@ -368,9 +368,9 @@ dummy_func(void) {
368368

369369
op(_BINARY_OP_INPLACE_ADD_UNICODE, (left, right -- )) {
370370
JitOptSymbol *res;
371-
if (sym_is_const(left) && sym_is_const(right) &&
371+
if (sym_is_const(ctx, left) && sym_is_const(ctx, right) &&
372372
sym_matches_type(left, &PyUnicode_Type) && sym_matches_type(right, &PyUnicode_Type)) {
373-
PyObject *temp = PyUnicode_Concat(sym_get_const(left), sym_get_const(right));
373+
PyObject *temp = PyUnicode_Concat(sym_get_const(ctx, left), sym_get_const(ctx, right));
374374
if (temp == NULL) {
375375
goto error;
376376
}
@@ -512,8 +512,8 @@ dummy_func(void) {
512512
op(_CHECK_ATTR_MODULE_PUSH_KEYS, (dict_version/2, owner -- owner, mod_keys)) {
513513
(void)dict_version;
514514
mod_keys = sym_new_not_null(ctx);
515-
if (sym_is_const(owner)) {
516-
PyObject *cnst = sym_get_const(owner);
515+
if (sym_is_const(ctx, owner)) {
516+
PyObject *cnst = sym_get_const(ctx, owner);
517517
if (PyModule_CheckExact(cnst)) {
518518
PyModuleObject *mod = (PyModuleObject *)cnst;
519519
PyObject *dict = mod->md_dict;
@@ -546,8 +546,8 @@ dummy_func(void) {
546546
attr = NULL;
547547
if (this_instr[-1].opcode == _NOP) {
548548
// Preceding _CHECK_ATTR_MODULE_PUSH_KEYS was removed: mod is const and dict is watched.
549-
assert(sym_is_const(owner));
550-
PyModuleObject *mod = (PyModuleObject *)sym_get_const(owner);
549+
assert(sym_is_const(ctx, owner));
550+
PyModuleObject *mod = (PyModuleObject *)sym_get_const(ctx, owner);
551551
assert(PyModule_CheckExact(mod));
552552
PyObject *dict = mod->md_dict;
553553
PyObject *res = convert_global_to_const(this_instr, dict);
@@ -614,19 +614,19 @@ dummy_func(void) {
614614
}
615615

616616
op(_CHECK_FUNCTION_VERSION, (func_version/2, callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) {
617-
if (sym_is_const(callable) && sym_matches_type(callable, &PyFunction_Type)) {
618-
assert(PyFunction_Check(sym_get_const(callable)));
617+
if (sym_is_const(ctx, callable) && sym_matches_type(callable, &PyFunction_Type)) {
618+
assert(PyFunction_Check(sym_get_const(ctx, callable)));
619619
REPLACE_OP(this_instr, _CHECK_FUNCTION_VERSION_INLINE, 0, func_version);
620-
this_instr->operand1 = (uintptr_t)sym_get_const(callable);
620+
this_instr->operand1 = (uintptr_t)sym_get_const(ctx, callable);
621621
}
622622
sym_set_type(callable, &PyFunction_Type);
623623
}
624624

625625
op(_CHECK_FUNCTION_EXACT_ARGS, (callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) {
626626
assert(sym_matches_type(callable, &PyFunction_Type));
627-
if (sym_is_const(callable)) {
627+
if (sym_is_const(ctx, callable)) {
628628
if (sym_is_null(self_or_null) || sym_is_not_null(self_or_null)) {
629-
PyFunctionObject *func = (PyFunctionObject *)sym_get_const(callable);
629+
PyFunctionObject *func = (PyFunctionObject *)sym_get_const(ctx, callable);
630630
PyCodeObject *co = (PyCodeObject *)func->func_code;
631631
if (co->co_argcount == oparg + !sym_is_null(self_or_null)) {
632632
REPLACE_OP(this_instr, _NOP, 0 ,0);
@@ -827,36 +827,39 @@ dummy_func(void) {
827827
}
828828

829829
op(_GUARD_IS_TRUE_POP, (flag -- )) {
830-
if (sym_is_const(flag)) {
831-
PyObject *value = sym_get_const(flag);
830+
if (sym_is_const(ctx, flag)) {
831+
PyObject *value = sym_get_const(ctx, flag);
832832
assert(value != NULL);
833833
eliminate_pop_guard(this_instr, value != Py_True);
834834
}
835+
sym_set_const(flag, Py_True);
835836
}
836837

837838
op(_GUARD_IS_FALSE_POP, (flag -- )) {
838-
if (sym_is_const(flag)) {
839-
PyObject *value = sym_get_const(flag);
839+
if (sym_is_const(ctx, flag)) {
840+
PyObject *value = sym_get_const(ctx, flag);
840841
assert(value != NULL);
841842
eliminate_pop_guard(this_instr, value != Py_False);
842843
}
844+
sym_set_const(flag, Py_False);
843845
}
844846

845847
op(_GUARD_IS_NONE_POP, (flag -- )) {
846-
if (sym_is_const(flag)) {
847-
PyObject *value = sym_get_const(flag);
848+
if (sym_is_const(ctx, flag)) {
849+
PyObject *value = sym_get_const(ctx, flag);
848850
assert(value != NULL);
849851
eliminate_pop_guard(this_instr, !Py_IsNone(value));
850852
}
851853
else if (sym_has_type(flag)) {
852854
assert(!sym_matches_type(flag, &_PyNone_Type));
853855
eliminate_pop_guard(this_instr, true);
854856
}
857+
sym_set_const(flag, Py_None);
855858
}
856859

857860
op(_GUARD_IS_NOT_NONE_POP, (flag -- )) {
858-
if (sym_is_const(flag)) {
859-
PyObject *value = sym_get_const(flag);
861+
if (sym_is_const(ctx, flag)) {
862+
PyObject *value = sym_get_const(ctx, flag);
860863
assert(value != NULL);
861864
eliminate_pop_guard(this_instr, Py_IsNone(value));
862865
}

0 commit comments

Comments
 (0)