gh-134584: JIT: Eliminate redundant refcount ops for X_INT (GH-142765)

This commit is contained in:
Ken Jin 2025-12-16 06:22:18 +08:00 committed by GitHub
parent 0978b9a7d5
commit 790a46a449
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 1050 additions and 1246 deletions

View File

@ -1330,12 +1330,12 @@ const struct opcode_macro_expansion
_PyOpcode_macro_expansion[256] = {
[BINARY_OP] = { .nuops = 1, .uops = { { _BINARY_OP, OPARG_SIMPLE, 4 } } },
[BINARY_OP_ADD_FLOAT] = { .nuops = 5, .uops = { { _GUARD_TOS_FLOAT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_FLOAT, OPARG_SIMPLE, 0 }, { _BINARY_OP_ADD_FLOAT, OPARG_SIMPLE, 5 }, { _POP_TOP_FLOAT, OPARG_SIMPLE, 5 }, { _POP_TOP_FLOAT, OPARG_SIMPLE, 5 } } },
[BINARY_OP_ADD_INT] = { .nuops = 3, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_INT, OPARG_SIMPLE, 0 }, { _BINARY_OP_ADD_INT, OPARG_SIMPLE, 5 } } },
[BINARY_OP_ADD_INT] = { .nuops = 5, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_INT, OPARG_SIMPLE, 0 }, { _BINARY_OP_ADD_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 } } },
[BINARY_OP_ADD_UNICODE] = { .nuops = 3, .uops = { { _GUARD_TOS_UNICODE, OPARG_SIMPLE, 0 }, { _GUARD_NOS_UNICODE, OPARG_SIMPLE, 0 }, { _BINARY_OP_ADD_UNICODE, OPARG_SIMPLE, 5 } } },
[BINARY_OP_EXTEND] = { .nuops = 2, .uops = { { _GUARD_BINARY_OP_EXTEND, 4, 1 }, { _BINARY_OP_EXTEND, 4, 1 } } },
[BINARY_OP_INPLACE_ADD_UNICODE] = { .nuops = 3, .uops = { { _GUARD_TOS_UNICODE, OPARG_SIMPLE, 0 }, { _GUARD_NOS_UNICODE, OPARG_SIMPLE, 0 }, { _BINARY_OP_INPLACE_ADD_UNICODE, OPARG_SIMPLE, 5 } } },
[BINARY_OP_MULTIPLY_FLOAT] = { .nuops = 5, .uops = { { _GUARD_TOS_FLOAT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_FLOAT, OPARG_SIMPLE, 0 }, { _BINARY_OP_MULTIPLY_FLOAT, OPARG_SIMPLE, 5 }, { _POP_TOP_FLOAT, OPARG_SIMPLE, 5 }, { _POP_TOP_FLOAT, OPARG_SIMPLE, 5 } } },
[BINARY_OP_MULTIPLY_INT] = { .nuops = 3, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_INT, OPARG_SIMPLE, 0 }, { _BINARY_OP_MULTIPLY_INT, OPARG_SIMPLE, 5 } } },
[BINARY_OP_MULTIPLY_INT] = { .nuops = 5, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_INT, OPARG_SIMPLE, 0 }, { _BINARY_OP_MULTIPLY_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 } } },
[BINARY_OP_SUBSCR_DICT] = { .nuops = 2, .uops = { { _GUARD_NOS_DICT, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_DICT, OPARG_SIMPLE, 5 } } },
[BINARY_OP_SUBSCR_GETITEM] = { .nuops = 4, .uops = { { _CHECK_PEP_523, OPARG_SIMPLE, 5 }, { _BINARY_OP_SUBSCR_CHECK_FUNC, OPARG_SIMPLE, 5 }, { _BINARY_OP_SUBSCR_INIT_CALL, OPARG_SIMPLE, 5 }, { _PUSH_FRAME, OPARG_SIMPLE, 5 } } },
[BINARY_OP_SUBSCR_LIST_INT] = { .nuops = 3, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_LIST, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_LIST_INT, OPARG_SIMPLE, 5 } } },
@ -1343,7 +1343,7 @@ _PyOpcode_macro_expansion[256] = {
[BINARY_OP_SUBSCR_STR_INT] = { .nuops = 3, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_UNICODE, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_STR_INT, OPARG_SIMPLE, 5 } } },
[BINARY_OP_SUBSCR_TUPLE_INT] = { .nuops = 3, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_TUPLE, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBSCR_TUPLE_INT, OPARG_SIMPLE, 5 } } },
[BINARY_OP_SUBTRACT_FLOAT] = { .nuops = 5, .uops = { { _GUARD_TOS_FLOAT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_FLOAT, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBTRACT_FLOAT, OPARG_SIMPLE, 5 }, { _POP_TOP_FLOAT, OPARG_SIMPLE, 5 }, { _POP_TOP_FLOAT, OPARG_SIMPLE, 5 } } },
[BINARY_OP_SUBTRACT_INT] = { .nuops = 3, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_INT, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBTRACT_INT, OPARG_SIMPLE, 5 } } },
[BINARY_OP_SUBTRACT_INT] = { .nuops = 5, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_INT, OPARG_SIMPLE, 0 }, { _BINARY_OP_SUBTRACT_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 }, { _POP_TOP_INT, OPARG_SIMPLE, 5 } } },
[BINARY_SLICE] = { .nuops = 1, .uops = { { _BINARY_SLICE, OPARG_SIMPLE, 0 } } },
[BUILD_INTERPOLATION] = { .nuops = 1, .uops = { { _BUILD_INTERPOLATION, OPARG_SIMPLE, 0 } } },
[BUILD_LIST] = { .nuops = 1, .uops = { { _BUILD_LIST, OPARG_SIMPLE, 0 } } },
@ -1382,7 +1382,7 @@ _PyOpcode_macro_expansion[256] = {
[CHECK_EXC_MATCH] = { .nuops = 1, .uops = { { _CHECK_EXC_MATCH, OPARG_SIMPLE, 0 } } },
[COMPARE_OP] = { .nuops = 1, .uops = { { _COMPARE_OP, OPARG_SIMPLE, 0 } } },
[COMPARE_OP_FLOAT] = { .nuops = 3, .uops = { { _GUARD_TOS_FLOAT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_FLOAT, OPARG_SIMPLE, 0 }, { _COMPARE_OP_FLOAT, OPARG_SIMPLE, 1 } } },
[COMPARE_OP_INT] = { .nuops = 3, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_INT, OPARG_SIMPLE, 0 }, { _COMPARE_OP_INT, OPARG_SIMPLE, 1 } } },
[COMPARE_OP_INT] = { .nuops = 5, .uops = { { _GUARD_TOS_INT, OPARG_SIMPLE, 0 }, { _GUARD_NOS_INT, OPARG_SIMPLE, 0 }, { _COMPARE_OP_INT, OPARG_SIMPLE, 1 }, { _POP_TOP_INT, OPARG_SIMPLE, 1 }, { _POP_TOP_INT, OPARG_SIMPLE, 1 } } },
[COMPARE_OP_STR] = { .nuops = 3, .uops = { { _GUARD_TOS_UNICODE, OPARG_SIMPLE, 0 }, { _GUARD_NOS_UNICODE, OPARG_SIMPLE, 0 }, { _COMPARE_OP_STR, OPARG_SIMPLE, 1 } } },
[CONTAINS_OP] = { .nuops = 1, .uops = { { _CONTAINS_OP, OPARG_SIMPLE, 0 } } },
[CONTAINS_OP_DICT] = { .nuops = 2, .uops = { { _GUARD_TOS_DICT, OPARG_SIMPLE, 0 }, { _CONTAINS_OP_DICT, OPARG_SIMPLE, 1 } } },

File diff suppressed because it is too large Load Diff

View File

@ -978,30 +978,30 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
},
},
[_BINARY_OP_MULTIPLY_INT] = {
.best = { 0, 1, 2, 3 },
.best = { 0, 1, 2, 2 },
.entries = {
{ 1, 0, _BINARY_OP_MULTIPLY_INT_r01 },
{ 1, 1, _BINARY_OP_MULTIPLY_INT_r11 },
{ 1, 2, _BINARY_OP_MULTIPLY_INT_r21 },
{ 2, 3, _BINARY_OP_MULTIPLY_INT_r32 },
{ 3, 0, _BINARY_OP_MULTIPLY_INT_r03 },
{ 3, 1, _BINARY_OP_MULTIPLY_INT_r13 },
{ 3, 2, _BINARY_OP_MULTIPLY_INT_r23 },
{ -1, -1, -1 },
},
},
[_BINARY_OP_ADD_INT] = {
.best = { 0, 1, 2, 3 },
.best = { 0, 1, 2, 2 },
.entries = {
{ 1, 0, _BINARY_OP_ADD_INT_r01 },
{ 1, 1, _BINARY_OP_ADD_INT_r11 },
{ 1, 2, _BINARY_OP_ADD_INT_r21 },
{ 2, 3, _BINARY_OP_ADD_INT_r32 },
{ 3, 0, _BINARY_OP_ADD_INT_r03 },
{ 3, 1, _BINARY_OP_ADD_INT_r13 },
{ 3, 2, _BINARY_OP_ADD_INT_r23 },
{ -1, -1, -1 },
},
},
[_BINARY_OP_SUBTRACT_INT] = {
.best = { 0, 1, 2, 3 },
.best = { 0, 1, 2, 2 },
.entries = {
{ 1, 0, _BINARY_OP_SUBTRACT_INT_r01 },
{ 1, 1, _BINARY_OP_SUBTRACT_INT_r11 },
{ 1, 2, _BINARY_OP_SUBTRACT_INT_r21 },
{ 2, 3, _BINARY_OP_SUBTRACT_INT_r32 },
{ 3, 0, _BINARY_OP_SUBTRACT_INT_r03 },
{ 3, 1, _BINARY_OP_SUBTRACT_INT_r13 },
{ 3, 2, _BINARY_OP_SUBTRACT_INT_r23 },
{ -1, -1, -1 },
},
},
[_GUARD_NOS_FLOAT] = {
@ -1873,7 +1873,7 @@ const _PyUopCachingInfo _PyUop_Caching[MAX_UOP_ID+1] = {
.entries = {
{ -1, -1, -1 },
{ -1, -1, -1 },
{ 1, 2, _COMPARE_OP_INT_r21 },
{ 3, 2, _COMPARE_OP_INT_r23 },
{ -1, -1, -1 },
},
},
@ -3388,18 +3388,15 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
[_GUARD_TOS_OVERFLOWED_r11] = _GUARD_TOS_OVERFLOWED,
[_GUARD_TOS_OVERFLOWED_r22] = _GUARD_TOS_OVERFLOWED,
[_GUARD_TOS_OVERFLOWED_r33] = _GUARD_TOS_OVERFLOWED,
[_BINARY_OP_MULTIPLY_INT_r01] = _BINARY_OP_MULTIPLY_INT,
[_BINARY_OP_MULTIPLY_INT_r11] = _BINARY_OP_MULTIPLY_INT,
[_BINARY_OP_MULTIPLY_INT_r21] = _BINARY_OP_MULTIPLY_INT,
[_BINARY_OP_MULTIPLY_INT_r32] = _BINARY_OP_MULTIPLY_INT,
[_BINARY_OP_ADD_INT_r01] = _BINARY_OP_ADD_INT,
[_BINARY_OP_ADD_INT_r11] = _BINARY_OP_ADD_INT,
[_BINARY_OP_ADD_INT_r21] = _BINARY_OP_ADD_INT,
[_BINARY_OP_ADD_INT_r32] = _BINARY_OP_ADD_INT,
[_BINARY_OP_SUBTRACT_INT_r01] = _BINARY_OP_SUBTRACT_INT,
[_BINARY_OP_SUBTRACT_INT_r11] = _BINARY_OP_SUBTRACT_INT,
[_BINARY_OP_SUBTRACT_INT_r21] = _BINARY_OP_SUBTRACT_INT,
[_BINARY_OP_SUBTRACT_INT_r32] = _BINARY_OP_SUBTRACT_INT,
[_BINARY_OP_MULTIPLY_INT_r03] = _BINARY_OP_MULTIPLY_INT,
[_BINARY_OP_MULTIPLY_INT_r13] = _BINARY_OP_MULTIPLY_INT,
[_BINARY_OP_MULTIPLY_INT_r23] = _BINARY_OP_MULTIPLY_INT,
[_BINARY_OP_ADD_INT_r03] = _BINARY_OP_ADD_INT,
[_BINARY_OP_ADD_INT_r13] = _BINARY_OP_ADD_INT,
[_BINARY_OP_ADD_INT_r23] = _BINARY_OP_ADD_INT,
[_BINARY_OP_SUBTRACT_INT_r03] = _BINARY_OP_SUBTRACT_INT,
[_BINARY_OP_SUBTRACT_INT_r13] = _BINARY_OP_SUBTRACT_INT,
[_BINARY_OP_SUBTRACT_INT_r23] = _BINARY_OP_SUBTRACT_INT,
[_GUARD_NOS_FLOAT_r02] = _GUARD_NOS_FLOAT,
[_GUARD_NOS_FLOAT_r12] = _GUARD_NOS_FLOAT,
[_GUARD_NOS_FLOAT_r22] = _GUARD_NOS_FLOAT,
@ -3554,7 +3551,7 @@ const uint16_t _PyUop_Uncached[MAX_UOP_REGS_ID+1] = {
[_COMPARE_OP_FLOAT_r11] = _COMPARE_OP_FLOAT,
[_COMPARE_OP_FLOAT_r21] = _COMPARE_OP_FLOAT,
[_COMPARE_OP_FLOAT_r32] = _COMPARE_OP_FLOAT,
[_COMPARE_OP_INT_r21] = _COMPARE_OP_INT,
[_COMPARE_OP_INT_r23] = _COMPARE_OP_INT,
[_COMPARE_OP_STR_r21] = _COMPARE_OP_STR,
[_IS_OP_r21] = _IS_OP,
[_CONTAINS_OP_r21] = _CONTAINS_OP,
@ -3903,10 +3900,9 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
[_BINARY_OP_ADD_FLOAT_r13] = "_BINARY_OP_ADD_FLOAT_r13",
[_BINARY_OP_ADD_FLOAT_r23] = "_BINARY_OP_ADD_FLOAT_r23",
[_BINARY_OP_ADD_INT] = "_BINARY_OP_ADD_INT",
[_BINARY_OP_ADD_INT_r01] = "_BINARY_OP_ADD_INT_r01",
[_BINARY_OP_ADD_INT_r11] = "_BINARY_OP_ADD_INT_r11",
[_BINARY_OP_ADD_INT_r21] = "_BINARY_OP_ADD_INT_r21",
[_BINARY_OP_ADD_INT_r32] = "_BINARY_OP_ADD_INT_r32",
[_BINARY_OP_ADD_INT_r03] = "_BINARY_OP_ADD_INT_r03",
[_BINARY_OP_ADD_INT_r13] = "_BINARY_OP_ADD_INT_r13",
[_BINARY_OP_ADD_INT_r23] = "_BINARY_OP_ADD_INT_r23",
[_BINARY_OP_ADD_UNICODE] = "_BINARY_OP_ADD_UNICODE",
[_BINARY_OP_ADD_UNICODE_r01] = "_BINARY_OP_ADD_UNICODE_r01",
[_BINARY_OP_ADD_UNICODE_r11] = "_BINARY_OP_ADD_UNICODE_r11",
@ -3921,10 +3917,9 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
[_BINARY_OP_MULTIPLY_FLOAT_r13] = "_BINARY_OP_MULTIPLY_FLOAT_r13",
[_BINARY_OP_MULTIPLY_FLOAT_r23] = "_BINARY_OP_MULTIPLY_FLOAT_r23",
[_BINARY_OP_MULTIPLY_INT] = "_BINARY_OP_MULTIPLY_INT",
[_BINARY_OP_MULTIPLY_INT_r01] = "_BINARY_OP_MULTIPLY_INT_r01",
[_BINARY_OP_MULTIPLY_INT_r11] = "_BINARY_OP_MULTIPLY_INT_r11",
[_BINARY_OP_MULTIPLY_INT_r21] = "_BINARY_OP_MULTIPLY_INT_r21",
[_BINARY_OP_MULTIPLY_INT_r32] = "_BINARY_OP_MULTIPLY_INT_r32",
[_BINARY_OP_MULTIPLY_INT_r03] = "_BINARY_OP_MULTIPLY_INT_r03",
[_BINARY_OP_MULTIPLY_INT_r13] = "_BINARY_OP_MULTIPLY_INT_r13",
[_BINARY_OP_MULTIPLY_INT_r23] = "_BINARY_OP_MULTIPLY_INT_r23",
[_BINARY_OP_SUBSCR_CHECK_FUNC] = "_BINARY_OP_SUBSCR_CHECK_FUNC",
[_BINARY_OP_SUBSCR_CHECK_FUNC_r23] = "_BINARY_OP_SUBSCR_CHECK_FUNC_r23",
[_BINARY_OP_SUBSCR_DICT] = "_BINARY_OP_SUBSCR_DICT",
@ -3947,10 +3942,9 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
[_BINARY_OP_SUBTRACT_FLOAT_r13] = "_BINARY_OP_SUBTRACT_FLOAT_r13",
[_BINARY_OP_SUBTRACT_FLOAT_r23] = "_BINARY_OP_SUBTRACT_FLOAT_r23",
[_BINARY_OP_SUBTRACT_INT] = "_BINARY_OP_SUBTRACT_INT",
[_BINARY_OP_SUBTRACT_INT_r01] = "_BINARY_OP_SUBTRACT_INT_r01",
[_BINARY_OP_SUBTRACT_INT_r11] = "_BINARY_OP_SUBTRACT_INT_r11",
[_BINARY_OP_SUBTRACT_INT_r21] = "_BINARY_OP_SUBTRACT_INT_r21",
[_BINARY_OP_SUBTRACT_INT_r32] = "_BINARY_OP_SUBTRACT_INT_r32",
[_BINARY_OP_SUBTRACT_INT_r03] = "_BINARY_OP_SUBTRACT_INT_r03",
[_BINARY_OP_SUBTRACT_INT_r13] = "_BINARY_OP_SUBTRACT_INT_r13",
[_BINARY_OP_SUBTRACT_INT_r23] = "_BINARY_OP_SUBTRACT_INT_r23",
[_BINARY_SLICE] = "_BINARY_SLICE",
[_BINARY_SLICE_r31] = "_BINARY_SLICE_r31",
[_BUILD_INTERPOLATION] = "_BUILD_INTERPOLATION",
@ -4088,7 +4082,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_REGS_ID+1] = {
[_COMPARE_OP_FLOAT_r21] = "_COMPARE_OP_FLOAT_r21",
[_COMPARE_OP_FLOAT_r32] = "_COMPARE_OP_FLOAT_r32",
[_COMPARE_OP_INT] = "_COMPARE_OP_INT",
[_COMPARE_OP_INT_r21] = "_COMPARE_OP_INT_r21",
[_COMPARE_OP_INT_r23] = "_COMPARE_OP_INT_r23",
[_COMPARE_OP_STR] = "_COMPARE_OP_STR",
[_COMPARE_OP_STR_r21] = "_COMPARE_OP_STR_r21",
[_CONTAINS_OP] = "_CONTAINS_OP",

View File

@ -1426,8 +1426,9 @@ class TestUopsOptimization(unittest.TestCase):
self.assertEqual(res, 3)
self.assertIsNotNone(ex)
uops = get_opnames(ex)
self.assertNotIn("_BINARY_OP_ADD_INT", uops)
self.assertNotIn("_POP_TWO_LOAD_CONST_INLINE_BORROW", uops)
# TODO (gh-142764): Re-enable after we get back automatic constant propagation.
# self.assertNotIn("_BINARY_OP_ADD_INT", uops)
# self.assertNotIn("_POP_TWO_LOAD_CONST_INLINE_BORROW", uops)
self.assertNotIn("_GUARD_NOS_INT", uops)
self.assertNotIn("_GUARD_TOS_INT", uops)
@ -1645,6 +1646,7 @@ class TestUopsOptimization(unittest.TestCase):
self.assertNotIn("_COMPARE_OP", uops)
self.assertNotIn("_POP_TWO_LOAD_CONST_INLINE_BORROW", uops)
@unittest.skip("TODO (gh-142764): Re-enable after we get back automatic constant propagation.")
def test_compare_op_int_pop_two_load_const_inline_borrow(self):
def testfunc(n):
x = 0
@ -2064,8 +2066,9 @@ class TestUopsOptimization(unittest.TestCase):
uops = get_opnames(ex)
self.assertIn("_CALL_TUPLE_1", uops)
self.assertIn("_UNPACK_SEQUENCE_TWO_TUPLE", uops)
self.assertNotIn("_COMPARE_OP_INT", uops)
self.assertNotIn("_GUARD_IS_TRUE_POP", uops)
# TODO (gh-142764): Re-enable after we get back automatic constant propagation.
# self.assertNotIn("_COMPARE_OP_INT", uops)
# self.assertNotIn("_GUARD_IS_TRUE_POP", uops)
def test_call_len(self):
def testfunc(n):
@ -2130,8 +2133,9 @@ class TestUopsOptimization(unittest.TestCase):
# length allows us to optimize more code, such as conditionals
# in this case
self.assertIn("_CALL_LEN", uops)
self.assertNotIn("_COMPARE_OP_INT", uops)
self.assertNotIn("_GUARD_IS_TRUE_POP", uops)
# TODO (gh-142764): Re-enable after we get back automatic constant propagation.
# self.assertNotIn("_COMPARE_OP_INT", uops)
# self.assertNotIn("_GUARD_IS_TRUE_POP", uops)
def test_call_builtin_o(self):
def testfunc(n):
@ -2206,8 +2210,9 @@ class TestUopsOptimization(unittest.TestCase):
self.assertIsNotNone(ex)
uops = get_opnames(ex)
self.assertIn("_BINARY_OP_SUBSCR_TUPLE_INT", uops)
self.assertNotIn("_COMPARE_OP_INT", uops)
self.assertNotIn("_GUARD_IS_TRUE_POP", uops)
# TODO (gh-142764): Re-enable after we get back automatic constant propagation.
# self.assertNotIn("_COMPARE_OP_INT", uops)
# self.assertNotIn("_GUARD_IS_TRUE_POP", uops)
def test_call_isinstance_guards_removed(self):
def testfunc(n):
@ -2468,6 +2473,66 @@ class TestUopsOptimization(unittest.TestCase):
uops = get_opnames(ex)
self.assertIn("_POP_TOP_NOP", uops)
def test_int_add_op_refcount_elimination(self):
def testfunc(n):
c = 1
res = 0
for _ in range(n):
res = c + c
return res
res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD)
self.assertIsNotNone(ex)
uops = get_opnames(ex)
self.assertIn("_BINARY_OP_ADD_INT", uops)
self.assertIn("_POP_TOP_NOP", uops)
self.assertNotIn("_POP_TOP", uops)
def test_int_sub_op_refcount_elimination(self):
def testfunc(n):
c = 1
res = 0
for _ in range(n):
res = c - c
return res
res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD)
self.assertIsNotNone(ex)
uops = get_opnames(ex)
self.assertIn("_BINARY_OP_SUBTRACT_INT", uops)
self.assertIn("_POP_TOP_NOP", uops)
self.assertNotIn("_POP_TOP", uops)
def test_int_mul_op_refcount_elimination(self):
def testfunc(n):
c = 1
res = 0
for _ in range(n):
res = c * c
return res
res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD)
self.assertIsNotNone(ex)
uops = get_opnames(ex)
self.assertIn("_BINARY_OP_MULTIPLY_INT", uops)
self.assertIn("_POP_TOP_NOP", uops)
self.assertNotIn("_POP_TOP", uops)
def test_int_cmp_op_refcount_elimination(self):
def testfunc(n):
c = 1
res = 0
for _ in range(n):
res = c == c
return res
res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD)
self.assertIsNotNone(ex)
uops = get_opnames(ex)
self.assertIn("_COMPARE_OP_INT", uops)
self.assertIn("_POP_TOP_NOP", uops)
self.assertNotIn("_POP_TOP", uops)
def test_remove_guard_for_slice_list(self):
def f(n):
for i in range(n):

View File

@ -614,7 +614,7 @@ dummy_func(
EXIT_IF(!_PyLong_IsCompact((PyLongObject *)value_o));
}
pure op(_BINARY_OP_MULTIPLY_INT, (left, right -- res)) {
pure op(_BINARY_OP_MULTIPLY_INT, (left, right -- res, l, r)) {
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
assert(PyLong_CheckExact(left_o));
@ -624,12 +624,12 @@ dummy_func(
STAT_INC(BINARY_OP, hit);
res = _PyCompactLong_Multiply((PyLongObject *)left_o, (PyLongObject *)right_o);
EXIT_IF(PyStackRef_IsNull(res));
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
l = left;
r = right;
INPUTS_DEAD();
}
pure op(_BINARY_OP_ADD_INT, (left, right -- res)) {
pure op(_BINARY_OP_ADD_INT, (left, right -- res, l, r)) {
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
assert(PyLong_CheckExact(left_o));
@ -639,12 +639,12 @@ dummy_func(
STAT_INC(BINARY_OP, hit);
res = _PyCompactLong_Add((PyLongObject *)left_o, (PyLongObject *)right_o);
EXIT_IF(PyStackRef_IsNull(res));
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
l = left;
r = right;
INPUTS_DEAD();
}
pure op(_BINARY_OP_SUBTRACT_INT, (left, right -- res)) {
pure op(_BINARY_OP_SUBTRACT_INT, (left, right -- res, l, r)) {
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
assert(PyLong_CheckExact(left_o));
@ -654,19 +654,19 @@ dummy_func(
STAT_INC(BINARY_OP, hit);
res = _PyCompactLong_Subtract((PyLongObject *)left_o, (PyLongObject *)right_o);
EXIT_IF(PyStackRef_IsNull(res));
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
l = left;
r = right;
INPUTS_DEAD();
}
macro(BINARY_OP_MULTIPLY_INT) =
_GUARD_TOS_INT + _GUARD_NOS_INT + unused/5 + _BINARY_OP_MULTIPLY_INT;
_GUARD_TOS_INT + _GUARD_NOS_INT + unused/5 + _BINARY_OP_MULTIPLY_INT + _POP_TOP_INT + _POP_TOP_INT;
macro(BINARY_OP_ADD_INT) =
_GUARD_TOS_INT + _GUARD_NOS_INT + unused/5 + _BINARY_OP_ADD_INT;
_GUARD_TOS_INT + _GUARD_NOS_INT + unused/5 + _BINARY_OP_ADD_INT + _POP_TOP_INT + _POP_TOP_INT;
macro(BINARY_OP_SUBTRACT_INT) =
_GUARD_TOS_INT + _GUARD_NOS_INT + unused/5 + _BINARY_OP_SUBTRACT_INT;
_GUARD_TOS_INT + _GUARD_NOS_INT + unused/5 + _BINARY_OP_SUBTRACT_INT + _POP_TOP_INT + _POP_TOP_INT;
op(_GUARD_NOS_FLOAT, (left, unused -- left, unused)) {
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
@ -2701,7 +2701,7 @@ dummy_func(
_GUARD_TOS_FLOAT + _GUARD_NOS_FLOAT + unused/1 + _COMPARE_OP_FLOAT;
macro(COMPARE_OP_INT) =
_GUARD_TOS_INT + _GUARD_NOS_INT + unused/1 + _COMPARE_OP_INT;
_GUARD_TOS_INT + _GUARD_NOS_INT + unused/1 + _COMPARE_OP_INT + _POP_TOP_INT + _POP_TOP_INT;
macro(COMPARE_OP_STR) =
_GUARD_TOS_UNICODE + _GUARD_NOS_UNICODE + unused/1 + _COMPARE_OP_STR;
@ -2724,7 +2724,7 @@ dummy_func(
}
// Similar to COMPARE_OP_FLOAT
op(_COMPARE_OP_INT, (left, right -- res)) {
op(_COMPARE_OP_INT, (left, right -- res, l, r)) {
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
@ -2737,9 +2737,9 @@ dummy_func(
Py_ssize_t iright = _PyLong_CompactValue((PyLongObject *)right_o);
// 2 if <, 4 if >, 8 if ==; this matches the low 4 bits of the oparg
int sign_ish = COMPARISON_BIT(ileft, iright);
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
l = left;
r = right;
DEAD(left);
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
DEAD(right);
res = (sign_ish & oparg) ? PyStackRef_True : PyStackRef_False;
// It's always a bool, so we don't care about oparg & 16.

View File

@ -3353,12 +3353,14 @@
break;
}
case _BINARY_OP_MULTIPLY_INT_r01: {
case _BINARY_OP_MULTIPLY_INT_r03: {
CHECK_CURRENT_CACHED_VALUES(0);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef right;
_PyStackRef left;
_PyStackRef res;
_PyStackRef l;
_PyStackRef r;
right = stack_pointer[-1];
left = stack_pointer[-2];
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
@ -3373,22 +3375,26 @@
SET_CURRENT_CACHED_VALUES(0);
JUMP_TO_JUMP_TARGET();
}
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
l = left;
r = right;
_tos_cache2 = r;
_tos_cache1 = l;
_tos_cache0 = res;
SET_CURRENT_CACHED_VALUES(1);
SET_CURRENT_CACHED_VALUES(3);
stack_pointer += -2;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _BINARY_OP_MULTIPLY_INT_r11: {
case _BINARY_OP_MULTIPLY_INT_r13: {
CHECK_CURRENT_CACHED_VALUES(1);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef right;
_PyStackRef left;
_PyStackRef res;
_PyStackRef l;
_PyStackRef r;
_PyStackRef _stack_item_0 = _tos_cache0;
right = _stack_item_0;
left = stack_pointer[-1];
@ -3405,22 +3411,26 @@
SET_CURRENT_CACHED_VALUES(1);
JUMP_TO_JUMP_TARGET();
}
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
l = left;
r = right;
_tos_cache2 = r;
_tos_cache1 = l;
_tos_cache0 = res;
SET_CURRENT_CACHED_VALUES(1);
SET_CURRENT_CACHED_VALUES(3);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _BINARY_OP_MULTIPLY_INT_r21: {
case _BINARY_OP_MULTIPLY_INT_r23: {
CHECK_CURRENT_CACHED_VALUES(2);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef right;
_PyStackRef left;
_PyStackRef res;
_PyStackRef l;
_PyStackRef r;
_PyStackRef _stack_item_0 = _tos_cache0;
_PyStackRef _stack_item_1 = _tos_cache1;
right = _stack_item_1;
@ -3439,55 +3449,24 @@
SET_CURRENT_CACHED_VALUES(2);
JUMP_TO_JUMP_TARGET();
}
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
l = left;
r = right;
_tos_cache2 = r;
_tos_cache1 = l;
_tos_cache0 = res;
SET_CURRENT_CACHED_VALUES(1);
SET_CURRENT_CACHED_VALUES(3);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _BINARY_OP_MULTIPLY_INT_r32: {
CHECK_CURRENT_CACHED_VALUES(3);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef right;
_PyStackRef left;
_PyStackRef res;
_PyStackRef _stack_item_0 = _tos_cache0;
_PyStackRef _stack_item_1 = _tos_cache1;
_PyStackRef _stack_item_2 = _tos_cache2;
right = _stack_item_2;
left = _stack_item_1;
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
assert(PyLong_CheckExact(left_o));
assert(PyLong_CheckExact(right_o));
assert(_PyLong_BothAreCompact((PyLongObject *)left_o, (PyLongObject *)right_o));
STAT_INC(BINARY_OP, hit);
res = _PyCompactLong_Multiply((PyLongObject *)left_o, (PyLongObject *)right_o);
if (PyStackRef_IsNull(res)) {
UOP_STAT_INC(uopcode, miss);
_tos_cache2 = right;
_tos_cache1 = left;
_tos_cache0 = _stack_item_0;
SET_CURRENT_CACHED_VALUES(3);
JUMP_TO_JUMP_TARGET();
}
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
_tos_cache1 = res;
_tos_cache0 = _stack_item_0;
SET_CURRENT_CACHED_VALUES(2);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _BINARY_OP_ADD_INT_r01: {
case _BINARY_OP_ADD_INT_r03: {
CHECK_CURRENT_CACHED_VALUES(0);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef right;
_PyStackRef left;
_PyStackRef res;
_PyStackRef l;
_PyStackRef r;
right = stack_pointer[-1];
left = stack_pointer[-2];
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
@ -3502,22 +3481,26 @@
SET_CURRENT_CACHED_VALUES(0);
JUMP_TO_JUMP_TARGET();
}
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
l = left;
r = right;
_tos_cache2 = r;
_tos_cache1 = l;
_tos_cache0 = res;
SET_CURRENT_CACHED_VALUES(1);
SET_CURRENT_CACHED_VALUES(3);
stack_pointer += -2;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _BINARY_OP_ADD_INT_r11: {
case _BINARY_OP_ADD_INT_r13: {
CHECK_CURRENT_CACHED_VALUES(1);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef right;
_PyStackRef left;
_PyStackRef res;
_PyStackRef l;
_PyStackRef r;
_PyStackRef _stack_item_0 = _tos_cache0;
right = _stack_item_0;
left = stack_pointer[-1];
@ -3534,22 +3517,26 @@
SET_CURRENT_CACHED_VALUES(1);
JUMP_TO_JUMP_TARGET();
}
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
l = left;
r = right;
_tos_cache2 = r;
_tos_cache1 = l;
_tos_cache0 = res;
SET_CURRENT_CACHED_VALUES(1);
SET_CURRENT_CACHED_VALUES(3);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _BINARY_OP_ADD_INT_r21: {
case _BINARY_OP_ADD_INT_r23: {
CHECK_CURRENT_CACHED_VALUES(2);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef right;
_PyStackRef left;
_PyStackRef res;
_PyStackRef l;
_PyStackRef r;
_PyStackRef _stack_item_0 = _tos_cache0;
_PyStackRef _stack_item_1 = _tos_cache1;
right = _stack_item_1;
@ -3568,55 +3555,24 @@
SET_CURRENT_CACHED_VALUES(2);
JUMP_TO_JUMP_TARGET();
}
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
l = left;
r = right;
_tos_cache2 = r;
_tos_cache1 = l;
_tos_cache0 = res;
SET_CURRENT_CACHED_VALUES(1);
SET_CURRENT_CACHED_VALUES(3);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _BINARY_OP_ADD_INT_r32: {
CHECK_CURRENT_CACHED_VALUES(3);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef right;
_PyStackRef left;
_PyStackRef res;
_PyStackRef _stack_item_0 = _tos_cache0;
_PyStackRef _stack_item_1 = _tos_cache1;
_PyStackRef _stack_item_2 = _tos_cache2;
right = _stack_item_2;
left = _stack_item_1;
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
assert(PyLong_CheckExact(left_o));
assert(PyLong_CheckExact(right_o));
assert(_PyLong_BothAreCompact((PyLongObject *)left_o, (PyLongObject *)right_o));
STAT_INC(BINARY_OP, hit);
res = _PyCompactLong_Add((PyLongObject *)left_o, (PyLongObject *)right_o);
if (PyStackRef_IsNull(res)) {
UOP_STAT_INC(uopcode, miss);
_tos_cache2 = right;
_tos_cache1 = left;
_tos_cache0 = _stack_item_0;
SET_CURRENT_CACHED_VALUES(3);
JUMP_TO_JUMP_TARGET();
}
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
_tos_cache1 = res;
_tos_cache0 = _stack_item_0;
SET_CURRENT_CACHED_VALUES(2);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _BINARY_OP_SUBTRACT_INT_r01: {
case _BINARY_OP_SUBTRACT_INT_r03: {
CHECK_CURRENT_CACHED_VALUES(0);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef right;
_PyStackRef left;
_PyStackRef res;
_PyStackRef l;
_PyStackRef r;
right = stack_pointer[-1];
left = stack_pointer[-2];
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
@ -3631,22 +3587,26 @@
SET_CURRENT_CACHED_VALUES(0);
JUMP_TO_JUMP_TARGET();
}
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
l = left;
r = right;
_tos_cache2 = r;
_tos_cache1 = l;
_tos_cache0 = res;
SET_CURRENT_CACHED_VALUES(1);
SET_CURRENT_CACHED_VALUES(3);
stack_pointer += -2;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _BINARY_OP_SUBTRACT_INT_r11: {
case _BINARY_OP_SUBTRACT_INT_r13: {
CHECK_CURRENT_CACHED_VALUES(1);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef right;
_PyStackRef left;
_PyStackRef res;
_PyStackRef l;
_PyStackRef r;
_PyStackRef _stack_item_0 = _tos_cache0;
right = _stack_item_0;
left = stack_pointer[-1];
@ -3663,22 +3623,26 @@
SET_CURRENT_CACHED_VALUES(1);
JUMP_TO_JUMP_TARGET();
}
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
l = left;
r = right;
_tos_cache2 = r;
_tos_cache1 = l;
_tos_cache0 = res;
SET_CURRENT_CACHED_VALUES(1);
SET_CURRENT_CACHED_VALUES(3);
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _BINARY_OP_SUBTRACT_INT_r21: {
case _BINARY_OP_SUBTRACT_INT_r23: {
CHECK_CURRENT_CACHED_VALUES(2);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef right;
_PyStackRef left;
_PyStackRef res;
_PyStackRef l;
_PyStackRef r;
_PyStackRef _stack_item_0 = _tos_cache0;
_PyStackRef _stack_item_1 = _tos_cache1;
right = _stack_item_1;
@ -3697,45 +3661,12 @@
SET_CURRENT_CACHED_VALUES(2);
JUMP_TO_JUMP_TARGET();
}
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
l = left;
r = right;
_tos_cache2 = r;
_tos_cache1 = l;
_tos_cache0 = res;
SET_CURRENT_CACHED_VALUES(1);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
case _BINARY_OP_SUBTRACT_INT_r32: {
CHECK_CURRENT_CACHED_VALUES(3);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef right;
_PyStackRef left;
_PyStackRef res;
_PyStackRef _stack_item_0 = _tos_cache0;
_PyStackRef _stack_item_1 = _tos_cache1;
_PyStackRef _stack_item_2 = _tos_cache2;
right = _stack_item_2;
left = _stack_item_1;
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
assert(PyLong_CheckExact(left_o));
assert(PyLong_CheckExact(right_o));
assert(_PyLong_BothAreCompact((PyLongObject *)left_o, (PyLongObject *)right_o));
STAT_INC(BINARY_OP, hit);
res = _PyCompactLong_Subtract((PyLongObject *)left_o, (PyLongObject *)right_o);
if (PyStackRef_IsNull(res)) {
UOP_STAT_INC(uopcode, miss);
_tos_cache2 = right;
_tos_cache1 = left;
_tos_cache0 = _stack_item_0;
SET_CURRENT_CACHED_VALUES(3);
JUMP_TO_JUMP_TARGET();
}
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
_tos_cache1 = res;
_tos_cache0 = _stack_item_0;
SET_CURRENT_CACHED_VALUES(2);
SET_CURRENT_CACHED_VALUES(3);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}
@ -9054,12 +8985,14 @@
break;
}
case _COMPARE_OP_INT_r21: {
case _COMPARE_OP_INT_r23: {
CHECK_CURRENT_CACHED_VALUES(2);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
_PyStackRef right;
_PyStackRef left;
_PyStackRef res;
_PyStackRef l;
_PyStackRef r;
_PyStackRef _stack_item_0 = _tos_cache0;
_PyStackRef _stack_item_1 = _tos_cache1;
oparg = CURRENT_OPARG();
@ -9075,13 +9008,13 @@
Py_ssize_t ileft = _PyLong_CompactValue((PyLongObject *)left_o);
Py_ssize_t iright = _PyLong_CompactValue((PyLongObject *)right_o);
int sign_ish = COMPARISON_BIT(ileft, iright);
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
l = left;
r = right;
res = (sign_ish & oparg) ? PyStackRef_True : PyStackRef_False;
_tos_cache2 = r;
_tos_cache1 = l;
_tos_cache0 = res;
_tos_cache1 = PyStackRef_ZERO_BITS;
_tos_cache2 = PyStackRef_ZERO_BITS;
SET_CURRENT_CACHED_VALUES(1);
SET_CURRENT_CACHED_VALUES(3);
assert(WITHIN_STACK_BOUNDS_IGNORING_CACHE());
break;
}

View File

@ -170,6 +170,8 @@
_PyStackRef left;
_PyStackRef right;
_PyStackRef res;
_PyStackRef l;
_PyStackRef r;
// _GUARD_TOS_INT
{
value = stack_pointer[-1];
@ -206,8 +208,20 @@
assert(_PyOpcode_Deopt[opcode] == (BINARY_OP));
JUMP_TO_PREDICTED(BINARY_OP);
}
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
l = left;
r = right;
}
// _POP_TOP_INT
{
value = r;
assert(PyLong_CheckExact(PyStackRef_AsPyObjectBorrow(value)));
PyStackRef_CLOSE_SPECIALIZED(value, _PyLong_ExactDealloc);
}
// _POP_TOP_INT
{
value = l;
assert(PyLong_CheckExact(PyStackRef_AsPyObjectBorrow(value)));
PyStackRef_CLOSE_SPECIALIZED(value, _PyLong_ExactDealloc);
}
stack_pointer[-2] = res;
stack_pointer += -1;
@ -511,6 +525,8 @@
_PyStackRef left;
_PyStackRef right;
_PyStackRef res;
_PyStackRef l;
_PyStackRef r;
// _GUARD_TOS_INT
{
value = stack_pointer[-1];
@ -547,8 +563,20 @@
assert(_PyOpcode_Deopt[opcode] == (BINARY_OP));
JUMP_TO_PREDICTED(BINARY_OP);
}
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
l = left;
r = right;
}
// _POP_TOP_INT
{
value = r;
assert(PyLong_CheckExact(PyStackRef_AsPyObjectBorrow(value)));
PyStackRef_CLOSE_SPECIALIZED(value, _PyLong_ExactDealloc);
}
// _POP_TOP_INT
{
value = l;
assert(PyLong_CheckExact(PyStackRef_AsPyObjectBorrow(value)));
PyStackRef_CLOSE_SPECIALIZED(value, _PyLong_ExactDealloc);
}
stack_pointer[-2] = res;
stack_pointer += -1;
@ -1109,6 +1137,8 @@
_PyStackRef left;
_PyStackRef right;
_PyStackRef res;
_PyStackRef l;
_PyStackRef r;
// _GUARD_TOS_INT
{
value = stack_pointer[-1];
@ -1145,8 +1175,20 @@
assert(_PyOpcode_Deopt[opcode] == (BINARY_OP));
JUMP_TO_PREDICTED(BINARY_OP);
}
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
l = left;
r = right;
}
// _POP_TOP_INT
{
value = r;
assert(PyLong_CheckExact(PyStackRef_AsPyObjectBorrow(value)));
PyStackRef_CLOSE_SPECIALIZED(value, _PyLong_ExactDealloc);
}
// _POP_TOP_INT
{
value = l;
assert(PyLong_CheckExact(PyStackRef_AsPyObjectBorrow(value)));
PyStackRef_CLOSE_SPECIALIZED(value, _PyLong_ExactDealloc);
}
stack_pointer[-2] = res;
stack_pointer += -1;
@ -4544,6 +4586,8 @@
_PyStackRef left;
_PyStackRef right;
_PyStackRef res;
_PyStackRef l;
_PyStackRef r;
// _GUARD_TOS_INT
{
value = stack_pointer[-1];
@ -4578,10 +4622,22 @@
Py_ssize_t ileft = _PyLong_CompactValue((PyLongObject *)left_o);
Py_ssize_t iright = _PyLong_CompactValue((PyLongObject *)right_o);
int sign_ish = COMPARISON_BIT(ileft, iright);
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
l = left;
r = right;
res = (sign_ish & oparg) ? PyStackRef_True : PyStackRef_False;
}
// _POP_TOP_INT
{
value = r;
assert(PyLong_CheckExact(PyStackRef_AsPyObjectBorrow(value)));
PyStackRef_CLOSE_SPECIALIZED(value, _PyLong_ExactDealloc);
}
// _POP_TOP_INT
{
value = l;
assert(PyLong_CheckExact(PyStackRef_AsPyObjectBorrow(value)));
PyStackRef_CLOSE_SPECIALIZED(value, _PyLong_ExactDealloc);
}
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);

View File

@ -251,37 +251,37 @@ dummy_func(void) {
}
}
op(_BINARY_OP_ADD_INT, (left, right -- res)) {
REPLACE_OPCODE_IF_EVALUATES_PURE(left, right);
op(_BINARY_OP_ADD_INT, (left, right -- res, l, r)) {
res = sym_new_compact_int(ctx);
l = left;
r = right;
}
op(_BINARY_OP_SUBTRACT_INT, (left, right -- res)) {
REPLACE_OPCODE_IF_EVALUATES_PURE(left, right);
op(_BINARY_OP_SUBTRACT_INT, (left, right -- res, l, r)) {
res = sym_new_compact_int(ctx);
l = left;
r = right;
}
op(_BINARY_OP_MULTIPLY_INT, (left, right -- res)) {
REPLACE_OPCODE_IF_EVALUATES_PURE(left, right);
op(_BINARY_OP_MULTIPLY_INT, (left, right -- res, l, r)) {
res = sym_new_compact_int(ctx);
l = left;
r = right;
}
op(_BINARY_OP_ADD_FLOAT, (left, right -- res, l, r)) {
REPLACE_OPCODE_IF_EVALUATES_PURE(left, right);
res = sym_new_type(ctx, &PyFloat_Type);
l = left;
r = right;
}
op(_BINARY_OP_SUBTRACT_FLOAT, (left, right -- res, l, r)) {
REPLACE_OPCODE_IF_EVALUATES_PURE(left, right);
res = sym_new_type(ctx, &PyFloat_Type);
l = left;
r = right;
}
op(_BINARY_OP_MULTIPLY_FLOAT, (left, right -- res, l, r)) {
REPLACE_OPCODE_IF_EVALUATES_PURE(left, right);
res = sym_new_type(ctx, &PyFloat_Type);
l = left;
r = right;
@ -446,9 +446,10 @@ dummy_func(void) {
}
}
op(_COMPARE_OP_INT, (left, right -- res)) {
REPLACE_OPCODE_IF_EVALUATES_PURE(left, right);
op(_COMPARE_OP_INT, (left, right -- res, l, r)) {
res = sym_new_type(ctx, &PyBool_Type);
l = left;
r = right;
}
op(_COMPARE_OP_FLOAT, (left, right -- res)) {

View File

@ -497,50 +497,18 @@
JitOptRef right;
JitOptRef left;
JitOptRef res;
JitOptRef l;
JitOptRef r;
right = stack_pointer[-1];
left = stack_pointer[-2];
if (
sym_is_safe_const(ctx, left) &&
sym_is_safe_const(ctx, right)
) {
JitOptRef left_sym = left;
JitOptRef right_sym = right;
_PyStackRef left = sym_get_const_as_stackref(ctx, left_sym);
_PyStackRef right = sym_get_const_as_stackref(ctx, right_sym);
_PyStackRef res_stackref;
/* Start of uop copied from bytecodes for constant evaluation */
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
assert(PyLong_CheckExact(left_o));
assert(PyLong_CheckExact(right_o));
assert(_PyLong_BothAreCompact((PyLongObject *)left_o, (PyLongObject *)right_o));
STAT_INC(BINARY_OP, hit);
res_stackref = _PyCompactLong_Multiply((PyLongObject *)left_o, (PyLongObject *)right_o);
if (PyStackRef_IsNull(res_stackref )) {
ctx->done = true;
break;
}
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
/* End of uop copied from bytecodes for constant evaluation */
res = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(res_stackref));
if (sym_is_const(ctx, res)) {
PyObject *result = sym_get_const(ctx, res);
if (_Py_IsImmortal(result)) {
// Replace with _POP_TWO_LOAD_CONST_INLINE_BORROW since we have two inputs and an immortal result
REPLACE_OP(this_instr, _POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
}
}
CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
res = sym_new_compact_int(ctx);
CHECK_STACK_BOUNDS(-1);
l = left;
r = right;
CHECK_STACK_BOUNDS(1);
stack_pointer[-2] = res;
stack_pointer += -1;
stack_pointer[-1] = l;
stack_pointer[0] = r;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
@ -549,50 +517,18 @@
JitOptRef right;
JitOptRef left;
JitOptRef res;
JitOptRef l;
JitOptRef r;
right = stack_pointer[-1];
left = stack_pointer[-2];
if (
sym_is_safe_const(ctx, left) &&
sym_is_safe_const(ctx, right)
) {
JitOptRef left_sym = left;
JitOptRef right_sym = right;
_PyStackRef left = sym_get_const_as_stackref(ctx, left_sym);
_PyStackRef right = sym_get_const_as_stackref(ctx, right_sym);
_PyStackRef res_stackref;
/* Start of uop copied from bytecodes for constant evaluation */
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
assert(PyLong_CheckExact(left_o));
assert(PyLong_CheckExact(right_o));
assert(_PyLong_BothAreCompact((PyLongObject *)left_o, (PyLongObject *)right_o));
STAT_INC(BINARY_OP, hit);
res_stackref = _PyCompactLong_Add((PyLongObject *)left_o, (PyLongObject *)right_o);
if (PyStackRef_IsNull(res_stackref )) {
ctx->done = true;
break;
}
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
/* End of uop copied from bytecodes for constant evaluation */
res = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(res_stackref));
if (sym_is_const(ctx, res)) {
PyObject *result = sym_get_const(ctx, res);
if (_Py_IsImmortal(result)) {
// Replace with _POP_TWO_LOAD_CONST_INLINE_BORROW since we have two inputs and an immortal result
REPLACE_OP(this_instr, _POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
}
}
CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
res = sym_new_compact_int(ctx);
CHECK_STACK_BOUNDS(-1);
l = left;
r = right;
CHECK_STACK_BOUNDS(1);
stack_pointer[-2] = res;
stack_pointer += -1;
stack_pointer[-1] = l;
stack_pointer[0] = r;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
@ -601,50 +537,18 @@
JitOptRef right;
JitOptRef left;
JitOptRef res;
JitOptRef l;
JitOptRef r;
right = stack_pointer[-1];
left = stack_pointer[-2];
if (
sym_is_safe_const(ctx, left) &&
sym_is_safe_const(ctx, right)
) {
JitOptRef left_sym = left;
JitOptRef right_sym = right;
_PyStackRef left = sym_get_const_as_stackref(ctx, left_sym);
_PyStackRef right = sym_get_const_as_stackref(ctx, right_sym);
_PyStackRef res_stackref;
/* Start of uop copied from bytecodes for constant evaluation */
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
assert(PyLong_CheckExact(left_o));
assert(PyLong_CheckExact(right_o));
assert(_PyLong_BothAreCompact((PyLongObject *)left_o, (PyLongObject *)right_o));
STAT_INC(BINARY_OP, hit);
res_stackref = _PyCompactLong_Subtract((PyLongObject *)left_o, (PyLongObject *)right_o);
if (PyStackRef_IsNull(res_stackref )) {
ctx->done = true;
break;
}
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
/* End of uop copied from bytecodes for constant evaluation */
res = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(res_stackref));
if (sym_is_const(ctx, res)) {
PyObject *result = sym_get_const(ctx, res);
if (_Py_IsImmortal(result)) {
// Replace with _POP_TWO_LOAD_CONST_INLINE_BORROW since we have two inputs and an immortal result
REPLACE_OP(this_instr, _POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
}
}
CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
res = sym_new_compact_int(ctx);
CHECK_STACK_BOUNDS(-1);
l = left;
r = right;
CHECK_STACK_BOUNDS(1);
stack_pointer[-2] = res;
stack_pointer += -1;
stack_pointer[-1] = l;
stack_pointer[0] = r;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
@ -677,44 +581,6 @@
JitOptRef r;
right = stack_pointer[-1];
left = stack_pointer[-2];
if (
sym_is_safe_const(ctx, left) &&
sym_is_safe_const(ctx, right)
) {
JitOptRef left_sym = left;
JitOptRef right_sym = right;
_PyStackRef left = sym_get_const_as_stackref(ctx, left_sym);
_PyStackRef right = sym_get_const_as_stackref(ctx, right_sym);
_PyStackRef res_stackref;
_PyStackRef l_stackref;
_PyStackRef r_stackref;
/* Start of uop copied from bytecodes for constant evaluation */
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
assert(PyFloat_CheckExact(left_o));
assert(PyFloat_CheckExact(right_o));
STAT_INC(BINARY_OP, hit);
double dres =
((PyFloatObject *)left_o)->ob_fval *
((PyFloatObject *)right_o)->ob_fval;
res_stackref = PyStackRef_FromPyObjectSteal(PyFloat_FromDouble(dres));
if (PyStackRef_IsNull(res)) {
JUMP_TO_LABEL(error);
}
l_stackref = left;
r_stackref = right;
/* End of uop copied from bytecodes for constant evaluation */
res = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(res_stackref));
l = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(l_stackref));
r = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(r_stackref));
CHECK_STACK_BOUNDS(1);
stack_pointer[-2] = res;
stack_pointer[-1] = l;
stack_pointer[0] = r;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
res = sym_new_type(ctx, &PyFloat_Type);
l = left;
r = right;
@ -735,44 +601,6 @@
JitOptRef r;
right = stack_pointer[-1];
left = stack_pointer[-2];
if (
sym_is_safe_const(ctx, left) &&
sym_is_safe_const(ctx, right)
) {
JitOptRef left_sym = left;
JitOptRef right_sym = right;
_PyStackRef left = sym_get_const_as_stackref(ctx, left_sym);
_PyStackRef right = sym_get_const_as_stackref(ctx, right_sym);
_PyStackRef res_stackref;
_PyStackRef l_stackref;
_PyStackRef r_stackref;
/* Start of uop copied from bytecodes for constant evaluation */
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
assert(PyFloat_CheckExact(left_o));
assert(PyFloat_CheckExact(right_o));
STAT_INC(BINARY_OP, hit);
double dres =
((PyFloatObject *)left_o)->ob_fval +
((PyFloatObject *)right_o)->ob_fval;
res_stackref = PyStackRef_FromPyObjectSteal(PyFloat_FromDouble(dres));
if (PyStackRef_IsNull(res)) {
JUMP_TO_LABEL(error);
}
l_stackref = left;
r_stackref = right;
/* End of uop copied from bytecodes for constant evaluation */
res = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(res_stackref));
l = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(l_stackref));
r = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(r_stackref));
CHECK_STACK_BOUNDS(1);
stack_pointer[-2] = res;
stack_pointer[-1] = l;
stack_pointer[0] = r;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
res = sym_new_type(ctx, &PyFloat_Type);
l = left;
r = right;
@ -793,44 +621,6 @@
JitOptRef r;
right = stack_pointer[-1];
left = stack_pointer[-2];
if (
sym_is_safe_const(ctx, left) &&
sym_is_safe_const(ctx, right)
) {
JitOptRef left_sym = left;
JitOptRef right_sym = right;
_PyStackRef left = sym_get_const_as_stackref(ctx, left_sym);
_PyStackRef right = sym_get_const_as_stackref(ctx, right_sym);
_PyStackRef res_stackref;
_PyStackRef l_stackref;
_PyStackRef r_stackref;
/* Start of uop copied from bytecodes for constant evaluation */
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
assert(PyFloat_CheckExact(left_o));
assert(PyFloat_CheckExact(right_o));
STAT_INC(BINARY_OP, hit);
double dres =
((PyFloatObject *)left_o)->ob_fval -
((PyFloatObject *)right_o)->ob_fval;
res_stackref = PyStackRef_FromPyObjectSteal(PyFloat_FromDouble(dres));
if (PyStackRef_IsNull(res)) {
JUMP_TO_LABEL(error);
}
l_stackref = left;
r_stackref = right;
/* End of uop copied from bytecodes for constant evaluation */
res = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(res_stackref));
l = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(l_stackref));
r = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(r_stackref));
CHECK_STACK_BOUNDS(1);
stack_pointer[-2] = res;
stack_pointer[-1] = l;
stack_pointer[0] = r;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
res = sym_new_type(ctx, &PyFloat_Type);
l = left;
r = right;
@ -2028,50 +1818,18 @@
JitOptRef right;
JitOptRef left;
JitOptRef res;
JitOptRef l;
JitOptRef r;
right = stack_pointer[-1];
left = stack_pointer[-2];
if (
sym_is_safe_const(ctx, left) &&
sym_is_safe_const(ctx, right)
) {
JitOptRef left_sym = left;
JitOptRef right_sym = right;
_PyStackRef left = sym_get_const_as_stackref(ctx, left_sym);
_PyStackRef right = sym_get_const_as_stackref(ctx, right_sym);
_PyStackRef res_stackref;
/* Start of uop copied from bytecodes for constant evaluation */
PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
assert(_PyLong_IsCompact((PyLongObject *)left_o));
assert(_PyLong_IsCompact((PyLongObject *)right_o));
STAT_INC(COMPARE_OP, hit);
assert(_PyLong_DigitCount((PyLongObject *)left_o) <= 1 &&
_PyLong_DigitCount((PyLongObject *)right_o) <= 1);
Py_ssize_t ileft = _PyLong_CompactValue((PyLongObject *)left_o);
Py_ssize_t iright = _PyLong_CompactValue((PyLongObject *)right_o);
int sign_ish = COMPARISON_BIT(ileft, iright);
PyStackRef_CLOSE_SPECIALIZED(left, _PyLong_ExactDealloc);
PyStackRef_CLOSE_SPECIALIZED(right, _PyLong_ExactDealloc);
res_stackref = (sign_ish & oparg) ? PyStackRef_True : PyStackRef_False;
/* End of uop copied from bytecodes for constant evaluation */
res = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal(res_stackref));
if (sym_is_const(ctx, res)) {
PyObject *result = sym_get_const(ctx, res);
if (_Py_IsImmortal(result)) {
// Replace with _POP_TWO_LOAD_CONST_INLINE_BORROW since we have two inputs and an immortal result
REPLACE_OP(this_instr, _POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
}
}
CHECK_STACK_BOUNDS(-1);
stack_pointer[-2] = res;
stack_pointer += -1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}
res = sym_new_type(ctx, &PyBool_Type);
CHECK_STACK_BOUNDS(-1);
l = left;
r = right;
CHECK_STACK_BOUNDS(1);
stack_pointer[-2] = res;
stack_pointer += -1;
stack_pointer[-1] = l;
stack_pointer[0] = r;
stack_pointer += 1;
ASSERT_WITHIN_STACK_BOUNDS(__FILE__, __LINE__);
break;
}