summaryrefslogtreecommitdiffstats
path: root/Tools/cases_generator
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2023-05-31 15:09:23 (GMT)
committerGitHub <noreply@github.com>2023-05-31 15:09:23 (GMT)
commitdf396b59af9d50892e5e30463300e8458cb84263 (patch)
tree9361299693ffb3cb8c5fecadacea0218c4cf7929 /Tools/cases_generator
parentfbc9d0dbb22549bac2706f61f3ab631239d357b4 (diff)
downloadcpython-df396b59af9d50892e5e30463300e8458cb84263.zip
cpython-df396b59af9d50892e5e30463300e8458cb84263.tar.gz
cpython-df396b59af9d50892e5e30463300e8458cb84263.tar.bz2
gh-104909: Split BINARY_OP into micro-ops (#104910)
Co-authored-by: Brandt Bucher <brandtbucher@gmail.com>
Diffstat (limited to 'Tools/cases_generator')
-rw-r--r--Tools/cases_generator/generate_cases.py39
1 files changed, 32 insertions, 7 deletions
diff --git a/Tools/cases_generator/generate_cases.py b/Tools/cases_generator/generate_cases.py
index 62ddeac..22184d5 100644
--- a/Tools/cases_generator/generate_cases.py
+++ b/Tools/cases_generator/generate_cases.py
@@ -489,6 +489,7 @@ class MacroInstruction(SuperOrMacroInstruction):
macro: parser.Macro
parts: list[Component | parser.CacheEffect]
+ predicted: bool = False
@dataclasses.dataclass
@@ -633,8 +634,8 @@ class Analyzer:
Raises SystemExit if there is an error.
"""
- self.find_predictions()
self.analyze_supers_and_macros()
+ self.find_predictions()
self.map_families()
self.check_families()
@@ -648,6 +649,8 @@ class Analyzer:
for target in targets:
if target_instr := self.instrs.get(target):
target_instr.predicted = True
+ elif target_macro := self.macro_instrs.get(target):
+ target_macro.predicted = True
else:
self.error(
f"Unknown instruction {target!r} predicted in {instr.name!r}",
@@ -896,6 +899,7 @@ class Analyzer:
pushed = ""
case parser.Super():
instr = self.super_instrs[thing.name]
+ # TODO: Same as for Macro below, if needed.
popped = "+".join(
effect_str(comp.instr.input_effects) for comp in instr.parts
)
@@ -905,12 +909,30 @@ class Analyzer:
case parser.Macro():
instr = self.macro_instrs[thing.name]
parts = [comp for comp in instr.parts if isinstance(comp, Component)]
- popped = "+".join(
- effect_str(comp.instr.input_effects) for comp in parts
- )
- pushed = "+".join(
- effect_str(comp.instr.output_effects) for comp in parts
- )
+ # Note: stack_analysis() already verifies that macro components
+ # have no variable-sized stack effects.
+ low = 0
+ sp = 0
+ high = 0
+ for comp in parts:
+ for effect in comp.instr.input_effects:
+ assert not effect.cond, effect
+ assert not effect.size, effect
+ sp -= 1
+ low = min(low, sp)
+ for effect in comp.instr.output_effects:
+ assert not effect.cond, effect
+ assert not effect.size, effect
+ sp += 1
+ high = max(sp, high)
+ if high != max(0, sp):
+ # If you get this, intermediate stack growth occurs,
+ # and stack size calculations may go awry.
+ # E.g. [push, pop]. The fix would be for stack size
+ # calculations to use the micro ops.
+ self.error("Macro has virtual stack growth", thing)
+ popped = str(-low)
+ pushed = str(sp - low)
case _:
typing.assert_never(thing)
return instr, popped, pushed
@@ -1152,6 +1174,9 @@ class Analyzer:
# outer block, rather than trusting the compiler to optimize it.
self.out.emit("")
with self.out.block(f"TARGET({up.name})"):
+ match up:
+ case MacroInstruction(predicted=True, name=name):
+ self.out.emit(f"PREDICTED({name});")
for i, var in reversed(list(enumerate(up.stack))):
src = None
if i < up.initial_sp: