Skip to content

Commit 6b0e5ed

Browse files
committed
review comments: reduce number of guards
1 parent d2dcb87 commit 6b0e5ed

3 files changed

Lines changed: 31 additions & 107 deletions

File tree

Python/optimizer_bytecodes.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,10 @@ dummy_func(void) {
411411

412412
op(_GUARD_BINARY_OP_EXTEND, (descr/4, left, right -- left, right)) {
413413
_PyBinaryOpSpecializationDescr *d = (_PyBinaryOpSpecializationDescr *)descr;
414-
if (d != NULL && d->lhs_type != NULL && d->rhs_type != NULL) {
414+
if (d != NULL && d->guard == NULL) {
415+
/* guard == NULL means the check is purely a type test against
416+
lhs_type/rhs_type, so eliminate it when types are already known. */
417+
assert(d->lhs_type != NULL && d->rhs_type != NULL);
415418
if (sym_matches_type(left, d->lhs_type) &&
416419
sym_matches_type(right, d->rhs_type)) {
417420
REPLACE_OP(this_instr, _NOP, 0, 0);

Python/optimizer_cases.c.h

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

Python/specialize.c

Lines changed: 25 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -2105,34 +2105,6 @@ is_compactlong(PyObject *v)
21052105
_PyLong_IsCompact((PyLongObject *)v);
21062106
}
21072107

2108-
/* list-list */
2109-
2110-
static int
2111-
list_list_guard(PyObject *lhs, PyObject *rhs)
2112-
{
2113-
return PyList_CheckExact(lhs) && PyList_CheckExact(rhs);
2114-
}
2115-
2116-
static PyObject *
2117-
list_list_add(PyObject *lhs, PyObject *rhs)
2118-
{
2119-
return _PyList_Concat(lhs, rhs);
2120-
}
2121-
2122-
/* tuple-tuple */
2123-
2124-
static int
2125-
tuple_tuple_guard(PyObject *lhs, PyObject *rhs)
2126-
{
2127-
return PyTuple_CheckExact(lhs) && PyTuple_CheckExact(rhs);
2128-
}
2129-
2130-
static PyObject *
2131-
tuple_tuple_add(PyObject *lhs, PyObject *rhs)
2132-
{
2133-
return _PyTuple_Concat(lhs, rhs);
2134-
}
2135-
21362108
/* sequence * int helpers: bypass PyNumber_Multiply dispatch overhead
21372109
by calling sq_repeat directly with PyLong_AsSsize_t. */
21382110

@@ -2147,20 +2119,6 @@ seq_int_multiply(PyObject *seq, PyObject *n,
21472119
return repeat(seq, count);
21482120
}
21492121

2150-
/* str-int and int-str */
2151-
2152-
static int
2153-
str_int_guard(PyObject *lhs, PyObject *rhs)
2154-
{
2155-
return PyUnicode_CheckExact(lhs) && PyLong_CheckExact(rhs);
2156-
}
2157-
2158-
static int
2159-
int_str_guard(PyObject *lhs, PyObject *rhs)
2160-
{
2161-
return PyLong_CheckExact(lhs) && PyUnicode_CheckExact(rhs);
2162-
}
2163-
21642122
static PyObject *
21652123
str_int_multiply(PyObject *lhs, PyObject *rhs)
21662124
{
@@ -2175,34 +2133,12 @@ int_str_multiply(PyObject *lhs, PyObject *rhs)
21752133
PyUnicode_Type.tp_as_sequence->sq_repeat);
21762134
}
21772135

2178-
/* bytes-bytes */
2179-
2180-
static int
2181-
bytes_bytes_guard(PyObject *lhs, PyObject *rhs)
2182-
{
2183-
return PyBytes_CheckExact(lhs) && PyBytes_CheckExact(rhs);
2184-
}
2185-
21862136
static PyObject *
21872137
bytes_bytes_add(PyObject *lhs, PyObject *rhs)
21882138
{
21892139
return PyBytes_Type.tp_as_sequence->sq_concat(lhs, rhs);
21902140
}
21912141

2192-
/* bytes-int and int-bytes */
2193-
2194-
static int
2195-
bytes_int_guard(PyObject *lhs, PyObject *rhs)
2196-
{
2197-
return PyBytes_CheckExact(lhs) && PyLong_CheckExact(rhs);
2198-
}
2199-
2200-
static int
2201-
int_bytes_guard(PyObject *lhs, PyObject *rhs)
2202-
{
2203-
return PyLong_CheckExact(lhs) && PyBytes_CheckExact(rhs);
2204-
}
2205-
22062142
static PyObject *
22072143
bytes_int_multiply(PyObject *lhs, PyObject *rhs)
22082144
{
@@ -2217,20 +2153,6 @@ int_bytes_multiply(PyObject *lhs, PyObject *rhs)
22172153
PyBytes_Type.tp_as_sequence->sq_repeat);
22182154
}
22192155

2220-
/* tuple-int and int-tuple */
2221-
2222-
static int
2223-
tuple_int_guard(PyObject *lhs, PyObject *rhs)
2224-
{
2225-
return PyTuple_CheckExact(lhs) && PyLong_CheckExact(rhs);
2226-
}
2227-
2228-
static int
2229-
int_tuple_guard(PyObject *lhs, PyObject *rhs)
2230-
{
2231-
return PyLong_CheckExact(lhs) && PyTuple_CheckExact(rhs);
2232-
}
2233-
22342156
static PyObject *
22352157
tuple_int_multiply(PyObject *lhs, PyObject *rhs)
22362158
{
@@ -2245,14 +2167,6 @@ int_tuple_multiply(PyObject *lhs, PyObject *rhs)
22452167
PyTuple_Type.tp_as_sequence->sq_repeat);
22462168
}
22472169

2248-
/* dict-dict */
2249-
2250-
static int
2251-
dict_dict_guard(PyObject *lhs, PyObject *rhs)
2252-
{
2253-
return PyDict_CheckExact(lhs) && PyDict_CheckExact(rhs);
2254-
}
2255-
22562170
static PyObject *
22572171
dict_dict_or(PyObject *lhs, PyObject *rhs)
22582172
{
@@ -2377,41 +2291,41 @@ static _PyBinaryOpSpecializationDescr binaryop_extend_descrs[] = {
23772291
{NB_MULTIPLY, compactlong_float_guard, compactlong_float_multiply, &PyFloat_Type, 1, NULL, NULL},
23782292

23792293
/* list-list concatenation: _PyList_Concat always allocates a new list */
2380-
{NB_ADD, list_list_guard, list_list_add, &PyList_Type, 1, &PyList_Type, &PyList_Type},
2294+
{NB_ADD, NULL, _PyList_Concat, &PyList_Type, 1, &PyList_Type, &PyList_Type},
23812295
/* tuple-tuple concatenation: _PyTuple_Concat has a zero-length shortcut
23822296
that can return one of the operands, so the result is not guaranteed
23832297
to be a freshly allocated object. */
2384-
{NB_ADD, tuple_tuple_guard, tuple_tuple_add, &PyTuple_Type, 0, &PyTuple_Type, &PyTuple_Type},
2298+
{NB_ADD, NULL, _PyTuple_Concat, &PyTuple_Type, 0, &PyTuple_Type, &PyTuple_Type},
23852299

23862300
/* str * int / int * str: call unicode_repeat directly.
23872301
unicode_repeat returns the original when n == 1. */
2388-
{NB_MULTIPLY, str_int_guard, str_int_multiply, &PyUnicode_Type, 0, &PyUnicode_Type, &PyLong_Type},
2389-
{NB_MULTIPLY, int_str_guard, int_str_multiply, &PyUnicode_Type, 0, &PyLong_Type, &PyUnicode_Type},
2390-
{NB_INPLACE_MULTIPLY, str_int_guard, str_int_multiply, &PyUnicode_Type, 0, &PyUnicode_Type, &PyLong_Type},
2391-
{NB_INPLACE_MULTIPLY, int_str_guard, int_str_multiply, &PyUnicode_Type, 0, &PyLong_Type, &PyUnicode_Type},
2302+
{NB_MULTIPLY, NULL, str_int_multiply, &PyUnicode_Type, 0, &PyUnicode_Type, &PyLong_Type},
2303+
{NB_MULTIPLY, NULL, int_str_multiply, &PyUnicode_Type, 0, &PyLong_Type, &PyUnicode_Type},
2304+
{NB_INPLACE_MULTIPLY, NULL, str_int_multiply, &PyUnicode_Type, 0, &PyUnicode_Type, &PyLong_Type},
2305+
{NB_INPLACE_MULTIPLY, NULL, int_str_multiply, &PyUnicode_Type, 0, &PyLong_Type, &PyUnicode_Type},
23922306

23932307
/* bytes + bytes: bytes_concat may return an operand when one side
23942308
is empty, so result is not always unique. */
2395-
{NB_ADD, bytes_bytes_guard, bytes_bytes_add, &PyBytes_Type, 0, &PyBytes_Type, &PyBytes_Type},
2396-
{NB_INPLACE_ADD, bytes_bytes_guard, bytes_bytes_add, &PyBytes_Type, 0, &PyBytes_Type, &PyBytes_Type},
2309+
{NB_ADD, NULL, bytes_bytes_add, &PyBytes_Type, 0, &PyBytes_Type, &PyBytes_Type},
2310+
{NB_INPLACE_ADD, NULL, bytes_bytes_add, &PyBytes_Type, 0, &PyBytes_Type, &PyBytes_Type},
23972311

23982312
/* bytes * int / int * bytes: call bytes_repeat directly.
23992313
bytes_repeat returns the original when n == 1. */
2400-
{NB_MULTIPLY, bytes_int_guard, bytes_int_multiply, &PyBytes_Type, 0, &PyBytes_Type, &PyLong_Type},
2401-
{NB_MULTIPLY, int_bytes_guard, int_bytes_multiply, &PyBytes_Type, 0, &PyLong_Type, &PyBytes_Type},
2402-
{NB_INPLACE_MULTIPLY, bytes_int_guard, bytes_int_multiply, &PyBytes_Type, 0, &PyBytes_Type, &PyLong_Type},
2403-
{NB_INPLACE_MULTIPLY, int_bytes_guard, int_bytes_multiply, &PyBytes_Type, 0, &PyLong_Type, &PyBytes_Type},
2314+
{NB_MULTIPLY, NULL, bytes_int_multiply, &PyBytes_Type, 0, &PyBytes_Type, &PyLong_Type},
2315+
{NB_MULTIPLY, NULL, int_bytes_multiply, &PyBytes_Type, 0, &PyLong_Type, &PyBytes_Type},
2316+
{NB_INPLACE_MULTIPLY, NULL, bytes_int_multiply, &PyBytes_Type, 0, &PyBytes_Type, &PyLong_Type},
2317+
{NB_INPLACE_MULTIPLY, NULL, int_bytes_multiply, &PyBytes_Type, 0, &PyLong_Type, &PyBytes_Type},
24042318

24052319
/* tuple * int / int * tuple: call tuple_repeat directly.
24062320
tuple_repeat returns the original when n == 1. */
2407-
{NB_MULTIPLY, tuple_int_guard, tuple_int_multiply, &PyTuple_Type, 0, &PyTuple_Type, &PyLong_Type},
2408-
{NB_MULTIPLY, int_tuple_guard, int_tuple_multiply, &PyTuple_Type, 0, &PyLong_Type, &PyTuple_Type},
2409-
{NB_INPLACE_MULTIPLY, tuple_int_guard, tuple_int_multiply, &PyTuple_Type, 0, &PyTuple_Type, &PyLong_Type},
2410-
{NB_INPLACE_MULTIPLY, int_tuple_guard, int_tuple_multiply, &PyTuple_Type, 0, &PyLong_Type, &PyTuple_Type},
2321+
{NB_MULTIPLY, NULL, tuple_int_multiply, &PyTuple_Type, 0, &PyTuple_Type, &PyLong_Type},
2322+
{NB_MULTIPLY, NULL, int_tuple_multiply, &PyTuple_Type, 0, &PyLong_Type, &PyTuple_Type},
2323+
{NB_INPLACE_MULTIPLY, NULL, tuple_int_multiply, &PyTuple_Type, 0, &PyTuple_Type, &PyLong_Type},
2324+
{NB_INPLACE_MULTIPLY, NULL, int_tuple_multiply, &PyTuple_Type, 0, &PyLong_Type, &PyTuple_Type},
24112325

24122326
/* dict | dict */
2413-
{NB_OR, dict_dict_guard, dict_dict_or, &PyDict_Type, 1, &PyDict_Type, &PyDict_Type},
2414-
{NB_INPLACE_OR, dict_dict_guard, dict_dict_ior, &PyDict_Type, 0, &PyDict_Type, &PyDict_Type},
2327+
{NB_OR, NULL, dict_dict_or, &PyDict_Type, 1, &PyDict_Type, &PyDict_Type},
2328+
{NB_INPLACE_OR, NULL, dict_dict_ior, &PyDict_Type, 0, &PyDict_Type, &PyDict_Type},
24152329
};
24162330

24172331
static int
@@ -2421,7 +2335,13 @@ binary_op_extended_specialization(PyObject *lhs, PyObject *rhs, int oparg,
24212335
size_t n = sizeof(binaryop_extend_descrs)/sizeof(_PyBinaryOpSpecializationDescr);
24222336
for (size_t i = 0; i < n; i++) {
24232337
_PyBinaryOpSpecializationDescr *d = &binaryop_extend_descrs[i];
2424-
if (d->oparg == oparg && d->guard(lhs, rhs)) {
2338+
if (d->oparg != oparg) {
2339+
continue;
2340+
}
2341+
int match = (d->guard != NULL)
2342+
? d->guard(lhs, rhs)
2343+
: (Py_TYPE(lhs) == d->lhs_type && Py_TYPE(rhs) == d->rhs_type);
2344+
if (match) {
24252345
*descr = d;
24262346
return 1;
24272347
}

0 commit comments

Comments
 (0)