Skip to content

Commit b2b261a

Browse files
authored
gh-106529: Generate uops for POP_JUMP_IF_[NOT_]NONE (#106796)
These aren't automatically translated because (ironically) they are macros deferring to POP_JUMP_IF_{TRUE,FALSE}, which are not viable uops (being manually translated). The hack is that we emit IS_NONE and then set opcode and jump to the POP_JUMP_IF_{TRUE,FALSE} translation code.
1 parent ad95c72 commit b2b261a

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

Lib/test/test_capi/test_misc.py

+30
Original file line numberDiff line numberDiff line change
@@ -2532,6 +2532,36 @@ def testfunc(n):
25322532
uops = {opname for opname, _ in ex}
25332533
self.assertIn("_POP_JUMP_IF_FALSE", uops)
25342534

2535+
def test_pop_jump_if_none(self):
2536+
def testfunc(a):
2537+
for x in a:
2538+
if x is None:
2539+
x = 0
2540+
2541+
opt = _testinternalcapi.get_uop_optimizer()
2542+
with temporary_optimizer(opt):
2543+
testfunc([1, 2, 3])
2544+
2545+
ex = get_first_executor(testfunc)
2546+
self.assertIsNotNone(ex)
2547+
uops = {opname for opname, _ in ex}
2548+
self.assertIn("_POP_JUMP_IF_TRUE", uops)
2549+
2550+
def test_pop_jump_if_not_none(self):
2551+
def testfunc(a):
2552+
for x in a:
2553+
if x is not None:
2554+
x = 0
2555+
2556+
opt = _testinternalcapi.get_uop_optimizer()
2557+
with temporary_optimizer(opt):
2558+
testfunc([1, 2, 3])
2559+
2560+
ex = get_first_executor(testfunc)
2561+
self.assertIsNotNone(ex)
2562+
uops = {opname for opname, _ in ex}
2563+
self.assertIn("_POP_JUMP_IF_FALSE", uops)
2564+
25352565
def test_pop_jump_if_true(self):
25362566
def testfunc(n):
25372567
i = 0

Python/optimizer.c

+17
Original file line numberDiff line numberDiff line change
@@ -464,9 +464,26 @@ translate_bytecode_to_trace(
464464

465465
switch (opcode) {
466466

467+
case POP_JUMP_IF_NONE:
468+
{
469+
RESERVE(2, 2);
470+
ADD_TO_TRACE(IS_NONE, 0);
471+
opcode = POP_JUMP_IF_TRUE;
472+
goto pop_jump_if_bool;
473+
}
474+
475+
case POP_JUMP_IF_NOT_NONE:
476+
{
477+
RESERVE(2, 2);
478+
ADD_TO_TRACE(IS_NONE, 0);
479+
opcode = POP_JUMP_IF_FALSE;
480+
goto pop_jump_if_bool;
481+
}
482+
467483
case POP_JUMP_IF_FALSE:
468484
case POP_JUMP_IF_TRUE:
469485
{
486+
pop_jump_if_bool:
470487
// Assume jump unlikely (TODO: handle jump likely case)
471488
RESERVE(1, 2);
472489
_Py_CODEUNIT *target_instr =

0 commit comments

Comments
 (0)