Skip to content

Commit

Permalink
Merge remote-tracking branch 'Yhg1s/compare_op' into pythongh-115999-…
Browse files Browse the repository at this point in the history
…integrate-attr
  • Loading branch information
mpage committed Dec 14, 2024
2 parents 0e2a208 + 47785d8 commit b7e9a16
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 12 deletions.
33 changes: 33 additions & 0 deletions Lib/test/test_opcache.py
Original file line number Diff line number Diff line change
Expand Up @@ -1618,6 +1618,39 @@ def binary_subscr_str_int():
self.assert_specialized(binary_subscr_str_int, "BINARY_SUBSCR_STR_INT")
self.assert_no_opcode(binary_subscr_str_int, "BINARY_SUBSCR")

@cpython_only
@requires_specialization_ft
def test_compare_op(self):
def compare_op_int():
for _ in range(100):
a, b = 1, 2
c = a == b
self.assertFalse(c)

compare_op_int()
self.assert_specialized(compare_op_int, "COMPARE_OP_INT")
self.assert_no_opcode(compare_op_int, "COMPARE_OP")

def compare_op_float():
for _ in range(100):
a, b = 1.0, 2.0
c = a == b
self.assertFalse(c)

compare_op_float()
self.assert_specialized(compare_op_float, "COMPARE_OP_FLOAT")
self.assert_no_opcode(compare_op_float, "COMPARE_OP")

def compare_op_str():
for _ in range(100):
a, b = "spam", "ham"
c = a == b
self.assertFalse(c)

compare_op_str()
self.assert_specialized(compare_op_str, "COMPARE_OP_STR")
self.assert_no_opcode(compare_op_str, "COMPARE_OP")


if __name__ == "__main__":
unittest.main()
2 changes: 1 addition & 1 deletion Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -2475,7 +2475,7 @@ dummy_func(
};

specializing op(_SPECIALIZE_COMPARE_OP, (counter/1, left, right -- left, right)) {
#if ENABLE_SPECIALIZATION
#if ENABLE_SPECIALIZATION_FT
if (ADAPTIVE_COUNTER_TRIGGERS(counter)) {
next_instr = this_instr;
_Py_Specialize_CompareOp(left, right, next_instr, oparg);
Expand Down
2 changes: 1 addition & 1 deletion Python/generated_cases.c.h

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

17 changes: 7 additions & 10 deletions Python/specialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -2531,23 +2531,23 @@ _Py_Specialize_CompareOp(_PyStackRef lhs_st, _PyStackRef rhs_st, _Py_CODEUNIT *i
{
PyObject *lhs = PyStackRef_AsPyObjectBorrow(lhs_st);
PyObject *rhs = PyStackRef_AsPyObjectBorrow(rhs_st);
uint8_t specialized_op;

assert(ENABLE_SPECIALIZATION);
assert(ENABLE_SPECIALIZATION_FT);
assert(_PyOpcode_Caches[COMPARE_OP] == INLINE_CACHE_ENTRIES_COMPARE_OP);
// All of these specializations compute boolean values, so they're all valid
// regardless of the fifth-lowest oparg bit.
_PyCompareOpCache *cache = (_PyCompareOpCache *)(instr + 1);
if (Py_TYPE(lhs) != Py_TYPE(rhs)) {
SPECIALIZATION_FAIL(COMPARE_OP, compare_op_fail_kind(lhs, rhs));
goto failure;
}
if (PyFloat_CheckExact(lhs)) {
instr->op.code = COMPARE_OP_FLOAT;
specialized_op = COMPARE_OP_FLOAT;
goto success;
}
if (PyLong_CheckExact(lhs)) {
if (_PyLong_IsCompact((PyLongObject *)lhs) && _PyLong_IsCompact((PyLongObject *)rhs)) {
instr->op.code = COMPARE_OP_INT;
specialized_op = COMPARE_OP_INT;
goto success;
}
else {
Expand All @@ -2562,19 +2562,16 @@ _Py_Specialize_CompareOp(_PyStackRef lhs_st, _PyStackRef rhs_st, _Py_CODEUNIT *i
goto failure;
}
else {
instr->op.code = COMPARE_OP_STR;
specialized_op = COMPARE_OP_STR;
goto success;
}
}
SPECIALIZATION_FAIL(COMPARE_OP, compare_op_fail_kind(lhs, rhs));
failure:
STAT_INC(COMPARE_OP, failure);
instr->op.code = COMPARE_OP;
cache->counter = adaptive_counter_backoff(cache->counter);
unspecialize(instr);
return;
success:
STAT_INC(COMPARE_OP, success);
cache->counter = adaptive_counter_cooldown();
specialize(instr, specialized_op);
}

#ifdef Py_STATS
Expand Down

0 comments on commit b7e9a16

Please sign in to comment.