Skip to content

Commit 862af99

Browse files
authored
[mypyc] Fix non-deterministic ordering of spilled registers (#21632)
Sort ops by their order in the basic blocks.
1 parent 9d5e32c commit 862af99

1 file changed

Lines changed: 20 additions & 1 deletion

File tree

mypyc/transform/spill.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
from __future__ import annotations
44

5+
from collections.abc import Collection
6+
from typing import cast
7+
58
from mypyc.analysis.dataflow import AnalysisResult, analyze_live_regs, get_cfg
69
from mypyc.common import TEMP_ATTR_NAME
710
from mypyc.ir.class_ir import ClassIR
@@ -13,6 +16,7 @@
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+
3451
def 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

Comments
 (0)