Skip to content

Commit b9e7dc7

Browse files
authored
gh-105229: Remove syntactic support for super-instructions (#105703)
It will not be used again.
1 parent 4f7d3b6 commit b9e7dc7

File tree

2 files changed

+38
-143
lines changed

2 files changed

+38
-143
lines changed

Tools/cases_generator/generate_cases.py

Lines changed: 29 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ def write_body(self, out: Formatter, dedent: int, cache_adjust: int = 0) -> None
390390
names_to_skip = self.unmoved_names | frozenset({UNUSED, "null"})
391391
offset = 0
392392
context = self.block.context
393-
assert context != None
393+
assert context is not None and context.owner is not None
394394
filename = context.owner.filename
395395
for line in self.block_text:
396396
out.set_lineno(self.block_line + offset, filename)
@@ -464,28 +464,14 @@ def write_body(self, out: Formatter, cache_adjust: int) -> None:
464464

465465

466466
@dataclasses.dataclass
467-
class SuperOrMacroInstruction:
468-
"""Common fields for super- and macro instructions."""
467+
class MacroInstruction:
468+
"""A macro instruction."""
469469

470470
name: str
471471
stack: list[StackEffect]
472472
initial_sp: int
473473
final_sp: int
474474
instr_fmt: str
475-
476-
477-
@dataclasses.dataclass
478-
class SuperInstruction(SuperOrMacroInstruction):
479-
"""A super-instruction."""
480-
481-
super: parser.Super
482-
parts: list[Component]
483-
484-
485-
@dataclasses.dataclass
486-
class MacroInstruction(SuperOrMacroInstruction):
487-
"""A macro instruction."""
488-
489475
macro: parser.Macro
490476
parts: list[Component | parser.CacheEffect]
491477
predicted: bool = False
@@ -505,7 +491,7 @@ class OverriddenInstructionPlaceHolder:
505491
name: str
506492

507493

508-
AnyInstruction = Instruction | SuperInstruction | MacroInstruction
494+
AnyInstruction = Instruction | MacroInstruction
509495
INSTR_FMT_PREFIX = "INSTR_FMT_"
510496

511497

@@ -538,12 +524,9 @@ def error(self, msg: str, node: parser.Node) -> None:
538524
self.errors += 1
539525

540526
everything: list[
541-
parser.InstDef | parser.Super | parser.Macro |
542-
parser.Pseudo | OverriddenInstructionPlaceHolder
527+
parser.InstDef | parser.Macro | parser.Pseudo | OverriddenInstructionPlaceHolder
543528
]
544529
instrs: dict[str, Instruction] # Includes ops
545-
supers: dict[str, parser.Super]
546-
super_instrs: dict[str, SuperInstruction]
547530
macros: dict[str, parser.Macro]
548531
macro_instrs: dict[str, MacroInstruction]
549532
families: dict[str, parser.Family]
@@ -558,7 +541,6 @@ def parse(self) -> None:
558541

559542
self.everything = []
560543
self.instrs = {}
561-
self.supers = {}
562544
self.macros = {}
563545
self.families = {}
564546
self.pseudos = {}
@@ -571,7 +553,7 @@ def parse(self) -> None:
571553
files = " + ".join(self.input_filenames)
572554
print(
573555
f"Read {len(self.instrs)} instructions/ops, "
574-
f"{len(self.supers)} supers, {len(self.macros)} macros, "
556+
f"{len(self.macros)} macros, {len(self.pseudos)} pseudos, "
575557
f"and {len(self.families)} families from {files}",
576558
file=sys.stderr,
577559
)
@@ -605,7 +587,7 @@ def parse_file(self, filename: str, instrs_idx: dict[str, int]) -> None:
605587

606588
# Parse from start
607589
psr.setpos(start)
608-
thing: parser.InstDef | parser.Super | parser.Macro | parser.Family | None
590+
thing: parser.InstDef | parser.Macro | parser.Family | None
609591
thing_first_token = psr.peek()
610592
while thing := psr.definition():
611593
match thing:
@@ -627,9 +609,6 @@ def parse_file(self, filename: str, instrs_idx: dict[str, int]) -> None:
627609
self.instrs[name] = Instruction(thing)
628610
instrs_idx[name] = len(self.everything)
629611
self.everything.append(thing)
630-
case parser.Super(name):
631-
self.supers[name] = thing
632-
self.everything.append(thing)
633612
case parser.Macro(name):
634613
self.macros[name] = thing
635614
self.everything.append(thing)
@@ -648,15 +627,15 @@ def analyze(self) -> None:
648627
649628
Raises SystemExit if there is an error.
650629
"""
651-
self.analyze_supers_and_macros_and_pseudos()
630+
self.analyze_macros_and_pseudos()
652631
self.find_predictions()
653632
self.map_families()
654633
self.check_families()
655634

656635
def find_predictions(self) -> None:
657636
"""Find the instructions that need PREDICTED() labels."""
658637
for instr in self.instrs.values():
659-
targets = set()
638+
targets: set[str] = set()
660639
for line in instr.block_text:
661640
if m := re.match(RE_PREDICTED, line):
662641
targets.add(m.group(1))
@@ -760,33 +739,15 @@ def effect_counts(self, name: str) -> tuple[int, int, int]:
760739
assert False, f"Unknown instruction {name!r}"
761740
return cache, input, output
762741

763-
def analyze_supers_and_macros_and_pseudos(self) -> None:
764-
"""Analyze each super-, macro- and pseudo- instruction."""
765-
self.super_instrs = {}
742+
def analyze_macros_and_pseudos(self) -> None:
743+
"""Analyze each super- and macro instruction."""
766744
self.macro_instrs = {}
767745
self.pseudo_instrs = {}
768-
for name, super in self.supers.items():
769-
self.super_instrs[name] = self.analyze_super(super)
770746
for name, macro in self.macros.items():
771747
self.macro_instrs[name] = self.analyze_macro(macro)
772748
for name, pseudo in self.pseudos.items():
773749
self.pseudo_instrs[name] = self.analyze_pseudo(pseudo)
774750

775-
def analyze_super(self, super: parser.Super) -> SuperInstruction:
776-
components = self.check_super_components(super)
777-
stack, initial_sp = self.stack_analysis(components)
778-
sp = initial_sp
779-
parts: list[Component] = []
780-
format = ""
781-
for instr in components:
782-
part, sp = self.analyze_instruction(instr, stack, sp)
783-
parts.append(part)
784-
format += instr.instr_fmt
785-
final_sp = sp
786-
return SuperInstruction(
787-
super.name, stack, initial_sp, final_sp, format, super, parts
788-
)
789-
790751
def analyze_macro(self, macro: parser.Macro) -> MacroInstruction:
791752
components = self.check_macro_components(macro)
792753
stack, initial_sp = self.stack_analysis(components)
@@ -836,15 +797,6 @@ def analyze_instruction(
836797
sp += 1
837798
return Component(instr, input_mapping, output_mapping), sp
838799

839-
def check_super_components(self, super: parser.Super) -> list[Instruction]:
840-
components: list[Instruction] = []
841-
for op in super.ops:
842-
if op.name not in self.instrs:
843-
self.error(f"Unknown instruction {op.name!r}", super)
844-
else:
845-
components.append(self.instrs[op.name])
846-
return components
847-
848800
def check_macro_components(
849801
self, macro: parser.Macro
850802
) -> list[InstructionOrCacheEffect]:
@@ -864,7 +816,7 @@ def check_macro_components(
864816
def stack_analysis(
865817
self, components: typing.Iterable[InstructionOrCacheEffect]
866818
) -> tuple[list[StackEffect], int]:
867-
"""Analyze a super-instruction or macro.
819+
"""Analyze a macro.
868820
869821
Ignore cache effects.
870822
@@ -880,8 +832,8 @@ def stack_analysis(
880832
# TODO: Eventually this will be needed, at least for macros.
881833
self.error(
882834
f"Instruction {instr.name!r} has variable-sized stack effect, "
883-
"which are not supported in super- or macro instructions",
884-
instr.inst, # TODO: Pass name+location of super/macro
835+
"which are not supported in macro instructions",
836+
instr.inst, # TODO: Pass name+location of macro
885837
)
886838
current -= len(instr.input_effects)
887839
lowest = min(lowest, current)
@@ -901,7 +853,7 @@ def stack_analysis(
901853
return stack, -lowest
902854

903855
def get_stack_effect_info(
904-
self, thing: parser.InstDef | parser.Super | parser.Macro | parser.Pseudo
856+
self, thing: parser.InstDef | parser.Macro | parser.Pseudo
905857
) -> tuple[AnyInstruction | None, str, str]:
906858
def effect_str(effects: list[StackEffect]) -> str:
907859
if getattr(thing, "kind", None) == "legacy":
@@ -922,15 +874,6 @@ def effect_str(effects: list[StackEffect]) -> str:
922874
instr = None
923875
popped = ""
924876
pushed = ""
925-
case parser.Super():
926-
instr = self.super_instrs[thing.name]
927-
# TODO: Same as for Macro below, if needed.
928-
popped = "+".join(
929-
effect_str(comp.instr.input_effects) for comp in instr.parts
930-
)
931-
pushed = "+".join(
932-
effect_str(comp.instr.output_effects) for comp in instr.parts
933-
)
934877
case parser.Macro():
935878
instr = self.macro_instrs[thing.name]
936879
parts = [comp for comp in instr.parts if isinstance(comp, Component)]
@@ -1032,8 +975,6 @@ def write_metadata(self) -> None:
1032975
continue
1033976
case parser.InstDef():
1034977
format = self.instrs[thing.name].instr_fmt
1035-
case parser.Super():
1036-
format = self.super_instrs[thing.name].instr_fmt
1037978
case parser.Macro():
1038979
format = self.macro_instrs[thing.name].instr_fmt
1039980
case parser.Pseudo():
@@ -1092,8 +1033,6 @@ def write_metadata(self) -> None:
10921033
case parser.InstDef():
10931034
if thing.kind != "op":
10941035
self.write_metadata_for_inst(self.instrs[thing.name])
1095-
case parser.Super():
1096-
self.write_metadata_for_super(self.super_instrs[thing.name])
10971036
case parser.Macro():
10981037
self.write_metadata_for_macro(self.macro_instrs[thing.name])
10991038
case parser.Pseudo():
@@ -1118,12 +1057,6 @@ def write_metadata_for_inst(self, instr: Instruction) -> None:
11181057
f" [{instr.name}] = {{ true, {INSTR_FMT_PREFIX}{instr.instr_fmt} }},"
11191058
)
11201059

1121-
def write_metadata_for_super(self, sup: SuperInstruction) -> None:
1122-
"""Write metadata for a super-instruction."""
1123-
self.out.emit(
1124-
f" [{sup.name}] = {{ true, {INSTR_FMT_PREFIX}{sup.instr_fmt} }},"
1125-
)
1126-
11271060
def write_metadata_for_macro(self, mac: MacroInstruction) -> None:
11281061
"""Write metadata for a macro-instruction."""
11291062
self.out.emit(
@@ -1149,7 +1082,6 @@ def write_instructions(self) -> None:
11491082

11501083
# Write and count instructions of all kinds
11511084
n_instrs = 0
1152-
n_supers = 0
11531085
n_macros = 0
11541086
n_pseudos = 0
11551087
for thing in self.everything:
@@ -1160,9 +1092,6 @@ def write_instructions(self) -> None:
11601092
if thing.kind != "op":
11611093
n_instrs += 1
11621094
self.write_instr(self.instrs[thing.name])
1163-
case parser.Super():
1164-
n_supers += 1
1165-
self.write_super(self.super_instrs[thing.name])
11661095
case parser.Macro():
11671096
n_macros += 1
11681097
self.write_macro(self.macro_instrs[thing.name])
@@ -1172,8 +1101,8 @@ def write_instructions(self) -> None:
11721101
typing.assert_never(thing)
11731102

11741103
print(
1175-
f"Wrote {n_instrs} instructions, {n_supers} supers, {n_macros}"
1176-
f" macros and {n_pseudos} pseudos to {self.output_filename}",
1104+
f"Wrote {n_instrs} instructions, {n_macros} macros, "
1105+
f"and {n_pseudos} pseudos to {self.output_filename}",
11771106
file=sys.stderr,
11781107
)
11791108

@@ -1197,23 +1126,10 @@ def write_instr(self, instr: Instruction) -> None:
11971126
self.out.emit("CHECK_EVAL_BREAKER();")
11981127
self.out.emit(f"DISPATCH();")
11991128

1200-
def write_super(self, sup: SuperInstruction) -> None:
1201-
"""Write code for a super-instruction."""
1202-
with self.wrap_super_or_macro(sup):
1203-
first = True
1204-
for comp in sup.parts:
1205-
if not first:
1206-
self.out.emit("oparg = (next_instr++)->op.arg;")
1207-
# self.out.emit("next_instr += OPSIZE(opcode) - 1;")
1208-
first = False
1209-
comp.write_body(self.out, 0)
1210-
if comp.instr.cache_offset:
1211-
self.out.emit(f"next_instr += {comp.instr.cache_offset};")
1212-
12131129
def write_macro(self, mac: MacroInstruction) -> None:
12141130
"""Write code for a macro instruction."""
12151131
last_instr: Instruction | None = None
1216-
with self.wrap_super_or_macro(mac):
1132+
with self.wrap_macro(mac):
12171133
cache_adjust = 0
12181134
for part in mac.parts:
12191135
match part:
@@ -1239,30 +1155,29 @@ def write_macro(self, mac: MacroInstruction) -> None:
12391155
)
12401156

12411157
@contextlib.contextmanager
1242-
def wrap_super_or_macro(self, up: SuperOrMacroInstruction):
1243-
"""Shared boilerplate for super- and macro instructions."""
1158+
def wrap_macro(self, mac: MacroInstruction):
1159+
"""Boilerplate for macro instructions."""
12441160
# TODO: Somewhere (where?) make it so that if one instruction
12451161
# has an output that is input to another, and the variable names
12461162
# and types match and don't conflict with other instructions,
12471163
# that variable is declared with the right name and type in the
12481164
# outer block, rather than trusting the compiler to optimize it.
12491165
self.out.emit("")
1250-
with self.out.block(f"TARGET({up.name})"):
1251-
match up:
1252-
case MacroInstruction(predicted=True, name=name):
1253-
self.out.emit(f"PREDICTED({name});")
1254-
for i, var in reversed(list(enumerate(up.stack))):
1166+
with self.out.block(f"TARGET({mac.name})"):
1167+
if mac.predicted:
1168+
self.out.emit(f"PREDICTED({mac.name});")
1169+
for i, var in reversed(list(enumerate(mac.stack))):
12551170
src = None
1256-
if i < up.initial_sp:
1257-
src = StackEffect(f"stack_pointer[-{up.initial_sp - i}]", "")
1171+
if i < mac.initial_sp:
1172+
src = StackEffect(f"stack_pointer[-{mac.initial_sp - i}]", "")
12581173
self.out.declare(var, src)
12591174

12601175
yield
12611176

1262-
# TODO: Use slices of up.stack instead of numeric values
1263-
self.out.stack_adjust(up.final_sp - up.initial_sp, [], [])
1177+
# TODO: Use slices of mac.stack instead of numeric values
1178+
self.out.stack_adjust(mac.final_sp - mac.initial_sp, [], [])
12641179

1265-
for i, var in enumerate(reversed(up.stack[: up.final_sp]), 1):
1180+
for i, var in enumerate(reversed(mac.stack[: mac.final_sp]), 1):
12661181
dst = StackEffect(f"stack_pointer[-{i}]", "")
12671182
self.out.assign(dst, var)
12681183

0 commit comments

Comments
 (0)