Skip to content

Commit 024690c

Browse files
Address PR comments
1 parent 2ada46b commit 024690c

File tree

5 files changed

+53
-137
lines changed

5 files changed

+53
-137
lines changed

Lib/test/test_capi/test_opt.py

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1665,38 +1665,6 @@ def testfunc(n):
16651665
self.assertNotIn("_UNARY_INVERT", uops)
16661666
self.assertNotIn("_POP_TOP_LOAD_CONST_INLINE_BORROW", uops)
16671667

1668-
def test_replace_with_true_pop_top_load_const_inline_borrow(self):
1669-
def testfunc(n):
1670-
x = 0
1671-
for _ in range(n):
1672-
a = 42
1673-
result = bool(a)
1674-
if result:
1675-
x += 1
1676-
return x
1677-
res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD)
1678-
self.assertEqual(res, TIER2_THRESHOLD)
1679-
self.assertIsNotNone(ex)
1680-
uops = get_opnames(ex)
1681-
self.assertNotIn("_REPLACE_WITH_TRUE", uops)
1682-
self.assertNotIn("_POP_TOP_LOAD_CONST_INLINE_BORROW", uops)
1683-
1684-
def test_to_bool_none_pop_top_load_const_inline_borrow(self):
1685-
def testfunc(n):
1686-
x = 0
1687-
for _ in range(n):
1688-
a = None
1689-
result = bool(a)
1690-
if result:
1691-
x += 1
1692-
return x
1693-
res, ex = self._run_with_optimizer(testfunc, TIER2_THRESHOLD)
1694-
self.assertEqual(res, 0)
1695-
self.assertIsNotNone(ex)
1696-
uops = get_opnames(ex)
1697-
self.assertNotIn("_TO_BOOL_NONE", uops)
1698-
self.assertNotIn("_POP_TOP_LOAD_CONST_INLINE_BORROW", uops)
1699-
17001668
def test_compare_op_pop_two_load_const_inline_borrow(self):
17011669
def testfunc(n):
17021670
x = 0
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Optimize ``_COMPARE_OP``, ``_CONTAINS_OP``, ``_GET_LEN``, ``_REPLACE_WITH_TRUE``, ``_TO_BOOL_NONE``, `_UNARY_NEGATIVE``, ``_UNARY_NOT``, and ``_UNARY_INVERT`` in JIT builds with constant-loading uops (``_POP_TWO_LOAD_CONST_INLINE_BORROW`` and ``_POP_TOP_LOAD_CONST_INLINE_BORROW``), and then remove both to reduce instruction count.
1+
Optimize ``_COMPARE_OP``, ``_CONTAINS_OP``, ``_UNARY_NEGATIVE``, ``_UNARY_NOT``, and ``_UNARY_INVERT`` in JIT builds with constant-loading uops (``_POP_TWO_LOAD_CONST_INLINE_BORROW`` and ``_POP_TOP_LOAD_CONST_INLINE_BORROW``), and then remove both to reduce instruction count.

Python/optimizer_bytecodes.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,6 @@ dummy_func(void) {
362362
}
363363

364364
op(_TO_BOOL_NONE, (value -- res)) {
365-
REPLACE_OPCODE_IF_EVALUATES_PURE(value);
366365
int already_bool = optimize_to_bool(this_instr, ctx, value, &res);
367366
if (!already_bool) {
368367
sym_set_const(value, Py_None);
@@ -424,8 +423,8 @@ dummy_func(void) {
424423
}
425424

426425
op(_COMPARE_OP, (left, right -- res)) {
426+
REPLACE_OPCODE_IF_EVALUATES_PURE(left, right);
427427
if (oparg & 16) {
428-
REPLACE_OPCODE_IF_EVALUATES_PURE(left, right);
429428
res = sym_new_type(ctx, &PyBool_Type);
430429
}
431430
else {
@@ -1028,7 +1027,6 @@ dummy_func(void) {
10281027
}
10291028

10301029
op(_REPLACE_WITH_TRUE, (value -- res)) {
1031-
REPLACE_OPCODE_IF_EVALUATES_PURE(value);
10321030
res = sym_new_const(ctx, Py_True);
10331031
}
10341032

Python/optimizer_cases.c.h

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

Tools/cases_generator/optimizer_generator.py

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -232,29 +232,28 @@ def replace_opcode_if_evaluates_pure(
232232
emitter.emit(f"{outp.name} = sym_new_const_steal(ctx, PyStackRef_AsPyObjectSteal({outp.name}_stackref));\n")
233233
else:
234234
emitter.emit(f"{outp.name} = sym_new_const(ctx, PyStackRef_AsPyObjectBorrow({outp.name}_stackref));\n")
235-
236235
if len(self.original_uop.stack.outputs) == 1:
237236
outp = self.original_uop.stack.outputs[0]
238237
if not outp.peek:
239238
if self.original_uop.name.startswith('_'):
240-
if len(used_stack_inputs) == 1:
241-
emitter.emit(f"""
242-
if (sym_is_const(ctx, {outp.name})) {{
243-
PyObject *result = sym_get_const(ctx, {outp.name});
244-
if (_Py_IsImmortal(result)) {{
245-
// Replace with _POP_TOP_LOAD_CONST_INLINE_BORROW since we have one input and an immortal result
246-
REPLACE_OP(this_instr, _POP_TOP_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
247-
}}
248-
}}""")
249-
elif len(used_stack_inputs) == 2:
239+
# Map input count to the appropriate constant-loading uop
240+
input_count_to_uop = {
241+
1: "_POP_TOP_LOAD_CONST_INLINE_BORROW",
242+
2: "_POP_TWO_LOAD_CONST_INLINE_BORROW"
243+
}
244+
245+
input_count = len(used_stack_inputs)
246+
if input_count in input_count_to_uop:
247+
replacement_uop = input_count_to_uop[input_count]
248+
input_desc = "one input" if input_count == 1 else "two inputs"
250249
emitter.emit(f"""
251-
if (sym_is_const(ctx, {outp.name})) {{
252-
PyObject *result = sym_get_const(ctx, {outp.name});
253-
if (_Py_IsImmortal(result)) {{
254-
// Replace with _POP_TWO_LOAD_CONST_INLINE_BORROW since we have two inputs and an immortal result
255-
REPLACE_OP(this_instr, _POP_TWO_LOAD_CONST_INLINE_BORROW, 0, (uintptr_t)result);
256-
}}
257-
}}""")
250+
if (sym_is_const(ctx, {outp.name})) {{
251+
PyObject *result = sym_get_const(ctx, {outp.name});
252+
if (_Py_IsImmortal(result)) {{
253+
// Replace with {replacement_uop} since we have {input_desc} and an immortal result
254+
REPLACE_OP(this_instr, {replacement_uop}, 0, (uintptr_t)result);
255+
}}
256+
}}""")
258257

259258
storage.flush(self.out)
260259
emitter.emit("break;\n")

0 commit comments

Comments
 (0)