Skip to content

Commit

Permalink
gh-106529: Implement JUMP_FORWARD in uops (with test) (#106651)
Browse files Browse the repository at this point in the history
Note that this may generate two SAVE_IP uops in a row.
Removing unneeded SAVE_IP uops is the optimizer's job.
  • Loading branch information
gvanrossum authored Jul 11, 2023
1 parent d0972c7 commit da86db5
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 0 deletions.
25 changes: 25 additions & 0 deletions Lib/test/test_capi/test_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2553,6 +2553,7 @@ def testfunc(n):
i = 0
while i < n:
i += 1

opt = _testinternalcapi.get_uop_optimizer()
with temporary_optimizer(opt):
testfunc(10)
Expand All @@ -2562,6 +2563,30 @@ def testfunc(n):
uops = {opname for opname, _ in ex}
self.assertIn("JUMP_TO_TOP", uops)

def test_jump_forward(self):
def testfunc(n):
a = 0
while a < n:
if a < 0:
a = -a
else:
a = +a
a += 1
return a

opt = _testinternalcapi.get_uop_optimizer()
with temporary_optimizer(opt):
testfunc(10)

ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
# for i, (opname, oparg) in enumerate(ex):
# print(f"{i:4d}: {opname:<20s} {oparg:4d}")
uops = {opname for opname, _ in ex}
# Since there is no JUMP_FORWARD instruction,
# look for indirect evidence: the += operator
self.assertIn("_BINARY_OP_ADD_INT", uops)


if __name__ == "__main__":
unittest.main()
7 changes: 7 additions & 0 deletions Python/optimizer.c
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,13 @@ translate_bytecode_to_trace(
goto done;
}

case JUMP_FORWARD:
{
// This will emit two SAVE_IP instructions; leave it to the optimizer
instr += oparg;
break;
}

default:
{
const struct opcode_macro_expansion *expansion = &_PyOpcode_macro_expansion[opcode];
Expand Down

0 comments on commit da86db5

Please sign in to comment.