aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Python
diff options
context:
space:
mode:
authorIrit Katriel <1055913+iritkatriel@users.noreply.github.com>2025-01-29 09:28:21 +0000
committerGitHub <noreply@github.com>2025-01-29 09:28:21 +0000
commit4815131910cec72805ad2966e7af1e2eba49fe51 (patch)
treece0cc600e25fd04294d3377b5e8beaefbe9fa2f3 /Python
parent03d9cdb7298cdbf67535dfeb3af5c1a619be7580 (diff)
downloadcpython-4815131910cec72805ad2966e7af1e2eba49fe51.tar.gz
cpython-4815131910cec72805ad2966e7af1e2eba49fe51.zip
gh-100239: specialize bitwise logical binary ops on ints (#128927)
Diffstat (limited to 'Python')
-rw-r--r--Python/bytecodes.c2
-rw-r--r--Python/specialize.c54
2 files changed, 55 insertions, 1 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index 0d7b9f2a781..f659a5e5c92 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -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)) {
diff --git a/Python/specialize.c b/Python/specialize.c
index fa022346bde..abb130d73ee 100644
--- a/Python/specialize.c
+++ b/Python/specialize.c
@@ -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;
}