Skip to content

Commit dcb294c

Browse files
committed
Add creation and narrowing of truths
1 parent 1d17afe commit dcb294c

File tree

3 files changed

+46
-10
lines changed

3 files changed

+46
-10
lines changed

Include/internal/pycore_optimizer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ extern bool _Py_uop_sym_is_immortal(JitOptSymbol *sym);
276276
extern JitOptSymbol *_Py_uop_sym_new_tuple(JitOptContext *ctx, int size, JitOptSymbol **args);
277277
extern JitOptSymbol *_Py_uop_sym_tuple_getitem(JitOptContext *ctx, JitOptSymbol *sym, int item);
278278
extern int _Py_uop_sym_tuple_length(JitOptSymbol *sym);
279+
extern JitOptSymbol *_Py_uop_sym_new_truth(JitOptContext *ctx, JitOptSymbol *value, bool not);
279280

280281
extern void _Py_uop_abstractcontext_init(JitOptContext *ctx);
281282
extern void _Py_uop_abstractcontext_fini(JitOptContext *ctx);

Python/optimizer_analysis.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,7 @@ remove_globals(_PyInterpreterFrame *frame, _PyUOpInstruction *buffer,
376376
#define sym_tuple_getitem _Py_uop_sym_tuple_getitem
377377
#define sym_tuple_length _Py_uop_sym_tuple_length
378378
#define sym_is_immortal _Py_uop_sym_is_immortal
379+
#define sym_new_truth _Py_uop_sym_new_truth
379380

380381
static int
381382
optimize_to_bool(

Python/optimizer_symbols.c

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ sym_new(JitOptContext *ctx)
7676
return self;
7777
}
7878

79+
static void make_const(JitOptSymbol *sym, PyObject *val)
80+
{
81+
sym->tag = JIT_SYM_KNOWN_VALUE_TAG;
82+
sym->value.value = Py_NewRef(val);
83+
}
84+
7985
static inline void
8086
sym_set_bottom(JitOptContext *ctx, JitOptSymbol *sym)
8187
{
@@ -103,7 +109,12 @@ _Py_uop_sym_is_const(JitOptContext *ctx, JitOptSymbol *sym)
103109
}
104110
if (sym->tag == JIT_SYM_TRUTH_TAG) {
105111
JitOptSymbol *value = allocation_base(ctx) + sym->truth.value;
106-
return _Py_uop_sym_truthiness(ctx, value) >= 0;
112+
int truth = _Py_uop_sym_truthiness(ctx, value);
113+
if (truth < 0) {
114+
return false;
115+
}
116+
make_const(sym, (truth ^ sym->truth.not) ? Py_True : Py_False);
117+
return true;
107118
}
108119
return false;
109120
}
@@ -127,7 +138,9 @@ _Py_uop_sym_get_const(JitOptContext *ctx, JitOptSymbol *sym)
127138
if (truth < 0) {
128139
return NULL;
129140
}
130-
return (truth ^ sym->truth.not) ? Py_True : Py_False;
141+
PyObject *res = (truth ^ sym->truth.not) ? Py_True : Py_False;
142+
make_const(sym, res);
143+
return res;
131144
}
132145
return NULL;
133146
}
@@ -229,12 +242,6 @@ _Py_uop_sym_set_type_version(JitOptContext *ctx, JitOptSymbol *sym, unsigned int
229242
Py_UNREACHABLE();
230243
}
231244

232-
static void make_const(JitOptSymbol *sym, PyObject *val)
233-
{
234-
sym->tag = JIT_SYM_KNOWN_VALUE_TAG;
235-
sym->value.value = Py_NewRef(val);
236-
}
237-
238245
void
239246
_Py_uop_sym_set_const(JitOptContext *ctx, JitOptSymbol *sym, PyObject *const_val)
240247
{
@@ -273,7 +280,10 @@ _Py_uop_sym_set_const(JitOptContext *ctx, JitOptSymbol *sym, PyObject *const_val
273280
make_const(sym, const_val);
274281
return;
275282
case JIT_SYM_TRUTH_TAG:
276-
if (!PyBool_Check(const_val) || _Py_uop_sym_get_const(ctx, sym) != const_val) {
283+
if (!PyBool_Check(const_val) ||
284+
(_Py_uop_sym_is_const(ctx, sym) &&
285+
_Py_uop_sym_get_const(ctx, sym) != const_val))
286+
{
277287
sym_set_bottom(ctx, sym);
278288
return;
279289
}
@@ -480,7 +490,9 @@ _Py_uop_sym_truthiness(JitOptContext *ctx, JitOptSymbol *sym)
480490
if (truth < 0) {
481491
return truth;
482492
}
483-
return truth ^ sym->truth.not;
493+
truth ^= sym->truth.not;
494+
make_const(sym, truth ? Py_True : Py_False);
495+
return truth;
484496
}
485497
PyObject *value = sym->value.value;
486498
/* Only handle a few known safe types */
@@ -565,6 +577,28 @@ _Py_uop_sym_is_immortal(JitOptSymbol *sym)
565577
return false;
566578
}
567579

580+
JitOptSymbol *
581+
_Py_uop_sym_new_truth(JitOptContext *ctx, JitOptSymbol *value, bool not)
582+
{
583+
if (value->tag == JIT_SYM_TRUTH_TAG && value->truth.not == not) {
584+
return value;
585+
}
586+
JitOptSymbol *res = sym_new(ctx);
587+
if (res == NULL) {
588+
return out_of_space(ctx);
589+
}
590+
int truth = _Py_uop_sym_truthiness(ctx, value);
591+
if (truth < 0) {
592+
res->tag = JIT_SYM_TRUTH_TAG;
593+
res->truth.not = not;
594+
res->truth.value = (uint16_t)(value - allocation_base(ctx));
595+
}
596+
else {
597+
make_const(res, (truth ^ not) ? Py_True : Py_False);
598+
}
599+
return res;
600+
}
601+
568602
// 0 on success, -1 on error.
569603
_Py_UOpsAbstractFrame *
570604
_Py_uop_frame_new(

0 commit comments

Comments
 (0)