Skip to content

Commit 96ee078

Browse files
STORE_SUBSCR_LIST_INT and BINARY_OP_SUBSCR_LIST_INT
1 parent bda1218 commit 96ee078

8 files changed

Lines changed: 421 additions & 237 deletions

File tree

Include/internal/pycore_uop_ids.h

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

Include/internal/pycore_uop_metadata.h

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

Python/bytecodes.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,32 @@ dummy_func(
949949
DECREF_INPUTS();
950950
}
951951

952+
op(_BINARY_OP_SUBSCR_LIST_INT__NO_DECREF_INPUTS, (list_st, sub_st -- res)) {
953+
PyObject *sub = PyStackRef_AsPyObjectBorrow(sub_st);
954+
PyObject *list = PyStackRef_AsPyObjectBorrow(list_st);
955+
956+
assert(PyLong_CheckExact(sub));
957+
assert(PyList_CheckExact(list));
958+
959+
// Deopt unless 0 <= sub < PyList_Size(list)
960+
DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub));
961+
Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0];
962+
#ifdef Py_GIL_DISABLED
963+
PyObject *res_o = _PyList_GetItemRef((PyListObject*)list, index);
964+
DEOPT_IF(res_o == NULL);
965+
STAT_INC(BINARY_OP, hit);
966+
res = PyStackRef_FromPyObjectSteal(res_o);
967+
#else
968+
DEOPT_IF(index >= PyList_GET_SIZE(list));
969+
STAT_INC(BINARY_OP, hit);
970+
PyObject *res_o = PyList_GET_ITEM(list, index);
971+
assert(res_o != NULL);
972+
res = PyStackRef_FromPyObjectNew(res_o);
973+
#endif
974+
STAT_INC(BINARY_OP, hit);
975+
INPUTS_DEAD();
976+
}
977+
952978
macro(BINARY_OP_SUBSCR_LIST_SLICE) =
953979
_GUARD_TOS_SLICE + _GUARD_NOS_LIST + unused/5 + _BINARY_OP_SUBSCR_LIST_SLICE;
954980

@@ -1152,6 +1178,34 @@ dummy_func(
11521178
Py_DECREF(old_value);
11531179
}
11541180

1181+
op(_STORE_SUBSCR_LIST_INT__NO_DECREF_INPUTS, (value, list_st, sub_st -- )) {
1182+
PyObject *sub = PyStackRef_AsPyObjectBorrow(sub_st);
1183+
PyObject *list = PyStackRef_AsPyObjectBorrow(list_st);
1184+
1185+
assert(PyLong_CheckExact(sub));
1186+
assert(PyList_CheckExact(list));
1187+
1188+
// Ensure nonnegative, zero-or-one-digit ints.
1189+
DEOPT_IF(!_PyLong_IsNonNegativeCompact((PyLongObject *)sub));
1190+
Py_ssize_t index = ((PyLongObject*)sub)->long_value.ob_digit[0];
1191+
DEOPT_IF(!LOCK_OBJECT(list));
1192+
// Ensure index < len(list)
1193+
if (index >= PyList_GET_SIZE(list)) {
1194+
UNLOCK_OBJECT(list);
1195+
DEOPT_IF(true);
1196+
}
1197+
STAT_INC(STORE_SUBSCR, hit);
1198+
1199+
PyObject *old_value = PyList_GET_ITEM(list, index);
1200+
FT_ATOMIC_STORE_PTR_RELEASE(_PyList_ITEMS(list)[index],
1201+
PyStackRef_AsPyObjectSteal(value));
1202+
assert(old_value != NULL);
1203+
UNLOCK_OBJECT(list); // unlock before decrefs!
1204+
DEAD(sub_st);
1205+
DEAD(list_st);
1206+
Py_DECREF(old_value);
1207+
}
1208+
11551209
macro(STORE_SUBSCR_DICT) =
11561210
_GUARD_NOS_DICT + unused/1 + _STORE_SUBSCR_DICT;
11571211

Python/executor_cases.c.h

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

Python/generated_cases.c.h

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

Python/optimizer_bytecodes.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,19 @@ dummy_func(void) {
270270
}
271271
}
272272

273+
op(_STORE_SUBSCR_LIST_INT, (value, list_st, sub_st -- )) {
274+
if (PyJitRef_IsBorrowed(list_st) && PyJitRef_IsBorrowed(sub_st)) {
275+
REPLACE_OP(this_instr, _STORE_SUBSCR_LIST_INT__NO_DECREF_INPUTS, oparg, 0);
276+
}
277+
}
278+
279+
op(_BINARY_OP_SUBSCR_LIST_INT, (list_st, sub_st -- res)) {
280+
if (PyJitRef_IsBorrowed(list_st) && PyJitRef_IsBorrowed(sub_st)) {
281+
REPLACE_OP(this_instr, _BINARY_OP_SUBSCR_LIST_INT__NO_DECREF_INPUTS, oparg, 0);
282+
}
283+
res = sym_new_not_null(ctx);
284+
}
285+
273286
op(_BINARY_OP_SUBTRACT_FLOAT, (left, right -- res)) {
274287
if (sym_is_const(ctx, left) && sym_is_const(ctx, right)) {
275288
assert(PyFloat_CheckExact(sym_get_const(ctx, left)));

Python/optimizer_cases.c.h

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

Tools/cases_generator/analyzer.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,7 @@ def has_error_without_pop(op: parser.CodeDef) -> bool:
635635
"_PyLong_IsCompact",
636636
"_PyLong_IsNegative",
637637
"_PyLong_IsNonNegativeCompact",
638+
"_PyList_GetItemRef",
638639
"_PyLong_IsZero",
639640
"_PyLong_BothAreCompact",
640641
"_PyCompactLong_Add",

0 commit comments

Comments
 (0)