mirror of
https://github.com/python/cpython.git
synced 2026-04-20 02:40:59 +00:00
gh-148211: refactor bool to explicit uops in JIT (GH-148258)
This commit is contained in:
parent
efde4333bf
commit
b5ccf00bd6
3 changed files with 64 additions and 57 deletions
|
|
@ -155,7 +155,8 @@ type_watcher_callback(PyTypeObject* type)
|
|||
}
|
||||
|
||||
static PyObject *
|
||||
convert_global_to_const(_PyUOpInstruction *inst, PyObject *obj, bool insert)
|
||||
convert_global_to_const(_PyUOpInstruction *inst, PyObject *obj,
|
||||
uint16_t immortal_op, uint16_t mortal_op)
|
||||
{
|
||||
assert(inst->opcode == _LOAD_GLOBAL_MODULE || inst->opcode == _LOAD_GLOBAL_BUILTINS || inst->opcode == _LOAD_ATTR_MODULE);
|
||||
assert(PyDict_CheckExact(obj));
|
||||
|
|
@ -175,18 +176,12 @@ convert_global_to_const(_PyUOpInstruction *inst, PyObject *obj, bool insert)
|
|||
if (res == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (insert) {
|
||||
if (_Py_IsImmortal(res)) {
|
||||
inst->opcode = _INSERT_1_LOAD_CONST_INLINE_BORROW;
|
||||
} else {
|
||||
inst->opcode = _INSERT_1_LOAD_CONST_INLINE;
|
||||
}
|
||||
if (_Py_IsImmortal(res)) {
|
||||
inst->opcode = immortal_op;
|
||||
} else {
|
||||
if (_Py_IsImmortal(res)) {
|
||||
inst->opcode = _LOAD_CONST_INLINE_BORROW;
|
||||
} else {
|
||||
inst->opcode = _LOAD_CONST_INLINE;
|
||||
}
|
||||
inst->opcode = mortal_op;
|
||||
}
|
||||
if (inst->opcode == _LOAD_CONST_INLINE_BORROW || inst->opcode == _LOAD_CONST_INLINE) {
|
||||
if (inst->oparg & 1) {
|
||||
assert(inst[1].opcode == _PUSH_NULL_CONDITIONAL);
|
||||
assert(inst[1].oparg & 1);
|
||||
|
|
@ -330,7 +325,7 @@ optimize_to_bool(
|
|||
JitOptContext *ctx,
|
||||
JitOptRef value,
|
||||
JitOptRef *result_ptr,
|
||||
bool insert_mode)
|
||||
uint16_t prefix, uint16_t load_op)
|
||||
{
|
||||
if (sym_matches_type(value, &PyBool_Type)) {
|
||||
ADD_OP(_NOP, 0, 0);
|
||||
|
|
@ -340,12 +335,10 @@ optimize_to_bool(
|
|||
int truthiness = sym_truthiness(ctx, value);
|
||||
if (truthiness >= 0) {
|
||||
PyObject *load = truthiness ? Py_True : Py_False;
|
||||
if (insert_mode) {
|
||||
ADD_OP(_INSERT_1_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)load);
|
||||
} else {
|
||||
ADD_OP(_POP_TOP, 0, 0);
|
||||
ADD_OP(_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)load);
|
||||
if (prefix != _NOP) {
|
||||
ADD_OP(prefix, 0, 0);
|
||||
}
|
||||
ADD_OP(load_op, 0, (uintptr_t)load);
|
||||
*result_ptr = sym_new_const(ctx, load);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -391,22 +384,18 @@ eliminate_pop_guard(_PyUOpInstruction *this_instr, JitOptContext *ctx, bool exit
|
|||
|
||||
static JitOptRef
|
||||
lookup_attr(JitOptContext *ctx, _PyBloomFilter *dependencies, _PyUOpInstruction *this_instr,
|
||||
PyTypeObject *type, PyObject *name, bool pop)
|
||||
PyTypeObject *type, PyObject *name,
|
||||
uint16_t prefix, uint16_t immortal_op, uint16_t mortal_op)
|
||||
{
|
||||
// The cached value may be dead, so we need to do the lookup again... :(
|
||||
if (type && PyType_Check(type)) {
|
||||
PyObject *lookup = _PyType_Lookup(type, name);
|
||||
if (lookup) {
|
||||
bool immortal = _Py_IsImmortal(lookup) || (type->tp_flags & Py_TPFLAGS_IMMUTABLETYPE);
|
||||
if (pop) {
|
||||
ADD_OP(_POP_TOP, 0, 0);
|
||||
ADD_OP(immortal ? _LOAD_CONST_INLINE_BORROW : _LOAD_CONST_INLINE,
|
||||
0, (uintptr_t)lookup);
|
||||
}
|
||||
else {
|
||||
ADD_OP(immortal ? _INSERT_1_LOAD_CONST_INLINE_BORROW : _INSERT_1_LOAD_CONST_INLINE,
|
||||
0, (uintptr_t)lookup);
|
||||
if (prefix != _NOP) {
|
||||
ADD_OP(prefix, 0, 0);
|
||||
}
|
||||
ADD_OP(immortal ? immortal_op : mortal_op, 0, (uintptr_t)lookup);
|
||||
PyType_Watch(TYPE_WATCHER_ID, (PyObject *)type);
|
||||
_Py_BloomFilter_Add(dependencies, type);
|
||||
return sym_new_const(ctx, lookup);
|
||||
|
|
|
|||
|
|
@ -536,21 +536,24 @@ dummy_func(void) {
|
|||
}
|
||||
|
||||
op(_TO_BOOL, (value -- res)) {
|
||||
int already_bool = optimize_to_bool(this_instr, ctx, value, &res, false);
|
||||
int already_bool = optimize_to_bool(this_instr, ctx, value, &res,
|
||||
_POP_TOP, _LOAD_CONST_INLINE_BORROW);
|
||||
if (!already_bool) {
|
||||
res = sym_new_truthiness(ctx, value, true);
|
||||
}
|
||||
}
|
||||
|
||||
op(_TO_BOOL_BOOL, (value -- value)) {
|
||||
int already_bool = optimize_to_bool(this_instr, ctx, value, &value, false);
|
||||
int already_bool = optimize_to_bool(this_instr, ctx, value, &value,
|
||||
_POP_TOP, _LOAD_CONST_INLINE_BORROW);
|
||||
if (!already_bool) {
|
||||
sym_set_type(value, &PyBool_Type);
|
||||
}
|
||||
}
|
||||
|
||||
op(_TO_BOOL_INT, (value -- res, v)) {
|
||||
int already_bool = optimize_to_bool(this_instr, ctx, value, &res, true);
|
||||
int already_bool = optimize_to_bool(this_instr, ctx, value, &res,
|
||||
_NOP, _INSERT_1_LOAD_CONST_INLINE_BORROW);
|
||||
if (!already_bool) {
|
||||
sym_set_type(value, &PyLong_Type);
|
||||
res = sym_new_truthiness(ctx, value, true);
|
||||
|
|
@ -559,7 +562,8 @@ dummy_func(void) {
|
|||
}
|
||||
|
||||
op(_TO_BOOL_LIST, (value -- res, v)) {
|
||||
int already_bool = optimize_to_bool(this_instr, ctx, value, &res, true);
|
||||
int already_bool = optimize_to_bool(this_instr, ctx, value, &res,
|
||||
_NOP, _INSERT_1_LOAD_CONST_INLINE_BORROW);
|
||||
if (!already_bool) {
|
||||
res = sym_new_type(ctx, &PyBool_Type);
|
||||
}
|
||||
|
|
@ -567,7 +571,8 @@ dummy_func(void) {
|
|||
}
|
||||
|
||||
op(_TO_BOOL_NONE, (value -- res)) {
|
||||
int already_bool = optimize_to_bool(this_instr, ctx, value, &res, false);
|
||||
int already_bool = optimize_to_bool(this_instr, ctx, value, &res,
|
||||
_POP_TOP, _LOAD_CONST_INLINE_BORROW);
|
||||
if (!already_bool) {
|
||||
sym_set_const(value, Py_None);
|
||||
res = sym_new_const(ctx, Py_False);
|
||||
|
|
@ -593,7 +598,8 @@ dummy_func(void) {
|
|||
}
|
||||
|
||||
op(_TO_BOOL_STR, (value -- res, v)) {
|
||||
int already_bool = optimize_to_bool(this_instr, ctx, value, &res, true);
|
||||
int already_bool = optimize_to_bool(this_instr, ctx, value, &res,
|
||||
_NOP, _INSERT_1_LOAD_CONST_INLINE_BORROW);
|
||||
v = value;
|
||||
if (!already_bool) {
|
||||
res = sym_new_truthiness(ctx, value, true);
|
||||
|
|
@ -837,7 +843,8 @@ dummy_func(void) {
|
|||
if (watched_mutations < _Py_MAX_ALLOWED_GLOBALS_MODIFICATIONS) {
|
||||
PyDict_Watch(GLOBALS_WATCHER_ID, dict);
|
||||
_Py_BloomFilter_Add(dependencies, dict);
|
||||
PyObject *res = convert_global_to_const(this_instr, dict, true);
|
||||
PyObject *res = convert_global_to_const(this_instr, dict,
|
||||
_INSERT_1_LOAD_CONST_INLINE_BORROW, _INSERT_1_LOAD_CONST_INLINE);
|
||||
if (res == NULL) {
|
||||
attr = sym_new_not_null(ctx);
|
||||
}
|
||||
|
|
@ -890,7 +897,7 @@ dummy_func(void) {
|
|||
PyTypeObject *type = (PyTypeObject *)sym_get_const(ctx, owner);
|
||||
PyObject *name = get_co_name(ctx, oparg >> 1);
|
||||
attr = lookup_attr(ctx, dependencies, this_instr, type, name,
|
||||
true);
|
||||
_POP_TOP, _LOAD_CONST_INLINE_BORROW, _LOAD_CONST_INLINE);
|
||||
}
|
||||
|
||||
op(_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, (descr/4, owner -- attr)) {
|
||||
|
|
@ -898,7 +905,7 @@ dummy_func(void) {
|
|||
PyTypeObject *type = sym_get_type(owner);
|
||||
PyObject *name = get_co_name(ctx, oparg >> 1);
|
||||
attr = lookup_attr(ctx, dependencies, this_instr, type, name,
|
||||
true);
|
||||
_POP_TOP, _LOAD_CONST_INLINE_BORROW, _LOAD_CONST_INLINE);
|
||||
}
|
||||
|
||||
op(_LOAD_ATTR_NONDESCRIPTOR_NO_DICT, (descr/4, owner -- attr)) {
|
||||
|
|
@ -906,7 +913,7 @@ dummy_func(void) {
|
|||
PyTypeObject *type = sym_get_type(owner);
|
||||
PyObject *name = get_co_name(ctx, oparg >> 1);
|
||||
attr = lookup_attr(ctx, dependencies, this_instr, type, name,
|
||||
true);
|
||||
_POP_TOP, _LOAD_CONST_INLINE_BORROW, _LOAD_CONST_INLINE);
|
||||
}
|
||||
|
||||
op(_LOAD_ATTR_METHOD_WITH_VALUES, (descr/4, owner -- attr, self)) {
|
||||
|
|
@ -914,7 +921,7 @@ dummy_func(void) {
|
|||
PyTypeObject *type = sym_get_type(owner);
|
||||
PyObject *name = get_co_name(ctx, oparg >> 1);
|
||||
attr = lookup_attr(ctx, dependencies, this_instr, type, name,
|
||||
false);
|
||||
_NOP, _INSERT_1_LOAD_CONST_INLINE_BORROW, _INSERT_1_LOAD_CONST_INLINE);
|
||||
self = owner;
|
||||
}
|
||||
|
||||
|
|
@ -923,7 +930,7 @@ dummy_func(void) {
|
|||
PyTypeObject *type = sym_get_type(owner);
|
||||
PyObject *name = get_co_name(ctx, oparg >> 1);
|
||||
attr = lookup_attr(ctx, dependencies, this_instr, type, name,
|
||||
false);
|
||||
_NOP, _INSERT_1_LOAD_CONST_INLINE_BORROW, _INSERT_1_LOAD_CONST_INLINE);
|
||||
self = owner;
|
||||
}
|
||||
|
||||
|
|
@ -932,7 +939,7 @@ dummy_func(void) {
|
|||
PyTypeObject *type = sym_get_type(owner);
|
||||
PyObject *name = get_co_name(ctx, oparg >> 1);
|
||||
attr = lookup_attr(ctx, dependencies, this_instr, type, name,
|
||||
false);
|
||||
_NOP, _INSERT_1_LOAD_CONST_INLINE_BORROW, _INSERT_1_LOAD_CONST_INLINE);
|
||||
self = owner;
|
||||
}
|
||||
|
||||
|
|
@ -2007,7 +2014,8 @@ dummy_func(void) {
|
|||
ctx->builtins_watched = true;
|
||||
}
|
||||
if (ctx->frame->globals_checked_version != 0 && ctx->frame->globals_watched) {
|
||||
cnst = convert_global_to_const(this_instr, builtins, false);
|
||||
cnst = convert_global_to_const(this_instr, builtins,
|
||||
_LOAD_CONST_INLINE_BORROW, _LOAD_CONST_INLINE);
|
||||
}
|
||||
}
|
||||
if (cnst == NULL) {
|
||||
|
|
@ -2046,7 +2054,8 @@ dummy_func(void) {
|
|||
ctx->frame->globals_checked_version = version;
|
||||
}
|
||||
if (ctx->frame->globals_checked_version == version) {
|
||||
cnst = convert_global_to_const(this_instr, globals, false);
|
||||
cnst = convert_global_to_const(this_instr, globals,
|
||||
_LOAD_CONST_INLINE_BORROW, _LOAD_CONST_INLINE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
39
Python/optimizer_cases.c.h
generated
39
Python/optimizer_cases.c.h
generated
|
|
@ -332,7 +332,8 @@
|
|||
JitOptRef value;
|
||||
JitOptRef res;
|
||||
value = stack_pointer[-1];
|
||||
int already_bool = optimize_to_bool(this_instr, ctx, value, &res, false);
|
||||
int already_bool = optimize_to_bool(this_instr, ctx, value, &res,
|
||||
_POP_TOP, _LOAD_CONST_INLINE_BORROW);
|
||||
if (!already_bool) {
|
||||
res = sym_new_truthiness(ctx, value, true);
|
||||
}
|
||||
|
|
@ -343,7 +344,8 @@
|
|||
case _TO_BOOL_BOOL: {
|
||||
JitOptRef value;
|
||||
value = stack_pointer[-1];
|
||||
int already_bool = optimize_to_bool(this_instr, ctx, value, &value, false);
|
||||
int already_bool = optimize_to_bool(this_instr, ctx, value, &value,
|
||||
_POP_TOP, _LOAD_CONST_INLINE_BORROW);
|
||||
if (!already_bool) {
|
||||
sym_set_type(value, &PyBool_Type);
|
||||
}
|
||||
|
|
@ -356,7 +358,8 @@
|
|||
JitOptRef res;
|
||||
JitOptRef v;
|
||||
value = stack_pointer[-1];
|
||||
int already_bool = optimize_to_bool(this_instr, ctx, value, &res, true);
|
||||
int already_bool = optimize_to_bool(this_instr, ctx, value, &res,
|
||||
_NOP, _INSERT_1_LOAD_CONST_INLINE_BORROW);
|
||||
if (!already_bool) {
|
||||
sym_set_type(value, &PyLong_Type);
|
||||
res = sym_new_truthiness(ctx, value, true);
|
||||
|
|
@ -411,7 +414,8 @@
|
|||
JitOptRef res;
|
||||
JitOptRef v;
|
||||
value = stack_pointer[-1];
|
||||
int already_bool = optimize_to_bool(this_instr, ctx, value, &res, true);
|
||||
int already_bool = optimize_to_bool(this_instr, ctx, value, &res,
|
||||
_NOP, _INSERT_1_LOAD_CONST_INLINE_BORROW);
|
||||
if (!already_bool) {
|
||||
res = sym_new_type(ctx, &PyBool_Type);
|
||||
}
|
||||
|
|
@ -428,7 +432,8 @@
|
|||
JitOptRef value;
|
||||
JitOptRef res;
|
||||
value = stack_pointer[-1];
|
||||
int already_bool = optimize_to_bool(this_instr, ctx, value, &res, false);
|
||||
int already_bool = optimize_to_bool(this_instr, ctx, value, &res,
|
||||
_POP_TOP, _LOAD_CONST_INLINE_BORROW);
|
||||
if (!already_bool) {
|
||||
sym_set_const(value, Py_None);
|
||||
res = sym_new_const(ctx, Py_False);
|
||||
|
|
@ -469,7 +474,8 @@
|
|||
JitOptRef res;
|
||||
JitOptRef v;
|
||||
value = stack_pointer[-1];
|
||||
int already_bool = optimize_to_bool(this_instr, ctx, value, &res, true);
|
||||
int already_bool = optimize_to_bool(this_instr, ctx, value, &res,
|
||||
_NOP, _INSERT_1_LOAD_CONST_INLINE_BORROW);
|
||||
v = value;
|
||||
if (!already_bool) {
|
||||
res = sym_new_truthiness(ctx, value, true);
|
||||
|
|
@ -2086,7 +2092,8 @@
|
|||
ctx->frame->globals_checked_version = version;
|
||||
}
|
||||
if (ctx->frame->globals_checked_version == version) {
|
||||
cnst = convert_global_to_const(this_instr, globals, false);
|
||||
cnst = convert_global_to_const(this_instr, globals,
|
||||
_LOAD_CONST_INLINE_BORROW, _LOAD_CONST_INLINE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2129,7 +2136,8 @@
|
|||
ctx->builtins_watched = true;
|
||||
}
|
||||
if (ctx->frame->globals_checked_version != 0 && ctx->frame->globals_watched) {
|
||||
cnst = convert_global_to_const(this_instr, builtins, false);
|
||||
cnst = convert_global_to_const(this_instr, builtins,
|
||||
_LOAD_CONST_INLINE_BORROW, _LOAD_CONST_INLINE);
|
||||
}
|
||||
}
|
||||
if (cnst == NULL) {
|
||||
|
|
@ -2439,7 +2447,8 @@
|
|||
if (watched_mutations < _Py_MAX_ALLOWED_GLOBALS_MODIFICATIONS) {
|
||||
PyDict_Watch(GLOBALS_WATCHER_ID, dict);
|
||||
_Py_BloomFilter_Add(dependencies, dict);
|
||||
PyObject *res = convert_global_to_const(this_instr, dict, true);
|
||||
PyObject *res = convert_global_to_const(this_instr, dict,
|
||||
_INSERT_1_LOAD_CONST_INLINE_BORROW, _INSERT_1_LOAD_CONST_INLINE);
|
||||
if (res == NULL) {
|
||||
attr = sym_new_not_null(ctx);
|
||||
}
|
||||
|
|
@ -2520,7 +2529,7 @@
|
|||
PyTypeObject *type = (PyTypeObject *)sym_get_const(ctx, owner);
|
||||
PyObject *name = get_co_name(ctx, oparg >> 1);
|
||||
attr = lookup_attr(ctx, dependencies, this_instr, type, name,
|
||||
true);
|
||||
_POP_TOP, _LOAD_CONST_INLINE_BORROW, _LOAD_CONST_INLINE);
|
||||
stack_pointer[-1] = attr;
|
||||
break;
|
||||
}
|
||||
|
|
@ -3413,7 +3422,7 @@
|
|||
PyTypeObject *type = sym_get_type(owner);
|
||||
PyObject *name = get_co_name(ctx, oparg >> 1);
|
||||
attr = lookup_attr(ctx, dependencies, this_instr, type, name,
|
||||
false);
|
||||
_NOP, _INSERT_1_LOAD_CONST_INLINE_BORROW, _INSERT_1_LOAD_CONST_INLINE);
|
||||
self = owner;
|
||||
CHECK_STACK_BOUNDS(1);
|
||||
stack_pointer[-1] = attr;
|
||||
|
|
@ -3433,7 +3442,7 @@
|
|||
PyTypeObject *type = sym_get_type(owner);
|
||||
PyObject *name = get_co_name(ctx, oparg >> 1);
|
||||
attr = lookup_attr(ctx, dependencies, this_instr, type, name,
|
||||
false);
|
||||
_NOP, _INSERT_1_LOAD_CONST_INLINE_BORROW, _INSERT_1_LOAD_CONST_INLINE);
|
||||
self = owner;
|
||||
CHECK_STACK_BOUNDS(1);
|
||||
stack_pointer[-1] = attr;
|
||||
|
|
@ -3452,7 +3461,7 @@
|
|||
PyTypeObject *type = sym_get_type(owner);
|
||||
PyObject *name = get_co_name(ctx, oparg >> 1);
|
||||
attr = lookup_attr(ctx, dependencies, this_instr, type, name,
|
||||
true);
|
||||
_POP_TOP, _LOAD_CONST_INLINE_BORROW, _LOAD_CONST_INLINE);
|
||||
stack_pointer[-1] = attr;
|
||||
break;
|
||||
}
|
||||
|
|
@ -3466,7 +3475,7 @@
|
|||
PyTypeObject *type = sym_get_type(owner);
|
||||
PyObject *name = get_co_name(ctx, oparg >> 1);
|
||||
attr = lookup_attr(ctx, dependencies, this_instr, type, name,
|
||||
true);
|
||||
_POP_TOP, _LOAD_CONST_INLINE_BORROW, _LOAD_CONST_INLINE);
|
||||
stack_pointer[-1] = attr;
|
||||
break;
|
||||
}
|
||||
|
|
@ -3485,7 +3494,7 @@
|
|||
PyTypeObject *type = sym_get_type(owner);
|
||||
PyObject *name = get_co_name(ctx, oparg >> 1);
|
||||
attr = lookup_attr(ctx, dependencies, this_instr, type, name,
|
||||
false);
|
||||
_NOP, _INSERT_1_LOAD_CONST_INLINE_BORROW, _INSERT_1_LOAD_CONST_INLINE);
|
||||
self = owner;
|
||||
CHECK_STACK_BOUNDS(1);
|
||||
stack_pointer[-1] = attr;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue