mirror of
https://github.com/python/cpython.git
synced 2025-08-04 17:08:35 +00:00
gh-100239: specialize bitwise logical binary ops on ints (#128927)
This commit is contained in:
parent
03d9cdb729
commit
4815131910
7 changed files with 82 additions and 3 deletions
2
Include/internal/pycore_opcode_metadata.h
generated
2
Include/internal/pycore_opcode_metadata.h
generated
|
@ -2013,7 +2013,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[266] = {
|
|||
[BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
|
||||
[BINARY_OP_ADD_INT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
|
||||
[BINARY_OP_ADD_UNICODE] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
|
||||
[BINARY_OP_EXTEND] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
|
||||
[BINARY_OP_EXTEND] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
|
||||
[BINARY_OP_INPLACE_ADD_UNICODE] = { true, INSTR_FMT_IXC0000, HAS_LOCAL_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG },
|
||||
[BINARY_OP_MULTIPLY_FLOAT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
|
||||
[BINARY_OP_MULTIPLY_INT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
|
||||
|
|
2
Include/internal/pycore_uop_metadata.h
generated
2
Include/internal/pycore_uop_metadata.h
generated
|
@ -82,7 +82,7 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
|
|||
[_GUARD_BOTH_UNICODE] = HAS_EXIT_FLAG,
|
||||
[_BINARY_OP_ADD_UNICODE] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
|
||||
[_BINARY_OP_INPLACE_ADD_UNICODE] = HAS_LOCAL_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG,
|
||||
[_GUARD_BINARY_OP_EXTEND] = HAS_EXIT_FLAG | HAS_ESCAPES_FLAG,
|
||||
[_GUARD_BINARY_OP_EXTEND] = HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
|
||||
[_BINARY_OP_EXTEND] = HAS_ESCAPES_FLAG | HAS_PURE_FLAG,
|
||||
[_BINARY_SUBSCR] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
|
||||
[_BINARY_SLICE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
|
||||
|
|
|
@ -1396,6 +1396,29 @@ class TestSpecializer(TestBase):
|
|||
|
||||
binary_op_nan()
|
||||
|
||||
def binary_op_bitwise_extend():
|
||||
for _ in range(100):
|
||||
a, b = 2, 7
|
||||
x = a | b
|
||||
self.assertEqual(x, 7)
|
||||
y = a & b
|
||||
self.assertEqual(y, 2)
|
||||
z = a ^ b
|
||||
self.assertEqual(z, 5)
|
||||
a, b = 3, 9
|
||||
a |= b
|
||||
self.assertEqual(a, 11)
|
||||
a, b = 11, 9
|
||||
a &= b
|
||||
self.assertEqual(a, 9)
|
||||
a, b = 3, 9
|
||||
a ^= b
|
||||
self.assertEqual(a, 10)
|
||||
|
||||
binary_op_bitwise_extend()
|
||||
self.assert_specialized(binary_op_bitwise_extend, "BINARY_OP_EXTEND")
|
||||
self.assert_no_opcode(binary_op_bitwise_extend, "BINARY_OP")
|
||||
|
||||
@cpython_only
|
||||
@requires_specialization_ft
|
||||
def test_load_super_attr(self):
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Specialize ``BINARY_OP`` for bitwise logical operations on compact ints.
|
|
@ -759,7 +759,7 @@ dummy_func(
|
|||
assert(INLINE_CACHE_ENTRIES_BINARY_OP == 5);
|
||||
assert(d && d->guard);
|
||||
int res = d->guard(left_o, right_o);
|
||||
EXIT_IF(!res);
|
||||
DEOPT_IF(!res);
|
||||
}
|
||||
|
||||
pure op(_BINARY_OP_EXTEND, (descr/4, left, right -- res)) {
|
||||
|
|
|
@ -581,6 +581,10 @@ _PyCode_Quicken(_Py_CODEUNIT *instructions, Py_ssize_t size, PyObject *consts,
|
|||
#define SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_FLOAT 26
|
||||
#define SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_OTHER 27
|
||||
#define SPEC_FAIL_BINARY_OP_XOR 28
|
||||
#define SPEC_FAIL_BINARY_OP_OR_INT 29
|
||||
#define SPEC_FAIL_BINARY_OP_OR_DIFFERENT_TYPES 30
|
||||
#define SPEC_FAIL_BINARY_OP_XOR_INT 31
|
||||
#define SPEC_FAIL_BINARY_OP_XOR_DIFFERENT_TYPES 32
|
||||
|
||||
/* Calls */
|
||||
|
||||
|
@ -2379,6 +2383,12 @@ binary_op_fail_kind(int oparg, PyObject *lhs, PyObject *rhs)
|
|||
return SPEC_FAIL_BINARY_OP_MULTIPLY_OTHER;
|
||||
case NB_OR:
|
||||
case NB_INPLACE_OR:
|
||||
if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) {
|
||||
return SPEC_FAIL_BINARY_OP_OR_DIFFERENT_TYPES;
|
||||
}
|
||||
if (PyLong_CheckExact(lhs)) {
|
||||
return SPEC_FAIL_BINARY_OP_OR_INT;
|
||||
}
|
||||
return SPEC_FAIL_BINARY_OP_OR;
|
||||
case NB_POWER:
|
||||
case NB_INPLACE_POWER:
|
||||
|
@ -2406,6 +2416,12 @@ binary_op_fail_kind(int oparg, PyObject *lhs, PyObject *rhs)
|
|||
return SPEC_FAIL_BINARY_OP_TRUE_DIVIDE_OTHER;
|
||||
case NB_XOR:
|
||||
case NB_INPLACE_XOR:
|
||||
if (!Py_IS_TYPE(lhs, Py_TYPE(rhs))) {
|
||||
return SPEC_FAIL_BINARY_OP_XOR_DIFFERENT_TYPES;
|
||||
}
|
||||
if (PyLong_CheckExact(lhs)) {
|
||||
return SPEC_FAIL_BINARY_OP_XOR_INT;
|
||||
}
|
||||
return SPEC_FAIL_BINARY_OP_XOR;
|
||||
}
|
||||
Py_UNREACHABLE();
|
||||
|
@ -2414,6 +2430,34 @@ binary_op_fail_kind(int oparg, PyObject *lhs, PyObject *rhs)
|
|||
|
||||
/** Binary Op Specialization Extensions */
|
||||
|
||||
/* long-long */
|
||||
|
||||
static inline int
|
||||
is_compactlong(PyObject *v)
|
||||
{
|
||||
return PyLong_CheckExact(v) &&
|
||||
_PyLong_IsCompact((PyLongObject *)v);
|
||||
}
|
||||
|
||||
static int
|
||||
compactlongs_guard(PyObject *lhs, PyObject *rhs)
|
||||
{
|
||||
return (is_compactlong(lhs) && is_compactlong(rhs));
|
||||
}
|
||||
|
||||
#define BITWISE_LONGS_ACTION(NAME, OP) \
|
||||
static PyObject * \
|
||||
(NAME)(PyObject *lhs, PyObject *rhs) \
|
||||
{ \
|
||||
Py_ssize_t rhs_val = _PyLong_CompactValue((PyLongObject *)rhs); \
|
||||
Py_ssize_t lhs_val = _PyLong_CompactValue((PyLongObject *)lhs); \
|
||||
return PyLong_FromSsize_t(lhs_val OP rhs_val); \
|
||||
}
|
||||
BITWISE_LONGS_ACTION(compactlongs_or, |)
|
||||
BITWISE_LONGS_ACTION(compactlongs_and, &)
|
||||
BITWISE_LONGS_ACTION(compactlongs_xor, ^)
|
||||
#undef BITWISE_LONGS_ACTION
|
||||
|
||||
/* float-long */
|
||||
|
||||
static inline int
|
||||
|
@ -2484,6 +2528,15 @@ LONG_FLOAT_ACTION(compactlong_float_multiply, *)
|
|||
LONG_FLOAT_ACTION(compactlong_float_true_div, /)
|
||||
#undef LONG_FLOAT_ACTION
|
||||
|
||||
static _PyBinaryOpSpecializationDescr compactlongs_specs[NB_OPARG_LAST+1] = {
|
||||
[NB_OR] = {compactlongs_guard, compactlongs_or},
|
||||
[NB_AND] = {compactlongs_guard, compactlongs_and},
|
||||
[NB_XOR] = {compactlongs_guard, compactlongs_xor},
|
||||
[NB_INPLACE_OR] = {compactlongs_guard, compactlongs_or},
|
||||
[NB_INPLACE_AND] = {compactlongs_guard, compactlongs_and},
|
||||
[NB_INPLACE_XOR] = {compactlongs_guard, compactlongs_xor},
|
||||
};
|
||||
|
||||
static _PyBinaryOpSpecializationDescr float_compactlong_specs[NB_OPARG_LAST+1] = {
|
||||
[NB_ADD] = {float_compactlong_guard, float_compactlong_add},
|
||||
[NB_SUBTRACT] = {float_compactlong_guard, float_compactlong_subtract},
|
||||
|
@ -2512,6 +2565,7 @@ binary_op_extended_specialization(PyObject *lhs, PyObject *rhs, int oparg,
|
|||
|
||||
LOOKUP_SPEC(compactlong_float_specs, oparg);
|
||||
LOOKUP_SPEC(float_compactlong_specs, oparg);
|
||||
LOOKUP_SPEC(compactlongs_specs, oparg);
|
||||
#undef LOOKUP_SPEC
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -381,6 +381,7 @@ Python/pylifecycle.c - INTERPRETER_TRAMPOLINE_CODEDEF -
|
|||
Python/pystate.c - initial -
|
||||
Python/specialize.c - adaptive_opcodes -
|
||||
Python/specialize.c - cache_requirements -
|
||||
Python/specialize.c - compactlongs_specs -
|
||||
Python/specialize.c - float_compactlong_specs -
|
||||
Python/specialize.c - compactlong_float_specs -
|
||||
Python/stdlib_module_names.h - _Py_stdlib_module_names -
|
||||
|
|
Can't render this file because it has a wrong number of fields in line 4.
|
Loading…
Add table
Add a link
Reference in a new issue