Skip to content

Commit 8fdbbf8

Browse files
authored
GH-131798: Type-propagate string/list/tuple slices (GH-134671)
1 parent ac9c343 commit 8fdbbf8

File tree

4 files changed

+55
-3
lines changed

4 files changed

+55
-3
lines changed

Lib/test/test_capi/test_opt.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1666,13 +1666,11 @@ def testfunc(n):
16661666
self.assertIn("_CONTAINS_OP_DICT", uops)
16671667
self.assertNotIn("_TO_BOOL_BOOL", uops)
16681668

1669-
16701669
def test_remove_guard_for_known_type_str(self):
16711670
def f(n):
16721671
for i in range(n):
16731672
false = i == TIER2_THRESHOLD
16741673
empty = "X"[:false]
1675-
empty += "" # Make JIT realize this is a string.
16761674
if empty:
16771675
return 1
16781676
return 0
@@ -2249,6 +2247,34 @@ def f(n):
22492247
self.assertNotIn("_LOAD_ATTR_METHOD_NO_DICT", uops)
22502248
self.assertNotIn("_LOAD_ATTR_METHOD_LAZY_DICT", uops)
22512249

2250+
def test_remove_guard_for_slice_list(self):
2251+
def f(n):
2252+
for i in range(n):
2253+
false = i == TIER2_THRESHOLD
2254+
sliced = [1, 2, 3][:false]
2255+
if sliced:
2256+
return 1
2257+
return 0
2258+
2259+
res, ex = self._run_with_optimizer(f, TIER2_THRESHOLD)
2260+
self.assertEqual(res, 0)
2261+
self.assertIsNotNone(ex)
2262+
uops = get_opnames(ex)
2263+
self.assertIn("_TO_BOOL_LIST", uops)
2264+
self.assertNotIn("_GUARD_TOS_LIST", uops)
2265+
2266+
def test_remove_guard_for_slice_tuple(self):
2267+
def f(n):
2268+
for i in range(n):
2269+
false = i == TIER2_THRESHOLD
2270+
a, b = (1, 2, 3)[: false + 2]
2271+
2272+
_, ex = self._run_with_optimizer(f, TIER2_THRESHOLD)
2273+
self.assertIsNotNone(ex)
2274+
uops = get_opnames(ex)
2275+
self.assertIn("_UNPACK_SEQUENCE_TWO_TUPLE", uops)
2276+
self.assertNotIn("_GUARD_TOS_TUPLE", uops)
2277+
22522278

22532279
def global_identity(x):
22542280
return x
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Make the JIT optimizer understand that slicing a string/list/tuple returns the same type.

Python/optimizer_bytecodes.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,6 +1237,20 @@ dummy_func(void) {
12371237
sym_set_const(callable, list_append);
12381238
}
12391239

1240+
op(_BINARY_SLICE, (container, start, stop -- res)) {
1241+
// Slicing a string/list/tuple always returns the same type.
1242+
PyTypeObject *type = sym_get_type(container);
1243+
if (type == &PyUnicode_Type ||
1244+
type == &PyList_Type ||
1245+
type == &PyTuple_Type)
1246+
{
1247+
res = sym_new_type(ctx, type);
1248+
}
1249+
else {
1250+
res = sym_new_not_null(ctx);
1251+
}
1252+
}
1253+
12401254
// END BYTECODES //
12411255

12421256
}

Python/optimizer_cases.c.h

Lines changed: 12 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy