Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Merge remote-tracking branch 'upstream/main' into jit-call-tuple-1
  • Loading branch information
tomasr8 committed Apr 24, 2025
commit 7e7c13ef5955ca748200e1a1f6ba3fd83025f568
58 changes: 57 additions & 1 deletion Lib/test/test_capi/test_opt.py
Original file line number Diff line number Diff line change
Expand Up @@ -1798,6 +1798,62 @@ def testfunc(n):
self.assertIn("_CALL_TYPE_1", uops)
self.assertNotIn("_GUARD_IS_NOT_NONE_POP", uops)

def test_call_str_1(self):
def testfunc(n):
x = 0
for _ in range(n):
y = str(42)
if y == '42':
x += 1
return x

res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD)
self.assertEqual(res, TIER2_THRESHOLD)
self.assertIsNotNone(ex)
uops = get_opnames(ex)
self.assertIn("_CALL_STR_1", uops)
self.assertNotIn("_GUARD_NOS_NULL", uops)
self.assertNotIn("_GUARD_CALLABLE_STR_1", uops)

def test_call_str_1_result_is_str(self):
def testfunc(n):
x = 0
for _ in range(n):
y = str(42) + 'foo'
if y == '42foo':
x += 1
return x

res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD)
self.assertEqual(res, TIER2_THRESHOLD)
self.assertIsNotNone(ex)
uops = get_opnames(ex)
self.assertIn("_CALL_STR_1", uops)
self.assertIn("_BINARY_OP_ADD_UNICODE", uops)
self.assertNotIn("_GUARD_NOS_UNICODE", uops)
self.assertNotIn("_GUARD_TOS_UNICODE", uops)

def test_call_str_1_result_is_const_for_str_input(self):
# Test a special case where the argument of str(arg)
# is known to be a string. The information about the
# argument being a string should be propagated to the
# result of str(arg).
def testfunc(n):
x = 0
for _ in range(n):
y = str('foo') # string argument
if y: # _TO_BOOL_STR + _GUARD_IS_TRUE_POP are removed
x += 1
return x

res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD)
self.assertEqual(res, TIER2_THRESHOLD)
self.assertIsNotNone(ex)
uops = get_opnames(ex)
self.assertIn("_CALL_STR_1", uops)
self.assertNotIn("_TO_BOOL_STR", uops)
self.assertNotIn("_GUARD_IS_TRUE_POP", uops)

def test_call_tuple_1(self):
def testfunc(n):
x = 0
Expand Down Expand Up @@ -1842,7 +1898,7 @@ def testfunc(n):
for _ in range(n):
y = tuple((1, 2)) # tuple argument
a, _ = y # _UNPACK_SEQUENCE_TWO_TUPLE
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I needed to use UNPACK_SEQUENCE(_TWO)_TUPLE here since it is currently the only uop that propagates the tuple items to the result.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice observation. Seems like _BINARY_OP_SUBSCR_TUPLE_INT could be taught how to do this pretty easily for a constant RHS. Want to add that to your queue?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It's already in the queue 😄

if a == 1: # _COMPARE_OP_INT + _GUARD_IS_TRUE_POP are removed
if a == 1: # _COMPARE_OP_INT + _GUARD_IS_TRUE_POP are removed
x += 1
return x

Expand Down
7 changes: 7 additions & 0 deletions Python/optimizer_bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1048,6 +1048,13 @@ dummy_func(void) {
sym_set_const(callable, (PyObject *)&PyTuple_Type);
}

op(_GUARD_CALLABLE_STR_1, (callable, unused, unused -- callable, unused, unused)) {
if (sym_get_const(ctx, callable) == (PyObject *)&PyUnicode_Type) {
REPLACE_OP(this_instr, _NOP, 0, 0);
}
sym_set_const(callable, (PyObject *)&PyUnicode_Type);
}

// END BYTECODES //

}
You are viewing a condensed version of this merge commit. You can view the full changes here.