@@ -229,7 +229,6 @@ class Instruction:
229
229
230
230
# Parts of the underlying instruction definition
231
231
inst : parser .InstDef
232
- register : bool
233
232
kind : typing .Literal ["inst" , "op" , "legacy" ] # Legacy means no (input -- output)
234
233
name : str
235
234
block : parser .Block
@@ -246,17 +245,12 @@ class Instruction:
246
245
unmoved_names : frozenset [str ]
247
246
instr_fmt : str
248
247
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
-
253
248
# Set later
254
249
family : parser .Family | None = None
255
250
predicted : bool = False
256
251
257
252
def __init__ (self , inst : parser .InstDef ):
258
253
self .inst = inst
259
- self .register = inst .register
260
254
self .kind = inst .kind
261
255
self .name = inst .name
262
256
self .block = inst .block
@@ -278,36 +272,17 @@ def __init__(self, inst: parser.InstDef):
278
272
else :
279
273
break
280
274
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"
285
277
else :
286
- if variable_used (inst , "oparg" ):
287
- fmt = "IB"
288
- else :
289
- fmt = "IX"
278
+ fmt = "IX"
290
279
cache = "C"
291
280
for ce in self .cache_effects :
292
281
for _ in range (ce .size ):
293
282
fmt += cache
294
283
cache = "0"
295
284
self .instr_fmt = fmt
296
285
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
-
311
286
def write (self , out : Formatter ) -> None :
312
287
"""Write one instruction, sans prologue and epilogue."""
313
288
# Write a static assertion that a family's cache size is correct
@@ -319,25 +294,19 @@ def write(self, out: Formatter) -> None:
319
294
f'{ self .cache_offset } , "incorrect cache size");'
320
295
)
321
296
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 )
341
310
342
311
# Write output stack effect variable declarations
343
312
isize = string_effect_size (list_effect_size (self .input_effects ))
@@ -367,32 +336,26 @@ def write(self, out: Formatter) -> None:
367
336
if self .always_exits :
368
337
return
369
338
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
+ )
377
345
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 )
396
359
397
360
# Write cache effect
398
361
if self .cache_offset :
@@ -438,41 +401,38 @@ def write_body(self, out: Formatter, dedent: int, cache_adjust: int = 0) -> None
438
401
# ERROR_IF() must pop the inputs from the stack.
439
402
# The code block is responsible for DECREF()ing them.
440
403
# 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 } "
454
415
if symbolic :
455
416
out .write_raw (
456
417
f"{ space } if ({ cond } ) {{ STACK_SHRINK({ symbolic } ); goto { label } ; }}\n "
457
418
)
458
419
else :
459
420
out .write_raw (f"{ space } if ({ cond } ) goto { label } ;\n " )
460
421
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 " )
476
436
else :
477
437
out .write_raw (extra + line )
478
438
out .reset_lineno ()
@@ -672,7 +632,6 @@ def analyze(self) -> None:
672
632
Raises SystemExit if there is an error.
673
633
"""
674
634
self .find_predictions ()
675
- self .analyze_register_instrs ()
676
635
self .analyze_supers_and_macros ()
677
636
self .map_families ()
678
637
self .check_families ()
@@ -782,11 +741,6 @@ def effect_counts(self, name: str) -> tuple[int, int, int]:
782
741
assert False , f"Unknown instruction { name !r} "
783
742
return cache , input , output
784
743
785
- def analyze_register_instrs (self ) -> None :
786
- for instr in self .instrs .values ():
787
- if instr .register :
788
- instr .analyze_registers (self )
789
-
790
744
def analyze_supers_and_macros (self ) -> None :
791
745
"""Analyze each super- and macro instruction."""
792
746
self .super_instrs = {}
@@ -816,7 +770,7 @@ def analyze_macro(self, macro: parser.Macro) -> MacroInstruction:
816
770
stack , initial_sp = self .stack_analysis (components )
817
771
sp = initial_sp
818
772
parts : list [Component | parser .CacheEffect ] = []
819
- format = "IB" # Macros don't support register instructions yet
773
+ format = "IB"
820
774
cache = "C"
821
775
for component in components :
822
776
match component :
@@ -1074,15 +1028,6 @@ def write_metadata(self) -> None:
1074
1028
def write_metadata_for_inst (self , instr : Instruction ) -> None :
1075
1029
"""Write metadata for a single instruction."""
1076
1030
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 ]
1086
1031
self .out .emit (
1087
1032
f" [{ instr .name } ] = {{ { dir_op1 } , { dir_op2 } , { dir_op3 } , true, { INSTR_FMT_PREFIX } { instr .instr_fmt } }},"
1088
1033
)
0 commit comments