@@ -74,10 +74,16 @@ def block(self, head: str):
74
74
self .emit ("}" )
75
75
76
76
77
- # This is not a data class
78
- class Instruction ( parser . InstDef ) :
77
+ @ dataclasses . dataclass
78
+ class Instruction :
79
79
"""An instruction with additional data and code."""
80
80
81
+ # Parts of the underlying instruction definition
82
+ inst : parser .InstDef
83
+ kind : typing .Literal ["inst" , "op" ]
84
+ name : str
85
+ block : parser .Block
86
+
81
87
# Computed by constructor
82
88
always_exits : bool
83
89
cache_offset : int
@@ -90,17 +96,19 @@ class Instruction(parser.InstDef):
90
96
predicted : bool = False
91
97
92
98
def __init__ (self , inst : parser .InstDef ):
93
- super ().__init__ (inst .kind , inst .name , inst .inputs , inst .outputs , inst .block )
94
- self .context = inst .context
99
+ self .inst = inst
100
+ self .kind = inst .kind
101
+ self .name = inst .name
102
+ self .block = inst .block
95
103
self .always_exits = always_exits (self .block )
96
104
self .cache_effects = [
97
- effect for effect in self .inputs if isinstance (effect , parser .CacheEffect )
105
+ effect for effect in inst .inputs if isinstance (effect , parser .CacheEffect )
98
106
]
99
107
self .cache_offset = sum (c .size for c in self .cache_effects )
100
108
self .input_effects = [
101
- effect for effect in self .inputs if isinstance (effect , parser .StackEffect )
109
+ effect for effect in inst .inputs if isinstance (effect , parser .StackEffect )
102
110
]
103
- self .output_effects = self .outputs # For consistency/completeness
111
+ self .output_effects = inst .outputs # For consistency/completeness
104
112
105
113
def write (self , out : Formatter ) -> None :
106
114
"""Write one instruction, sans prologue and epilogue."""
@@ -235,35 +243,32 @@ def write_body(self, out: Formatter, cache_adjust: int) -> None:
235
243
236
244
237
245
# TODO: Use a common base class for {Super,Macro}Instruction
246
+
238
247
@dataclasses .dataclass
239
- class SuperInstruction :
240
- """A super-instruction ."""
248
+ class SuperOrMacroInstruction :
249
+ """Common fields for super- and macro instructions ."""
241
250
242
- super : parser . Super
251
+ name : str
243
252
stack : list [str ]
244
253
initial_sp : int
245
254
final_sp : int
246
- parts : list [Component ]
247
255
248
- @property
249
- def name (self ) -> str :
250
- return self .super .name
256
+
257
+ @dataclasses .dataclass
258
+ class SuperInstruction (SuperOrMacroInstruction ):
259
+ """A super-instruction."""
260
+
261
+ super : parser .Super
262
+ parts : list [Component ]
251
263
252
264
253
265
@dataclasses .dataclass
254
- class MacroInstruction :
266
+ class MacroInstruction ( SuperOrMacroInstruction ) :
255
267
"""A macro instruction."""
256
268
257
269
macro : parser .Macro
258
- stack : list [str ]
259
- initial_sp : int
260
- final_sp : int
261
270
parts : list [Component | parser .CacheEffect ]
262
271
263
- @property
264
- def name (self ) -> str :
265
- return self .macro .name
266
-
267
272
268
273
class Analyzer :
269
274
"""Parse input, analyze it, and write to output."""
@@ -369,7 +374,7 @@ def find_predictions(self) -> None:
369
374
else :
370
375
self .error (
371
376
f"Unknown instruction { target !r} predicted in { instr .name !r} " ,
372
- instr , # TODO: Use better location
377
+ instr . inst , # TODO: Use better location
373
378
)
374
379
375
380
def map_families (self ) -> None :
@@ -453,7 +458,7 @@ def analyze_super(self, super: parser.Super) -> SuperInstruction:
453
458
case _:
454
459
typing .assert_never (component )
455
460
final_sp = sp
456
- return SuperInstruction (super , stack , initial_sp , final_sp , parts )
461
+ return SuperInstruction (super . name , stack , initial_sp , final_sp , super , parts )
457
462
458
463
def analyze_macro (self , macro : parser .Macro ) -> MacroInstruction :
459
464
components = self .check_macro_components (macro )
@@ -479,12 +484,10 @@ def analyze_macro(self, macro: parser.Macro) -> MacroInstruction:
479
484
case _:
480
485
typing .assert_never (component )
481
486
final_sp = sp
482
- return MacroInstruction (macro , stack , initial_sp , final_sp , parts )
487
+ return MacroInstruction (macro . name , stack , initial_sp , final_sp , macro , parts )
483
488
484
489
def check_super_components (self , super : parser .Super ) -> list [Instruction ]:
485
490
components : list [Instruction ] = []
486
- if not super .ops :
487
- self .error (f"Super-instruction has no operands" , super )
488
491
for op in super .ops :
489
492
if op .name not in self .instrs :
490
493
self .error (f"Unknown instruction { op .name !r} " , super )
@@ -496,8 +499,6 @@ def check_macro_components(
496
499
self , macro : parser .Macro
497
500
) -> list [InstructionOrCacheEffect ]:
498
501
components : list [InstructionOrCacheEffect ] = []
499
- if not macro .uops :
500
- self .error (f"Macro instruction has no operands" , macro )
501
502
for uop in macro .uops :
502
503
match uop :
503
504
case parser .OpName (name ):
0 commit comments