22
33from __future__ import annotations
44
5+ from collections .abc import Collection
6+ from typing import cast
7+
58from mypyc .analysis .dataflow import AnalysisResult , analyze_live_regs , get_cfg
69from mypyc .common import TEMP_ATTR_NAME
710from mypyc .ir .class_ir import ClassIR
1316 GetAttr ,
1417 IncRef ,
1518 LoadErrorValue ,
19+ Op ,
1620 Register ,
1721 SetAttr ,
1822 Value ,
@@ -31,6 +35,19 @@ def insert_spills(ir: FuncIR, env: ClassIR) -> None:
3135 ir .blocks = spill_regs (ir .blocks , env , entry_live , live , ir .arg_regs [0 ])
3236
3337
38+ def sort_values (values : Collection [Op ], blocks : list [BasicBlock ]) -> list [Op ]:
39+ if len (values ) > 1 :
40+ order = {}
41+ i = 0
42+ for block in blocks :
43+ for op in block .ops :
44+ order [op ] = i
45+ i += 1
46+ return sorted (values , key = lambda v : order [v ])
47+ else :
48+ return list (values )
49+
50+
3451def spill_regs (
3552 blocks : list [BasicBlock ],
3653 env : ClassIR ,
@@ -48,7 +65,9 @@ def spill_regs(
4865 env_reg = self_reg
4966
5067 spill_locs = {}
51- for i , val in enumerate (to_spill ):
68+ # Sort values to make the order deterministic. All the spilled values are
69+ # known to be Op instances, so the cast is safe.
70+ for i , val in enumerate (sort_values (cast (set [Op ], to_spill ), blocks )):
5271 name = f"{ TEMP_ATTR_NAME } 2_{ i } "
5372 env .attributes [name ] = val .type
5473 if val .type .error_overlap :
0 commit comments