8000 gh-106701: Move the hand-written Tier 2 uops to bytecodes.c (#106702) · python/cpython@e6e0ea0 · GitHub
[go: up one dir, main page]

Skip to content

Commit e6e0ea0

Browse files
authored
gh-106701: Move the hand-written Tier 2 uops to bytecodes.c (#106702)
This moves EXIT_TRACE, SAVE_IP, JUMP_TO_TOP, and _POP_JUMP_IF_{FALSE,TRUE} from ceval.c to bytecodes.c. They are no less special than before, but this way they are discoverable o the copy-and-patch tooling.
1 parent 2f3ee02 commit e6e0ea0

File tree

5 files changed

+124
-94
lines changed

5 files changed

+124
-94
lines changed

Include/internal/pycore_opcode_metadata.h

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

Python/bytecodes.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3654,6 +3654,36 @@ dummy_func(
36543654
Py_UNREACHABLE();
36553655
}
36563656

3657+
///////// Tier-2 only opcodes /////////
3658+
3659+
op(_POP_JUMP_IF_FALSE, (flag -- )) {
3660+
if (Py_IsFalse(flag)) {
3661+
pc = oparg;
3662+
}
3663+
}
3664+
3665+
op(_POP_JUMP_IF_TRUE, (flag -- )) {
3666+
if (Py_IsTrue(flag)) {
3667+
pc = oparg;
3668+
}
3669+
}
3670+
3671+
op(JUMP_TO_TOP, (--)) {
3672+
pc = 0;
3673+
CHECK_EVAL_BREAKER();
3674+
}
3675+
3676+
op(SAVE_IP, (--)) {
3677+
frame->prev_instr = ip_offset + oparg;
3678+
}
3679+
3680+
op(EXIT_TRACE, (--)) {
3681+
frame->prev_instr--; // Back up to just before destination
3682+
_PyFrame_SetStackPointer(frame, stack_pointer);
3683+
Py_DECREF(self);
3684+
return frame;
3685+
}
3686+
36573687

36583688
// END BYTECODES //
36593689

Python/ceval.c

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2764,46 +2764,6 @@ _PyUopExecute(_PyExecutorObject *executor, _PyInterpreterFrame *frame, PyObject
27642764
#define ENABLE_SPECIALIZATION 0
27652765
#include "executor_cases.c.h"
27662766

2767-
// NOTE: These pop-jumps move the uop pc, not the bytecode ip
2768-
case _POP_JUMP_IF_FALSE:
2769-
{
2770-
if (Py_IsFalse(stack_pointer[-1])) {
2771-
pc = oparg;
2772-
}
2773-
stack_pointer--;
2774-
break;
2775-
}
2776-
2777-
case _POP_JUMP_IF_TRUE:
2778-
{
2779-
if (Py_IsTrue(stack_pointer[-1])) {
2780-
pc = oparg;
2781-
}
2782-
stack_pointer--;
2783-
break;
2784-
}
2785-
2786-
case JUMP_TO_TOP:
2787-
{
2788-
pc = 0;
2789-
CHECK_EVAL_BREAKER();
2790-
break;
2791-
}
2792-
2793-
case SAVE_IP:
2794-
{
2795-
frame->prev_instr = ip_offset + oparg;
2796-
break;
2797-
}
2798-
2799-
case EXIT_TRACE:
2800-
{
2801-
frame->prev_instr--; // Back up to just before destination
2802-
_PyFrame_SetStackPointer(frame, stack_pointer);
2803-
Py_DECREF(self);
2804-
return frame;
2805-
}
2806-
28072767
default:
28082768
{
28092769
fprintf(stderr, "Unknown uop %d, operand %" PRIu64 "\n", opcode, operand);

Python/executor_cases.c.h

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

Tools/cases_generator/generate_cases.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,8 @@ def __init__(self, inst: parser.InstDef):
410410

411411
def is_viable_uop(self) -> bool:
412412
"""Whether this instruction is viable as a uop."""
413+
if self.name == "EXIT_TRACE":
414+
return True # This has 'return frame' but it's okay
413415
if self.always_exits:
414416
# print(f"Skipping {self.name} because it always exits")
415417
return False
@@ -1278,7 +1280,7 @@ def write_metadata(self) -> None:
12781280
typing.assert_never(thing)
12791281

12801282
with self.out.block("const char * const _PyOpcode_uop_name[512] =", ";"):
1281-
self.write_uop_items(lambda name, counter: f"[{counter}] = \"{name}\",")
1283+
self.write_uop_items(lambda name, counter: f"[{name}] = \"{name}\",")
12821284

12831285
self.out.emit("#endif // NEED_OPCODE_METADATA")
12841286

@@ -1324,17 +1326,19 @@ def write_pseudo_instrs(self) -> None:
13241326
def write_uop_items(self, make_text: typing.Callable[[str, int], str]) -> None:
13251327
"""Write '#define XXX NNN' for each uop"""
13261328
counter = 300 # TODO: Avoid collision with pseudo instructions
1329+
seen = set()
13271330

13281331
def add(name: str) -> None:
1332+
if name in seen:
1333+
return
13291334
nonlocal counter
13301335
self.out.emit(make_text(name, counter))
13311336
counter += 1
1337+
seen.add(name)
13321338

1339+
# These two are first by convention
13331340
add("EXIT_TRACE")
13341341
add("SAVE_IP")
1335-
add("_POP_JUMP_IF_FALSE")
1336-
add("_POP_JUMP_IF_TRUE")
1337-
add("JUMP_TO_TOP")
13381342

13391343
for instr in self.instrs.values():
13401344
if instr.kind == "op" and instr.is_viable_uop():

0 commit comments

Comments
 (0)
0