Skip to content

Commit 94630d4

Browse files
committed
Stop special-casing _PUSH_FRAME altogether
Instead, we special-case SAVE_IP: - Its Tier 2 expansion sets oparg to the instruction offset - In Tier 1 it is a no-op (and skipped if present in a macro)
1 parent 6facc8d commit 94630d4

File tree

3 files changed

+19
-10
lines changed

3 files changed

+19
-10
lines changed

Python/bytecodes.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3005,6 +3005,7 @@ dummy_func(
30053005
_CHECK_FUNCTION_EXACT_ARGS +
30063006
_CHECK_STACK_SPACE +
30073007
_INIT_CALL_PY_EXACT_ARGS +
3008+
SAVE_IP + // Tier 2 only; special-cased oparg
30083009
_PUSH_FRAME;
30093010

30103011
inst(CALL_PY_WITH_DEFAULTS, (unused/1, func_version/2, callable, self_or_null, args[oparg] -- unused)) {

Tools/cases_generator/generate_cases.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -443,13 +443,6 @@ def write_macro_expansions(
443443
expansions: list[tuple[str, int, int]] = [] # [(name, size, offset), ...]
444444
for part in parts:
445445
if isinstance(part, Component):
446-
# _PUSH_FRAME is super special; it expands to SAVE_IP(next_instr) + _PUSH_FRAME
447-
if part.instr.name == "_PUSH_FRAME":
448-
expansions.append(
449-
("SAVE_IP", OPARG_SIZES["OPARG_SAVE_IP"], cache_offset)
450-
)
451-
expansions.append(("_PUSH_FRAME", OPARG_SIZES["OPARG_FULL"], 0))
452-
continue
453446
# All component instructions must be viable uops
454447
if not part.instr.is_viable_uop():
455448
# This note just reminds us about macros that cannot
@@ -463,7 +456,10 @@ def write_macro_expansions(
463456
)
464457
return
465458
if not part.active_caches:
466-
size, offset = OPARG_SIZES["OPARG_FULL"], 0
459+
if part.instr.name == "SAVE_IP":
460+
size, offset = OPARG_SIZES["OPARG_SAVE_IP"], cache_offset
461+
else:
462+
size, offset = OPARG_SIZES["OPARG_FULL"], 0
467463
else:
468464
# If this assert triggers, is_viable_uops() lied
469465
assert len(part.active_caches) == 1, (name, part.instr.name)

Tools/cases_generator/stacking.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ class EffectManager:
147147
# Track offsets from stack pointer
148148
min_offset: StackOffset
149149
final_offset: StackOffset
150+
# Link to previous manager
151+
pred: "EffectManager | None" = None
150152

151153
def __init__(
152154
self,
@@ -168,7 +170,8 @@ def __init__(
168170
self.pokes.append(StackItem(offset=self.final_offset.clone(), effect=eff))
169171
self.final_offset.higher(eff)
170172

171-
if pred:
173+
self.pred = pred
174+
while pred:
172175
# Replace push(x) + pop(y) with copy(x, y).
173176
# Check that the sources and destinations are disjoint.
174177
sources: set[str] = set()
@@ -193,6 +196,11 @@ def __init__(
193196
sources,
194197
destinations,
195198
)
199+
# See if we can get more copies of a earlier predecessor.
200+
if self.peeks and not pred.pokes and not pred.peeks:
201+
pred = pred.pred
202+
else:
203+
pred = None # Break
196204

197205
def adjust_deeper(self, eff: StackEffect) -> None:
198206
for peek in self.peeks:
@@ -305,7 +313,11 @@ def write_single_instr(
305313
def write_macro_instr(
306314
mac: MacroInstruction, out: Formatter, family: Family | None
307315
) -> None:
308-
parts = [part for part in mac.parts if isinstance(part, Component)]
316+
parts = [
317+
part
318+
for part in mac.parts
319+
if isinstance(part, Component) and part.instr.name != "SAVE_IP"
320+
]
309321
out.emit("")
310322
with out.block(f"TARGET({mac.name})"):
311323
if mac.predicted:

0 commit comments

Comments
 (0)