Skip to content

Commit

Permalink
Add free-threaded specialization for COMPARE_OP, and tests for COMPAR…
Browse files Browse the repository at this point in the history
…E_OP

specialization in general.
  • Loading branch information
Yhg1s committed Nov 4, 2024
1 parent 2e95c5b commit 7457d45
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 7 deletions.
26 changes: 26 additions & 0 deletions Lib/test/test_dis.py
Original file line number Diff line number Diff line change
Expand Up @@ -1335,6 +1335,32 @@ def test_call_specialize(self):
got = self.get_disassembly(co, adaptive=True)
self.do_disassembly_compare(got, call_quicken)

@cpython_only
@requires_specialization_ft
def test_compare_specialize(self):
compare_op_quicken = """\
0 RESUME_CHECK 0
1 LOAD_NAME 0 (a)
LOAD_NAME 1 (b)
%s
RETURN_VALUE
"""
co_int = compile('a == b', "<int>", "eval")
self.code_quicken(lambda: exec(co_int, {}, {'a': 1, 'b': 2}))
got = self.get_disassembly(co_int, adaptive=True)
self.do_disassembly_compare(got, compare_op_quicken % "COMPARE_OP_INT 72 (==)")

co_float = compile('a == b', "<int>", "eval")
self.code_quicken(lambda: exec(co_float, {}, {'a': 1.0, 'b': 2.0}))
got = self.get_disassembly(co_float, adaptive=True)
self.do_disassembly_compare(got, compare_op_quicken % "COMPARE_OP_FLOAT 72 (==)")

co_unicode = compile('a == b', "<unicode>", "eval")
self.code_quicken(lambda: exec(co_unicode, {}, {'a': 'a', 'b': 'b'}))
got = self.get_disassembly(co_unicode, adaptive=True)
self.do_disassembly_compare(got, compare_op_quicken % "COMPARE_OP_STR 72 (==)")

@cpython_only
@requires_specialization
def test_loop_quicken(self):
Expand Down
2 changes: 1 addition & 1 deletion Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -2381,7 +2381,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.

12 changes: 7 additions & 5 deletions Python/specialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -2382,8 +2382,9 @@ _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.
Expand All @@ -2393,12 +2394,12 @@ _Py_Specialize_CompareOp(_PyStackRef lhs_st, _PyStackRef rhs_st, _Py_CODEUNIT *i
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 @@ -2413,18 +2414,19 @@ _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;
SET_OPCODE_OR_RETURN(instr, COMPARE_OP);
cache->counter = adaptive_counter_backoff(cache->counter);
return;
success:
STAT_INC(COMPARE_OP, success);
SET_OPCODE_OR_RETURN(instr, specialized_op);
cache->counter = adaptive_counter_cooldown();
}

Expand Down

0 comments on commit 7457d45

Please sign in to comment.