Skip to content

Commit 289f19a

Browse files
authored
gh-148083: Constant-fold _CONTAINS_OP_SET for frozenset (gh-148084)
1 parent fe9befc commit 289f19a

File tree

6 files changed

+70
-2
lines changed

6 files changed

+70
-2
lines changed

Lib/test/test_capi/test_opt.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
# For frozendict JIT tests
2424
FROZEN_DICT_CONST = frozendict(x=1, y=2)
2525

26+
# For frozenset JIT tests
27+
FROZEN_SET_CONST = frozenset({1, 2, 3})
28+
2629
class _GenericKey:
2730
pass
2831

@@ -2169,7 +2172,8 @@ def f(n):
21692172
self.assertIsNotNone(ex)
21702173
uops = get_opnames(ex)
21712174
self.assertNotIn("_GUARD_TOS_ANY_SET", uops)
2172-
self.assertIn("_CONTAINS_OP_SET", uops)
2175+
# _CONTAINS_OP_SET is constant-folded away for frozenset literals
2176+
self.assertIn("_INSERT_2_LOAD_CONST_INLINE_BORROW", uops)
21732177

21742178
def test_remove_guard_for_known_type_tuple(self):
21752179
def f(n):
@@ -4399,6 +4403,20 @@ def testfunc(n):
43994403
# lookup result is folded to constant 1, so comparison is optimized away
44004404
self.assertNotIn("_COMPARE_OP_INT", uops)
44014405

4406+
def test_contains_op_frozenset_const_fold(self):
4407+
def testfunc(n):
4408+
x = 0
4409+
for _ in range(n):
4410+
if 1 in FROZEN_SET_CONST:
4411+
x += 1
4412+
return x
4413+
4414+
res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD)
4415+
self.assertEqual(res, TIER2_THRESHOLD)
4416+
self.assertIsNotNone(ex)
4417+
uops = get_opnames(ex)
4418+
self.assertNotIn("_CONTAINS_OP_SET", uops)
4419+
44024420
def test_binary_subscr_list_slice(self):
44034421
def testfunc(n):
44044422
x = 0
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Constant-fold ``_CONTAINS_OP_SET`` for :class:`frozenset`. Patch by Donghee Na.

Python/optimizer_analysis.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "pycore_unicodeobject.h"
3131
#include "pycore_ceval.h"
3232
#include "pycore_floatobject.h"
33+
#include "pycore_setobject.h"
3334

3435
#include <stdarg.h>
3536
#include <stdbool.h>

Python/optimizer_bytecodes.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,9 @@ dummy_func(void) {
706706
b = sym_new_type(ctx, &PyBool_Type);
707707
l = left;
708708
r = right;
709+
if (sym_matches_type(right, &PyFrozenSet_Type)) {
710+
REPLACE_OPCODE_IF_EVALUATES_PURE(left, right, b);
711+
}
709712
}
710713

711714
op(_CONTAINS_OP_DICT, (left, right -- b, l, r)) {

Python/optimizer_cases.c.h

Lines changed: 44 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/optimizer_symbols.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,8 @@ _Py_uop_sym_is_safe_const(JitOptContext *ctx, JitOptRef sym)
283283
(typ == &PyFloat_Type) ||
284284
(typ == &_PyNone_Type) ||
285285
(typ == &PyBool_Type) ||
286-
(typ == &PyFrozenDict_Type);
286+
(typ == &PyFrozenDict_Type) ||
287+
(typ == &PyFrozenSet_Type);
287288
}
288289

289290
void

0 commit comments

Comments
 (0)