Skip to content

Commit 7c2fb2f

Browse files
committed
Macro instructions can now also have cache effects.
We pass the initial cache offset into write_body(). This is a little fiddly because everything is different for super-instructions vs macros: - For super, cache_adjust is always zero because we bump `next_instr` after each op. - For macro, cache_adjust accumulates previous cache offsets, and we bump `next_instr` at the end. Also, I had to move the bump of `next_instr` back into `Instr*.write()`. It is better placed there anyway because that function avoids the bump if the C code already ends in a `goto`, `return` or `DISPATCH*()` call. (The previous commit emitted one unreachable bump, which is now fixed.) Tested manually.
1 parent aa04e51 commit 7c2fb2f

File tree

2 files changed

+36
-26
lines changed

2 files changed

+36
-26
lines changed

Python/generated_cases.c.h

Lines changed: 12 additions & 13 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: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,16 @@ def write(self, f: typing.TextIO, indent: str) -> None:
100100
if seffect.name not in unmoved_names:
101101
f.write(f"{indent} POKE({i+1}, {seffect.name});\n")
102102

103-
def write_body(self, f: typing.TextIO, indent: str, dedent: int) -> None:
103+
# Write cache effect
104+
if self.cache_offset:
105+
f.write(f"{indent} next_instr += {self.cache_offset};\n")
106+
107+
def write_body(
108+
self, f: typing.TextIO, indent: str, dedent: int, cache_adjust: int = 0
109+
) -> None:
104110
"""Write the instruction body."""
105111
# Write cache effect variable declarations and initializations
106-
cache_offset = 0
112+
cache_offset = cache_adjust
107113
for ceffect in self.cache_effects:
108114
if ceffect.name != UNUSED:
109115
bits = ceffect.size * BITS_PER_CODE_UNIT
@@ -124,7 +130,7 @@ def write_body(self, f: typing.TextIO, indent: str, dedent: int) -> None:
124130
else:
125131
f.write(f"read_u{bits}(next_instr + {cache_offset});\n")
126132
cache_offset += ceffect.size
127-
assert cache_offset == self.cache_offset
133+
assert cache_offset == self.cache_offset + cache_adjust
128134

129135
# Get lines of text with proper dedent
130136
blocklines = self.block.to_text(dedent=dedent).splitlines(True)
@@ -167,10 +173,6 @@ def write_body(self, f: typing.TextIO, indent: str, dedent: int) -> None:
167173
else:
168174
f.write(line)
169175

170-
# Write cache effect
171-
if self.cache_offset:
172-
f.write(f"{indent}next_instr += {self.cache_offset};\n")
173-
174176

175177
@dataclasses.dataclass
176178
class SuperComponent:
@@ -234,11 +236,6 @@ def super_macro_analysis(
234236
"""
235237
lowest = current = highest = 0
236238
for instr in components:
237-
if self.kind == "macro" and instr.cache_effects:
238-
a.error(
239-
f"Super-instruction {self.name!r} has cache effects in {instr.name!r}",
240-
instr,
241-
)
242239
current -= len(instr.input_effects)
243240
lowest = min(lowest, current)
244241
current += len(instr.output_effects)
@@ -459,6 +456,7 @@ def block(head: str):
459456
else:
460457
write(f"PyObject *{var};")
461458

459+
cache_adjust = 0
462460
for i, comp in enumerate(sup.parts):
463461
if i > 0 and sup.kind == "super":
464462
write(f"NEXTOPARG();")
@@ -469,16 +467,29 @@ def block(head: str):
469467
write(f"PyObject *{ieffect.name} = {var};")
470468
for oeffect in comp.output_mapping.values():
471469
write(f"PyObject *{oeffect.name};")
472-
comp.instr.write_body(f, indent, dedent=-4)
470+
comp.instr.write_body(
471+
f, indent, dedent=-4, cache_adjust=cache_adjust
472+
)
473473
for var, oeffect in comp.output_mapping.items():
474474
write(f"{var} = {oeffect.name};")
475475

476+
if sup.kind == "macro":
477+
cache_adjust += comp.instr.cache_offset
478+
else:
479+
if comp.instr.cache_offset:
480+
write(f"next_instr += {comp.instr.cache_offset};")
481+
476482
if sup.final_sp > sup.initial_sp:
477483
write(f"STACK_GROW({sup.final_sp - sup.initial_sp});")
478484
elif sup.final_sp < sup.initial_sp:
479485
write(f"STACK_SHRINK({sup.initial_sp - sup.final_sp});")
480486
for i, var in enumerate(reversed(sup.stack[:sup.final_sp]), 1):
481487
write(f"POKE({i}, {var});")
488+
489+
# Write cache effect
490+
if sup.kind == "macro" and cache_adjust:
491+
f.write(f"{indent}next_instr += {cache_adjust};\n")
492+
482493
write(f"DISPATCH();")
483494

484495

0 commit comments

Comments
 (0)