Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
4 changes: 2 additions & 2 deletions Include/internal/pycore_opcode_metadata.h

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

34 changes: 18 additions & 16 deletions Include/internal/pycore_uop_ids.h

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

18 changes: 11 additions & 7 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 @@ -2935,6 +2935,23 @@ def testfunc(n):
self.assertLessEqual(count_ops(ex, "_POP_TOP"), 1)
self.assertIn("_POP_TOP_NOP", uops)

def test_to_bool_str(self):
def f(n):
for i in range(n):
false = i == TIER2_THRESHOLD
empty = "X"[:false]
if empty:
return 1
return 0

res, ex = self._run_with_optimizer(f, TIER2_THRESHOLD)
self.assertEqual(res, 0)
self.assertIsNotNone(ex)
uops = get_opnames(ex)
self.assertIn("_TO_BOOL_STR", uops)
self.assertLessEqual(count_ops(ex, "_POP_TOP"), 3)
self.assertIn("_POP_TOP_NOP", uops)

def test_to_bool_always_true(self):
def testfunc(n):
class A:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Eliminate redundant refcounting from ``TO_BOOL_STR``.
17 changes: 5 additions & 12 deletions Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -547,23 +547,16 @@ dummy_func(
EXIT_IF(!PyUnicode_CheckExact(value_o));
}

op(_TO_BOOL_STR, (value -- res)) {
op(_TO_BOOL_STR, (value -- res, v)) {
STAT_INC(TO_BOOL, hit);
PyObject *value_o = PyStackRef_AsPyObjectBorrow(value);
if (value_o == &_Py_STR(empty)) {
assert(_Py_IsImmortal(value_o));
DEAD(value);
res = PyStackRef_False;
}
else {
assert(Py_SIZE(value_o));
PyStackRef_CLOSE(value);
res = PyStackRef_True;
}
res = value_o == &_Py_STR(empty) ? PyStackRef_False : PyStackRef_True;
v = value;
DEAD(value);
}

macro(TO_BOOL_STR) =
_GUARD_TOS_UNICODE + unused/1 + unused/2 + _TO_BOOL_STR;
_GUARD_TOS_UNICODE + unused/1 + unused/2 + _TO_BOOL_STR + _POP_TOP_UNICODE;

op(_REPLACE_WITH_TRUE, (value -- res, v)) {
res = PyStackRef_True;
Expand Down
62 changes: 47 additions & 15 deletions Python/executor_cases.c.h

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

23 changes: 9 additions & 14 deletions Python/generated_cases.c.h

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

8 changes: 6 additions & 2 deletions Python/optimizer_analysis.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,8 @@ optimize_to_bool(
_PyUOpInstruction *this_instr,
JitOptContext *ctx,
JitOptRef value,
JitOptRef *result_ptr)
JitOptRef *result_ptr,
bool insert_mode)
{
if (sym_matches_type(value, &PyBool_Type)) {
REPLACE_OP(this_instr, _NOP, 0, 0);
Expand All @@ -224,7 +225,10 @@ optimize_to_bool(
int truthiness = sym_truthiness(ctx, value);
if (truthiness >= 0) {
PyObject *load = truthiness ? Py_True : Py_False;
REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)load);
int opcode = insert_mode ?
_INSERT_1_LOAD_CONST_INLINE_BORROW :
_POP_TOP_LOAD_CONST_INLINE_BORROW;
REPLACE_OP(this_instr, opcode, 0, (uintptr_t)load);
*result_ptr = sym_new_const(ctx, load);
return 1;
}
Expand Down
20 changes: 11 additions & 9 deletions Python/optimizer_bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ optimize_to_bool(
_PyUOpInstruction *this_instr,
JitOptContext *ctx,
JitOptSymbol *value,
JitOptSymbol **result_ptr);
JitOptSymbol **result_ptr,
bool insert_mode);

extern void
eliminate_pop_guard(_PyUOpInstruction *this_instr, bool exit);
Expand Down Expand Up @@ -90,7 +91,7 @@ dummy_func(void) {
}

op(_LOAD_FAST_BORROW, (-- value)) {
value = PyJitRef_Borrow(GETLOCAL(oparg));
value = PyJitRef_Borrow(GETLOCAL(oparg));
}

op(_LOAD_FAST_AND_CLEAR, (-- value)) {
Expand Down Expand Up @@ -377,36 +378,36 @@ dummy_func(void) {
}

op(_TO_BOOL, (value -- res)) {
int already_bool = optimize_to_bool(this_instr, ctx, value, &res);
int already_bool = optimize_to_bool(this_instr, ctx, value, &res, false);
if (!already_bool) {
res = sym_new_truthiness(ctx, value, true);
}
}

op(_TO_BOOL_BOOL, (value -- value)) {
int already_bool = optimize_to_bool(this_instr, ctx, value, &value);
int already_bool = optimize_to_bool(this_instr, ctx, value, &value, false);
if (!already_bool) {
sym_set_type(value, &PyBool_Type);
}
}

op(_TO_BOOL_INT, (value -- res)) {
int already_bool = optimize_to_bool(this_instr, ctx, value, &res);
int already_bool = optimize_to_bool(this_instr, ctx, value, &res, false);
if (!already_bool) {
sym_set_type(value, &PyLong_Type);
res = sym_new_truthiness(ctx, value, true);
}
}

op(_TO_BOOL_LIST, (value -- res)) {
int already_bool = optimize_to_bool(this_instr, ctx, value, &res);
int already_bool = optimize_to_bool(this_instr, ctx, value, &res, false);
if (!already_bool) {
res = sym_new_type(ctx, &PyBool_Type);
}
}

op(_TO_BOOL_NONE, (value -- res)) {
int already_bool = optimize_to_bool(this_instr, ctx, value, &res);
int already_bool = optimize_to_bool(this_instr, ctx, value, &res, false);
if (!already_bool) {
sym_set_const(value, Py_None);
res = sym_new_const(ctx, Py_False);
Expand All @@ -431,8 +432,9 @@ dummy_func(void) {
sym_set_type(value, &PyUnicode_Type);
}

op(_TO_BOOL_STR, (value -- res)) {
int already_bool = optimize_to_bool(this_instr, ctx, value, &res);
op(_TO_BOOL_STR, (value -- res, v)) {
int already_bool = optimize_to_bool(this_instr, ctx, value, &res, true);
v = value;
if (!already_bool) {
res = sym_new_truthiness(ctx, value, true);
}
Expand Down
Loading
Loading