@@ -229,7 +229,6 @@ class Instruction:
229229
230230 # Parts of the underlying instruction definition
231231 inst : parser .InstDef
232- register : bool
233232 kind : typing .Literal ["inst" , "op" , "legacy" ] # Legacy means no (input -- output)
234233 name : str
235234 block : parser .Block
@@ -246,17 +245,12 @@ class Instruction:
246245 unmoved_names : frozenset [str ]
247246 instr_fmt : str
248247
249- # Parallel to input_effects; set later
250- input_registers : list [str ] = dataclasses .field (repr = False )
251- output_registers : list [str ] = dataclasses .field (repr = False )
252-
253248 # Set later
254249 family : parser .Family | None = None
255250 predicted : bool = False
256251
257252 def __init__ (self , inst : parser .InstDef ):
258253 self .inst = inst
259- self .register = inst .register
260254 self .kind = inst .kind
261255 self .name = inst .name
262256 self .block = inst .block
@@ -278,36 +272,17 @@ def __init__(self, inst: parser.InstDef):
278272 else :
279273 break
280274 self .unmoved_names = frozenset (unmoved_names )
281- if self .register :
282- num_regs = len (self .input_effects ) + len (self .output_effects )
283- num_dummies = (num_regs // 2 ) * 2 + 1 - num_regs
284- fmt = "I" + "B" * num_regs + "X" * num_dummies
275+ if variable_used (inst , "oparg" ):
276+ fmt = "IB"
285277 else :
286- if variable_used (inst , "oparg" ):
287- fmt = "IB"
288- else :
289- fmt = "IX"
278+ fmt = "IX"
290279 cache = "C"
291280 for ce in self .cache_effects :
292281 for _ in range (ce .size ):
293282 fmt += cache
294283 cache = "0"
295284 self .instr_fmt = fmt
296285
297- def analyze_registers (self , a : "Analyzer" ) -> None :
298- regs = iter (("REG(oparg1)" , "REG(oparg2)" , "REG(oparg3)" ))
299- try :
300- self .input_registers = [
301- next (regs ) for ieff in self .input_effects if ieff .name != UNUSED
302- ]
303- self .output_registers = [
304- next (regs ) for oeff in self .output_effects if oeff .name != UNUSED
305- ]
306- except StopIteration : # Running out of registers
307- a .error (
308- f"Instruction { self .name } has too many register effects" , node = self .inst
309- )
310-
311286 def write (self , out : Formatter ) -> None :
312287 """Write one instruction, sans prologue and epilogue."""
313288 # Write a static assertion that a family's cache size is correct
@@ -319,25 +294,19 @@ def write(self, out: Formatter) -> None:
319294 f'{ self .cache_offset } , "incorrect cache size");'
320295 )
321296
322- if not self .register :
323- # Write input stack effect variable declarations and initializations
324- ieffects = list (reversed (self .input_effects ))
325- for i , ieffect in enumerate (ieffects ):
326- isize = string_effect_size (
327- list_effect_size ([ieff for ieff in ieffects [: i + 1 ]])
328- )
329- if ieffect .size :
330- src = StackEffect (f"(stack_pointer - { maybe_parenthesize (isize )} )" , "PyObject **" )
331- elif ieffect .cond :
332- src = StackEffect (f"({ ieffect .cond } ) ? stack_pointer[-{ maybe_parenthesize (isize )} ] : NULL" , "" )
333- else :
334- src = StackEffect (f"stack_pointer[-{ maybe_parenthesize (isize )} ]" , "" )
335- out .declare (ieffect , src )
336- else :
337- # Write input register variable declarations and initializations
338- for ieffect , reg in zip (self .input_effects , self .input_registers ):
339- src = StackEffect (reg , "" )
340- out .declare (ieffect , src )
297+ # Write input stack effect variable declarations and initializations
298+ ieffects = list (reversed (self .input_effects ))
299+ for i , ieffect in enumerate (ieffects ):
300+ isize = string_effect_size (
301+ list_effect_size ([ieff for ieff in ieffects [: i + 1 ]])
302+ )
303+ if ieffect .size :
304+ src = StackEffect (f"(stack_pointer - { maybe_parenthesize (isize )} )" , "PyObject **" )
305+ elif ieffect .cond :
306+ src = StackEffect (f"({ ieffect .cond } ) ? stack_pointer[-{ maybe_parenthesize (isize )} ] : NULL" , "" )
307+ else :
308+ src = StackEffect (f"stack_pointer[-{ maybe_parenthesize (isize )} ]" , "" )
309+ out .declare (ieffect , src )
341310
342311 # Write output stack effect variable declarations
343312 isize = string_effect_size (list_effect_size (self .input_effects ))
@@ -367,32 +336,26 @@ def write(self, out: Formatter) -> None:
367336 if self .always_exits :
368337 return
369338
370- if not self .register :
371- # Write net stack growth/shrinkage
372- out .stack_adjust (
373- 0 ,
374- [ieff for ieff in self .input_effects ],
375- [oeff for oeff in self .output_effects ],
376- )
339+ # Write net stack growth/shrinkage
340+ out .stack_adjust (
341+ 0 ,
342+ [ieff for ieff in self .input_effects ],
343+ [oeff for oeff in self .output_effects ],
344+ )
377345
378- # Write output stack effect assignments
379- oeffects = list (reversed (self .output_effects ))
380- for i , oeffect in enumerate (oeffects ):
381- if oeffect .name in self .unmoved_names :
382- continue
383- osize = string_effect_size (
384- list_effect_size ([oeff for oeff in oeffects [: i + 1 ]])
385- )
386- if oeffect .size :
387- dst = StackEffect (f"stack_pointer - { maybe_parenthesize (osize )} " , "PyObject **" )
388- else :
389- dst = StackEffect (f"stack_pointer[-{ maybe_parenthesize (osize )} ]" , "" )
390- out .assign (dst , oeffect )
391- else :
392- # Write output register assignments
393- for oeffect , reg in zip (self .output_effects , self .output_registers ):
394- dst = StackEffect (reg , "" )
395- out .assign (dst , oeffect )
346+ # Write output stack effect assignments
347+ oeffects = list (reversed (self .output_effects ))
348+ for i , oeffect in enumerate (oeffects ):
349+ if oeffect .name in self .unmoved_names :
350+ continue
351+ osize = string_effect_size (
352+ list_effect_size ([oeff for oeff in oeffects [: i + 1 ]])
353+ )
354+ if oeffect .size :
355+ dst = StackEffect (f"stack_pointer - { maybe_parenthesize (osize )} " , "PyObject **" )
356+ else :
357+ dst = StackEffect (f"stack_pointer[-{ maybe_parenthesize (osize )} ]" , "" )
358+ out .assign (dst , oeffect )
396359
397360 # Write cache effect
398361 if self .cache_offset :
@@ -438,41 +401,38 @@ def write_body(self, out: Formatter, dedent: int, cache_adjust: int = 0) -> None
438401 # ERROR_IF() must pop the inputs from the stack.
439402 # The code block is responsible for DECREF()ing them.
440403 # NOTE: If the label doesn't exist, just add it to ceval.c.
441- if not self .register :
442- # Don't pop common input/output effects at the bottom!
443- # These aren't DECREF'ed so they can stay.
444- ieffs = list (self .input_effects )
445- oeffs = list (self .output_effects )
446- while ieffs and oeffs and ieffs [0 ] == oeffs [0 ]:
447- ieffs .pop (0 )
448- oeffs .pop (0 )
449- ninputs , symbolic = list_effect_size (ieffs )
450- if ninputs :
451- label = f"pop_{ ninputs } _{ label } "
452- else :
453- symbolic = ""
404+
405+ # Don't pop common input/output effects at the bottom!
406+ # These aren't DECREF'ed so they can stay.
407+ ieffs = list (self .input_effects )
408+ oeffs = list (self .output_effects )
409+ while ieffs and oeffs and ieffs [0 ] == oeffs [0 ]:
410+ ieffs .pop (0 )
411+ oeffs .pop (0 )
412+ ninputs , symbolic = list_effect_size (ieffs )
413+ if ninputs :
414+ label = f"pop_{ ninputs } _{ label } "
454415 if symbolic :
455416 out .write_raw (
456417 f"{ space } if ({ cond } ) {{ STACK_SHRINK({ symbolic } ); goto { label } ; }}\n "
457418 )
458419 else :
459420 out .write_raw (f"{ space } if ({ cond } ) goto { label } ;\n " )
460421 elif m := re .match (r"(\s*)DECREF_INPUTS\(\);\s*(?://.*)?$" , line ):
461- if not self .register :
462- out .reset_lineno ()
463- space = extra + m .group (1 )
464- for ieff in self .input_effects :
465- if ieff .name in names_to_skip :
466- continue
467- if ieff .size :
468- out .write_raw (
469- f"{ space } for (int _i = { ieff .size } ; --_i >= 0;) {{\n "
470- )
471- out .write_raw (f"{ space } Py_DECREF({ ieff .name } [_i]);\n " )
472- out .write_raw (f"{ space } }}\n " )
473- else :
474- decref = "XDECREF" if ieff .cond else "DECREF"
475- out .write_raw (f"{ space } Py_{ decref } ({ ieff .name } );\n " )
422+ out .reset_lineno ()
423+ space = extra + m .group (1 )
424+ for ieff in self .input_effects :
425+ if ieff .name in names_to_skip :
426+ continue
427+ if ieff .size :
428+ out .write_raw (
429+ f"{ space } for (int _i = { ieff .size } ; --_i >= 0;) {{\n "
430+ )
431+ out .write_raw (f"{ space } Py_DECREF({ ieff .name } [_i]);\n " )
432+ out .write_raw (f"{ space } }}\n " )
433+ else :
434+ decref = "XDECREF" if ieff .cond else "DECREF"
435+ out .write_raw (f"{ space } Py_{ decref } ({ ieff .name } );\n " )
476436 else :
477437 out .write_raw (extra + line )
478438 out .reset_lineno ()
@@ -672,7 +632,6 @@ def analyze(self) -> None:
672632 Raises SystemExit if there is an error.
673633 """
674634 self .find_predictions ()
675- self .analyze_register_instrs ()
676635 self .analyze_supers_and_macros ()
677636 self .map_families ()
678637 self .check_families ()
@@ -782,11 +741,6 @@ def effect_counts(self, name: str) -> tuple[int, int, int]:
782741 assert False , f"Unknown instruction { name !r} "
783742 return cache , input , output
784743
785- def analyze_register_instrs (self ) -> None :
786- for instr in self .instrs .values ():
787- if instr .register :
788- instr .analyze_registers (self )
789-
790744 def analyze_supers_and_macros (self ) -> None :
791745 """Analyze each super- and macro instruction."""
792746 self .super_instrs = {}
@@ -816,7 +770,7 @@ def analyze_macro(self, macro: parser.Macro) -> MacroInstruction:
816770 stack , initial_sp = self .stack_analysis (components )
817771 sp = initial_sp
818772 parts : list [Component | parser .CacheEffect ] = []
819- format = "IB" # Macros don't support register instructions yet
773+ format = "IB"
820774 cache = "C"
821775 for component in components :
822776 match component :
@@ -1074,15 +1028,6 @@ def write_metadata(self) -> None:
10741028 def write_metadata_for_inst (self , instr : Instruction ) -> None :
10751029 """Write metadata for a single instruction."""
10761030 dir_op1 = dir_op2 = dir_op3 = "DIR_NONE"
1077- if instr .kind == "legacy" :
1078- assert not instr .register
1079- else :
1080- if instr .register :
1081- directions : list [str ] = []
1082- directions .extend ("DIR_READ" for _ in instr .input_effects )
1083- directions .extend ("DIR_WRITE" for _ in instr .output_effects )
1084- directions .extend ("DIR_NONE" for _ in range (3 ))
1085- dir_op1 , dir_op2 , dir_op3 = directions [:3 ]
10861031 self .out .emit (
10871032 f" [{ instr .name } ] = {{ { dir_op1 } , { dir_op2 } , { dir_op3 } , true, { INSTR_FMT_PREFIX } { instr .instr_fmt } }},"
10881033 )
0 commit comments