Skip to content

Commit b5ccf00

Browse files
authored
gh-148211: refactor bool to explicit uops in JIT (GH-148258)
1 parent efde433 commit b5ccf00

File tree

3 files changed

+64
-57
lines changed

3 files changed

+64
-57
lines changed

Python/optimizer_analysis.c

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,8 @@ type_watcher_callback(PyTypeObject* type)
155155
}
156156

157157
static PyObject *
158-
convert_global_to_const(_PyUOpInstruction *inst, PyObject *obj, bool insert)
158+
convert_global_to_const(_PyUOpInstruction *inst, PyObject *obj,
159+
uint16_t immortal_op, uint16_t mortal_op)
159160
{
160161
assert(inst->opcode == _LOAD_GLOBAL_MODULE || inst->opcode == _LOAD_GLOBAL_BUILTINS || inst->opcode == _LOAD_ATTR_MODULE);
161162
assert(PyDict_CheckExact(obj));
@@ -175,18 +176,12 @@ convert_global_to_const(_PyUOpInstruction *inst, PyObject *obj, bool insert)
175176
if (res == NULL) {
176177
return NULL;
177178
}
178-
if (insert) {
179-
if (_Py_IsImmortal(res)) {
180-
inst->opcode = _INSERT_1_LOAD_CONST_INLINE_BORROW;
181-
} else {
182-
inst->opcode = _INSERT_1_LOAD_CONST_INLINE;
183-
}
179+
if (_Py_IsImmortal(res)) {
180+
inst->opcode = immortal_op;
184181
} else {
185-
if (_Py_IsImmortal(res)) {
186-
inst->opcode = _LOAD_CONST_INLINE_BORROW;
187-
} else {
188-
inst->opcode = _LOAD_CONST_INLINE;
189-
}
182+
inst->opcode = mortal_op;
183+
}
184+
if (inst->opcode == _LOAD_CONST_INLINE_BORROW || inst->opcode == _LOAD_CONST_INLINE) {
190185
if (inst->oparg & 1) {
191186
assert(inst[1].opcode == _PUSH_NULL_CONDITIONAL);
192187
assert(inst[1].oparg & 1);
@@ -330,7 +325,7 @@ optimize_to_bool(
330325
JitOptContext *ctx,
331326
JitOptRef value,
332327
JitOptRef *result_ptr,
333-
bool insert_mode)
328+
uint16_t prefix, uint16_t load_op)
334329
{
335330
if (sym_matches_type(value, &PyBool_Type)) {
336331
ADD_OP(_NOP, 0, 0);
@@ -340,12 +335,10 @@ optimize_to_bool(
340335
int truthiness = sym_truthiness(ctx, value);
341336
if (truthiness >= 0) {
342337
PyObject *load = truthiness ? Py_True : Py_False;
343-
if (insert_mode) {
344-
ADD_OP(_INSERT_1_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)load);
345-
} else {
346-
ADD_OP(_POP_TOP, 0, 0);
347-
ADD_OP(_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)load);
338+
if (prefix != _NOP) {
339+
ADD_OP(prefix, 0, 0);
348340
}
341+
ADD_OP(load_op, 0, (uintptr_t)load);
349342
*result_ptr = sym_new_const(ctx, load);
350343
return 1;
351344
}
@@ -391,22 +384,18 @@ eliminate_pop_guard(_PyUOpInstruction *this_instr, JitOptContext *ctx, bool exit
391384

392385
static JitOptRef
393386
lookup_attr(JitOptContext *ctx, _PyBloomFilter *dependencies, _PyUOpInstruction *this_instr,
394-
PyTypeObject *type, PyObject *name, bool pop)
387+
PyTypeObject *type, PyObject *name,
388+
uint16_t prefix, uint16_t immortal_op, uint16_t mortal_op)
395389
{
396390
// The cached value may be dead, so we need to do the lookup again... :(
397391
if (type && PyType_Check(type)) {
398392
PyObject *lookup = _PyType_Lookup(type, name);
399393
if (lookup) {
400394
bool immortal = _Py_IsImmortal(lookup) || (type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE);
401-
if (pop) {
402-
ADD_OP(_POP_TOP, 0, 0);
403-
ADD_OP(immortal ? _LOAD_CONST_INLINE_BORROW : _LOAD_CONST_INLINE,
404-
0, (uintptr_t)lookup);
405-
}
406-
else {
407-
ADD_OP(immortal ? _INSERT_1_LOAD_CONST_INLINE_BORROW : _INSERT_1_LOAD_CONST_INLINE,
408-
0, (uintptr_t)lookup);
395+
if (prefix != _NOP) {
396+
ADD_OP(prefix, 0, 0);
409397
}
398+
ADD_OP(immortal ? immortal_op : mortal_op, 0, (uintptr_t)lookup);
410399
PyType_Watch(TYPE_WATCHER_ID, (PyObject *)type);
411400
_Py_BloomFilter_Add(dependencies, type);
412401
return sym_new_const(ctx, lookup);

Python/optimizer_bytecodes.c

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -536,21 +536,24 @@ dummy_func(void) {
536536
}
537537

538538
op(_TO_BOOL, (value -- res)) {
539-
int already_bool = optimize_to_bool(this_instr, ctx, value, &res, false);
539+
int already_bool = optimize_to_bool(this_instr, ctx, value, &res,
540+
_POP_TOP, _LOAD_CONST_INLINE_BORROW);
540541
if (!already_bool) {
541542
res = sym_new_truthiness(ctx, value, true);
542543
}
543544
}
544545

545546
op(_TO_BOOL_BOOL, (value -- value)) {
546-
int already_bool = optimize_to_bool(this_instr, ctx, value, &value, false);
547+
int already_bool = optimize_to_bool(this_instr, ctx, value, &value,
548+
_POP_TOP, _LOAD_CONST_INLINE_BORROW);
547549
if (!already_bool) {
548550
sym_set_type(value, &PyBool_Type);
549551
}
550552
}
551553

552554
op(_TO_BOOL_INT, (value -- res, v)) {
553-
int already_bool = optimize_to_bool(this_instr, ctx, value, &res, true);
555+
int already_bool = optimize_to_bool(this_instr, ctx, value, &res,
556+
_NOP, _INSERT_1_LOAD_CONST_INLINE_BORROW);
554557
if (!already_bool) {
555558
sym_set_type(value, &PyLong_Type);
556559
res = sym_new_truthiness(ctx, value, true);
@@ -559,15 +562,17 @@ dummy_func(void) {
559562
}
560563

561564
op(_TO_BOOL_LIST, (value -- res, v)) {
562-
int already_bool = optimize_to_bool(this_instr, ctx, value, &res, true);
565+
int already_bool = optimize_to_bool(this_instr, ctx, value, &res,
566+
_NOP, _INSERT_1_LOAD_CONST_INLINE_BORROW);
563567
if (!already_bool) {
564568
res = sym_new_type(ctx, &PyBool_Type);
565569
}
566570
v = value;
567571
}
568572

569573
op(_TO_BOOL_NONE, (value -- res)) {
570-
int already_bool = optimize_to_bool(this_instr, ctx, value, &res, false);
574+
int already_bool = optimize_to_bool(this_instr, ctx, value, &res,
575+
_POP_TOP, _LOAD_CONST_INLINE_BORROW);
571576
if (!already_bool) {
572577
sym_set_const(value, Py_None);
573578
res = sym_new_const(ctx, Py_False);
@@ -593,7 +598,8 @@ dummy_func(void) {
593598
}
594599

595600
op(_TO_BOOL_STR, (value -- res, v)) {
596-
int already_bool = optimize_to_bool(this_instr, ctx, value, &res, true);
601+
int already_bool = optimize_to_bool(this_instr, ctx, value, &res,
602+
_NOP, _INSERT_1_LOAD_CONST_INLINE_BORROW);
597603
v = value;
598604
if (!already_bool) {
599605
res = sym_new_truthiness(ctx, value, true);
@@ -837,7 +843,8 @@ dummy_func(void) {
837843
if (watched_mutations < _Py_MAX_ALLOWED_GLOBALS_MODIFICATIONS) {
838844
PyDict_Watch(GLOBALS_WATCHER_ID, dict);
839845
_Py_BloomFilter_Add(dependencies, dict);
840-
PyObject *res = convert_global_to_const(this_instr, dict, true);
846+
PyObject *res = convert_global_to_const(this_instr, dict,
847+
_INSERT_1_LOAD_CONST_INLINE_BORROW, _INSERT_1_LOAD_CONST_INLINE);
841848
if (res == NULL) {
842849
attr = sym_new_not_null(ctx);
843850
}
@@ -890,31 +897,31 @@ dummy_func(void) {
890897
PyTypeObject *type = (PyTypeObject *)sym_get_const(ctx, owner);
891898
PyObject *name = get_co_name(ctx, oparg >> 1);
892899
attr = lookup_attr(ctx, dependencies, this_instr, type, name,
893-
true);
900+
_POP_TOP, _LOAD_CONST_INLINE_BORROW, _LOAD_CONST_INLINE);
894901
}
895902

896903
op(_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, (descr/4, owner -- attr)) {
897904
(void)descr;
898905
PyTypeObject *type = sym_get_type(owner);
899906
PyObject *name = get_co_name(ctx, oparg >> 1);
900907
attr = lookup_attr(ctx, dependencies, this_instr, type, name,
901-
true);
908+
_POP_TOP, _LOAD_CONST_INLINE_BORROW, _LOAD_CONST_INLINE);
902909
}
903910

904911
op(_LOAD_ATTR_NONDESCRIPTOR_NO_DICT, (descr/4, owner -- attr)) {
905912
(void)descr;
906913
PyTypeObject *type = sym_get_type(owner);
907914
PyObject *name = get_co_name(ctx, oparg >> 1);
908915
attr = lookup_attr(ctx, dependencies, this_instr, type, name,
909-
true);
916+
_POP_TOP, _LOAD_CONST_INLINE_BORROW, _LOAD_CONST_INLINE);
910917
}
911918

912919
op(_LOAD_ATTR_METHOD_WITH_VALUES, (descr/4, owner -- attr, self)) {
913920
(void)descr;
914921
PyTypeObject *type = sym_get_type(owner);
915922
PyObject *name = get_co_name(ctx, oparg >> 1);
916923
attr = lookup_attr(ctx, dependencies, this_instr, type, name,
917-
false);
924+
_NOP, _INSERT_1_LOAD_CONST_INLINE_BORROW, _INSERT_1_LOAD_CONST_INLINE);
918925
self = owner;
919926
}
920927

@@ -923,7 +930,7 @@ dummy_func(void) {
923930
PyTypeObject *type = sym_get_type(owner);
924931
PyObject *name = get_co_name(ctx, oparg >> 1);
925932
attr = lookup_attr(ctx, dependencies, this_instr, type, name,
926-
false);
933+
_NOP, _INSERT_1_LOAD_CONST_INLINE_BORROW, _INSERT_1_LOAD_CONST_INLINE);
927934
self = owner;
928935
}
929936

@@ -932,7 +939,7 @@ dummy_func(void) {
932939
PyTypeObject *type = sym_get_type(owner);
933940
PyObject *name = get_co_name(ctx, oparg >> 1);
934941
attr = lookup_attr(ctx, dependencies, this_instr, type, name,
935-
false);
942+
_NOP, _INSERT_1_LOAD_CONST_INLINE_BORROW, _INSERT_1_LOAD_CONST_INLINE);
936943
self = owner;
937944
}
938945

@@ -2007,7 +2014,8 @@ dummy_func(void) {
20072014
ctx->builtins_watched = true;
20082015
}
20092016
if (ctx->frame->globals_checked_version != 0 && ctx->frame->globals_watched) {
2010-
cnst = convert_global_to_const(this_instr, builtins, false);
2017+
cnst = convert_global_to_const(this_instr, builtins,
2018+
_LOAD_CONST_INLINE_BORROW, _LOAD_CONST_INLINE);
20112019
}
20122020
}
20132021
if (cnst == NULL) {
@@ -2046,7 +2054,8 @@ dummy_func(void) {
20462054
ctx->frame->globals_checked_version = version;
20472055
}
20482056
if (ctx->frame->globals_checked_version == version) {
2049-
cnst = convert_global_to_const(this_instr, globals, false);
2057+
cnst = convert_global_to_const(this_instr, globals,
2058+
_LOAD_CONST_INLINE_BORROW, _LOAD_CONST_INLINE);
20502059
}
20512060
}
20522061
}

Python/optimizer_cases.c.h

Lines changed: 24 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)