diff options
author | Guido van Rossum <guido@python.org> | 2023-05-31 15:09:23 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-31 15:09:23 (GMT) |
commit | df396b59af9d50892e5e30463300e8458cb84263 (patch) | |
tree | 9361299693ffb3cb8c5fecadacea0218c4cf7929 /Tools/cases_generator | |
parent | fbc9d0dbb22549bac2706f61f3ab631239d357b4 (diff) | |
download | cpython-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.py | 39 |
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: |