Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
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
2 changes: 1 addition & 1 deletion Include/internal/pycore_opcode_metadata.h

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

15 changes: 15 additions & 0 deletions Lib/test/test_capi/test_opt.py
Original file line number Diff line number Diff line change
Expand Up @@ -1841,6 +1841,21 @@ def testfunc(n):
uops = get_opnames(ex)
self.assertNotIn("_GUARD_IS_NOT_NONE_POP", uops)

def test_call_tuple_1_pop_top(self):
def testfunc(n):
x = 0
for _ in range(n):
t = tuple(())
x += len(t) == 0
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_TUPLE_1", uops)
self.assertIn("_POP_TOP_NOP", uops)

def test_call_str_1(self):
def testfunc(n):
x = 0
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Eliminate redundant refcounting from ``_CALL_TUPLE_1``. Patch by Noam Cohen
10 changes: 4 additions & 6 deletions Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -4083,17 +4083,14 @@ dummy_func(
DEOPT_IF(callable_o != (PyObject *)&PyTuple_Type);
}

op(_CALL_TUPLE_1, (callable, null, arg -- res)) {
op(_CALL_TUPLE_1, (callable, null, arg -- res, a)) {
PyObject *arg_o = PyStackRef_AsPyObjectBorrow(arg);

assert(oparg == 1);
STAT_INC(CALL, hit);
INPUTS_DEAD();
Comment thread
noamcohen97 marked this conversation as resolved.
Outdated
PyObject *res_o = PySequence_Tuple(arg_o);
DEAD(null);
DEAD(callable);
(void)callable; // Silence compiler warnings about unused variables
(void)null;
PyStackRef_CLOSE(arg);
a = arg;
ERROR_IF(res_o == NULL);
res = PyStackRef_FromPyObjectSteal(res_o);
}
Expand All @@ -4104,6 +4101,7 @@ dummy_func(
_GUARD_NOS_NULL +
_GUARD_CALLABLE_TUPLE_1 +
_CALL_TUPLE_1 +
POP_TOP +
_CHECK_PERIODIC;

op(_CHECK_AND_ALLOCATE_OBJECT, (type_version/2, callable, self_or_null, unused[oparg] -- callable, self_or_null, unused[oparg])) {
Expand Down
16 changes: 5 additions & 11 deletions Python/executor_cases.c.h

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

27 changes: 14 additions & 13 deletions Python/generated_cases.c.h

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

3 changes: 2 additions & 1 deletion Python/optimizer_bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1127,14 +1127,15 @@ dummy_func(void) {
}
}

op(_CALL_TUPLE_1, (callable, null, arg -- res)) {
op(_CALL_TUPLE_1, (callable, null, arg -- res, a)) {
if (sym_matches_type(arg, &PyTuple_Type)) {
// e.g. tuple((1, 2)) or tuple(foo) where foo is known to be a tuple
res = arg;
}
else {
res = sym_new_type(ctx, &PyTuple_Type);
}
a = arg;
}

op(_GUARD_TOS_LIST, (tos -- tos)) {
Expand Down
5 changes: 4 additions & 1 deletion Python/optimizer_cases.c.h

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

Loading