gh-106529: Implement JUMP_FORWARD in uops (with test) (#106651)

Note that this may generate two SAVE_IP uops in a row.
Removing unneeded SAVE_IP uops is the optimizer's job.
This commit is contained in:
Guido van Rossum 2023-07-11 15:13:57 -07:00 committed by GitHub
parent d0972c77aa
commit da86db56cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 0 deletions

View File

@ -2553,6 +2553,7 @@ class TestUops(unittest.TestCase):
i = 0
while i < n:
i += 1
opt = _testinternalcapi.get_uop_optimizer()
with temporary_optimizer(opt):
testfunc(10)
@ -2562,6 +2563,30 @@ class TestUops(unittest.TestCase):
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()

View File

@ -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];