Skip to content
59 changes: 30 additions & 29 deletions Include/internal/pycore_uop_ids.h

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

4 changes: 4 additions & 0 deletions Include/internal/pycore_uop_metadata.h

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

17 changes: 17 additions & 0 deletions Lib/test/test_capi/test_opt.py
Original file line number Diff line number Diff line change
Expand Up @@ -1564,6 +1564,23 @@ def f(n):
# But all of the appends we care about are still there:
self.assertEqual(uops.count("_CALL_LIST_APPEND"), len("ABCDEFG"))

def test_compare_pop_two_load_const_inline_borrow(self):
def testfunc(n):
x = 0
for _ in range(n):
a = 10
b = 10
if a == b:
x += 1
return x

res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD)
self.assertEqual(res, 1)
self.assertIsNotNone(ex)
uops = get_opnames(ex)
self.assertNotIn("_COMPARE_OP_INT", uops)
self.assertIn("_POP_TWO_LOAD_CONST_INLINE_BORROW", uops)

def global_identity(x):
return x

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Optimize comparison of two constants in JIT builds
6 changes: 6 additions & 0 deletions Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -5132,6 +5132,12 @@ dummy_func(
value = PyStackRef_FromPyObjectImmortal(ptr);
}

tier2 pure op (_POP_TWO_LOAD_CONST_INLINE_BORROW, (ptr/4, pop1, pop2 -- value)) {
PyStackRef_CLOSE(pop2);
PyStackRef_CLOSE(pop1);
value = PyStackRef_FromPyObjectImmortal(ptr);
}

tier2 op(_CHECK_FUNCTION, (func_version/2 -- )) {
assert(PyStackRef_FunctionCheck(frame->f_funcobj));
PyFunctionObject *func = (PyFunctionObject *)PyStackRef_AsPyObjectBorrow(frame->f_funcobj);
Expand Down
24 changes: 24 additions & 0 deletions Python/executor_cases.c.h

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

25 changes: 24 additions & 1 deletion Python/optimizer_bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,30 @@ dummy_func(void) {
}

op(_COMPARE_OP_INT, (left, right -- res)) {
res = sym_new_type(ctx, &PyBool_Type);
if (sym_is_const(ctx, left) && sym_is_const(ctx, right) &&
sym_matches_type(left, &PyLong_Type) && sym_matches_type(right, &PyLong_Type))
{
assert(PyLong_CheckExact(sym_get_const(ctx, left)));
assert(PyLong_CheckExact(sym_get_const(ctx, right)));
PyObject *tmp = PyObject_RichCompare(sym_get_const(ctx, left),
sym_get_const(ctx, right),
oparg >> 5);
if (tmp == NULL) {
goto error;
}
res = sym_new_const(ctx, tmp);
Py_DECREF(tmp);

if (_Py_IsImmortal(res)) {
REPLACE_OP(this_instr, _POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)tmp);
}
else {
res = sym_new_type(ctx, &PyBool_Type);
}
}
else {
res = sym_new_type(ctx, &PyBool_Type);
}
}

op(_COMPARE_OP_FLOAT, (left, right -- res)) {
Expand Down
48 changes: 44 additions & 4 deletions Python/optimizer_cases.c.h

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

Loading