Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Include/internal/pycore_opcode_metadata.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Include/internal/pycore_uop_metadata.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions Lib/test/test_opcache.py
Original file line number Diff line number Diff line change
Expand Up @@ -1362,6 +1362,20 @@ def binary_op_add_extend():
self.assert_specialized(binary_op_add_extend, "BINARY_OP_EXTEND")
self.assert_no_opcode(binary_op_add_extend, "BINARY_OP")

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)

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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Specialize ``BINARY_OP`` for bitwise logical operations on non-negative compact ints.
2 changes: 1 addition & 1 deletion Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -749,7 +749,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)) {
Expand Down
51 changes: 51 additions & 0 deletions Python/specialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,10 @@
#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 */

Expand Down Expand Up @@ -2379,6 +2383,12 @@
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:
Expand Down Expand Up @@ -2406,6 +2416,12 @@
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();
Expand All @@ -2414,6 +2430,34 @@

/** 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_FromLong(lhs_val OP rhs_val); \
}
BITWISE_LONGS_ACTION(compactlongs_or, |)

Check warning on line 2456 in Python/specialize.c

View workflow job for this annotation

GitHub Actions / Windows / build and test (arm64)

'function': conversion from 'Py_ssize_t' to 'long', possible loss of data [D:\a\cpython\cpython\PCbuild\pythoncore.vcxproj]

Check warning on line 2456 in Python/specialize.c

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / build and test (arm64)

'function': conversion from 'Py_ssize_t' to 'long', possible loss of data [D:\a\cpython\cpython\PCbuild\pythoncore.vcxproj]

Check warning on line 2456 in Python/specialize.c

View workflow job for this annotation

GitHub Actions / Windows / build and test (x64)

'function': conversion from 'Py_ssize_t' to 'long', possible loss of data [D:\a\cpython\cpython\PCbuild\pythoncore.vcxproj]

Check warning on line 2456 in Python/specialize.c

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / build and test (x64)

'function': conversion from 'Py_ssize_t' to 'long', possible loss of data [D:\a\cpython\cpython\PCbuild\pythoncore.vcxproj]
BITWISE_LONGS_ACTION(compactlongs_and, &)

Check warning on line 2457 in Python/specialize.c

View workflow job for this annotation

GitHub Actions / Windows / build and test (arm64)

'function': conversion from 'Py_ssize_t' to 'long', possible loss of data [D:\a\cpython\cpython\PCbuild\pythoncore.vcxproj]

Check warning on line 2457 in Python/specialize.c

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / build and test (arm64)

'function': conversion from 'Py_ssize_t' to 'long', possible loss of data [D:\a\cpython\cpython\PCbuild\pythoncore.vcxproj]

Check warning on line 2457 in Python/specialize.c

View workflow job for this annotation

GitHub Actions / Windows / build and test (x64)

'function': conversion from 'Py_ssize_t' to 'long', possible loss of data [D:\a\cpython\cpython\PCbuild\pythoncore.vcxproj]

Check warning on line 2457 in Python/specialize.c

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / build and test (x64)

'function': conversion from 'Py_ssize_t' to 'long', possible loss of data [D:\a\cpython\cpython\PCbuild\pythoncore.vcxproj]
BITWISE_LONGS_ACTION(compactlongs_xor, ^)

Check warning on line 2458 in Python/specialize.c

View workflow job for this annotation

GitHub Actions / Windows / build and test (arm64)

'function': conversion from 'Py_ssize_t' to 'long', possible loss of data [D:\a\cpython\cpython\PCbuild\pythoncore.vcxproj]

Check warning on line 2458 in Python/specialize.c

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / build and test (arm64)

'function': conversion from 'Py_ssize_t' to 'long', possible loss of data [D:\a\cpython\cpython\PCbuild\pythoncore.vcxproj]

Check warning on line 2458 in Python/specialize.c

View workflow job for this annotation

GitHub Actions / Windows / build and test (x64)

'function': conversion from 'Py_ssize_t' to 'long', possible loss of data [D:\a\cpython\cpython\PCbuild\pythoncore.vcxproj]

Check warning on line 2458 in Python/specialize.c

View workflow job for this annotation

GitHub Actions / Windows (free-threading) / build and test (x64)

'function': conversion from 'Py_ssize_t' to 'long', possible loss of data [D:\a\cpython\cpython\PCbuild\pythoncore.vcxproj]
#undef BITWISE_LONGS_ACTION

/* float-long */

static int
Expand Down Expand Up @@ -2466,6 +2510,12 @@
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},
};

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},
Expand Down Expand Up @@ -2494,6 +2544,7 @@

LOOKUP_SPEC(compactlong_float_specs, oparg);
LOOKUP_SPEC(float_compactlong_specs, oparg);
LOOKUP_SPEC(compactlongs_specs, oparg);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why three tables, rather than one?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A single table would need to have a list of (guard, action) pairs for each OP. So it's a table of tables. Same thing basically.

#undef LOOKUP_SPEC
return 0;
}
Expand Down
1 change: 1 addition & 0 deletions Tools/c-analyzer/cpython/ignored.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,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 -
Expand Down
Loading