Skip to content

Commit 691354c

Browse files
authored
GH-130415: Narrow str to "" based on boolean tests (GH-130476)
1 parent b6769e9 commit 691354c

File tree

6 files changed

+40
-2
lines changed

6 files changed

+40
-2
lines changed

Lib/test/test_capi/test_opt.py

+33
Original file line numberDiff line numberDiff line change
@@ -1531,6 +1531,39 @@ def f(n):
15311531
# But all of the appends we care about are still there:
15321532
self.assertEqual(uops.count("_CALL_LIST_APPEND"), len("ABCDEFG"))
15331533

1534+
def test_narrow_type_to_constant_str_empty(self):
1535+
def f(n):
1536+
trace = []
1537+
for i in range(n):
1538+
# Hopefully the optimizer can't guess what the value is.
1539+
# empty is always "", but we can only prove that it's a string:
1540+
false = i == TIER2_THRESHOLD
1541+
empty = "X"[:false]
1542+
trace.append("A")
1543+
if not empty: # Kept.
1544+
trace.append("B")
1545+
if not empty: # Removed!
1546+
trace.append("C")
1547+
trace.append("D")
1548+
if empty: # Removed!
1549+
trace.append("X")
1550+
trace.append("E")
1551+
trace.append("F")
1552+
if empty: # Removed!
1553+
trace.append("X")
1554+
trace.append("G")
1555+
return trace
1556+
1557+
trace, ex = self._run_with_optimizer(f, TIER2_THRESHOLD)
1558+
self.assertEqual(trace, list("ABCDEFG") * TIER2_THRESHOLD)
1559+
self.assertIsNotNone(ex)
1560+
uops = get_opnames(ex)
1561+
# Only one guard remains:
1562+
self.assertEqual(uops.count("_GUARD_IS_FALSE_POP"), 1)
1563+
self.assertEqual(uops.count("_GUARD_IS_TRUE_POP"), 0)
1564+
# But all of the appends we care about are still there:
1565+
self.assertEqual(uops.count("_CALL_LIST_APPEND"), len("ABCDEFG"))
1566+
15341567
def global_identity(x):
15351568
return x
15361569

Misc/ACKS

+1
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,7 @@ Keenan Lau
10651065
Piers Lauder
10661066
Ben Laurie
10671067
Yoni Lavi
1068+
Amit Lavon
10681069
Simon Law
10691070
Julia Lawall
10701071
Chris Lawrence
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improve JIT's ability to optimize strings in boolean contexts.

Python/optimizer_bytecodes.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ dummy_func(void) {
426426

427427
op(_TO_BOOL_STR, (value -- res)) {
428428
if (!optimize_to_bool(this_instr, ctx, value, &res)) {
429-
res = sym_new_type(ctx, &PyBool_Type);
429+
res = sym_new_truthiness(ctx, value, true);
430430
sym_set_type(value, &PyUnicode_Type);
431431
}
432432
}

Python/optimizer_cases.c.h

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/optimizer_symbols.c

+3
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,9 @@ _Py_uop_sym_set_const(JitOptContext *ctx, JitOptSymbol *sym, PyObject *const_val
302302
else if (type == &PyLong_Type) {
303303
_Py_uop_sym_set_const(ctx, value, Py_GetConstant(Py_CONSTANT_ZERO));
304304
}
305+
else if (type == &PyUnicode_Type) {
306+
_Py_uop_sym_set_const(ctx, value, Py_GetConstant(Py_CONSTANT_EMPTY_STR));
307+
}
305308
// TODO: More types (GH-130415)!
306309
make_const(sym, const_val);
307310
return;

0 commit comments

Comments
 (0)