Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion mypyc/transform/spill.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

from __future__ import annotations

from collections.abc import Collection
from typing import cast

from mypyc.analysis.dataflow import AnalysisResult, analyze_live_regs, get_cfg
from mypyc.common import TEMP_ATTR_NAME
from mypyc.ir.class_ir import ClassIR
Expand All @@ -13,6 +16,7 @@
GetAttr,
IncRef,
LoadErrorValue,
Op,
Register,
SetAttr,
Value,
Expand All @@ -31,6 +35,19 @@ def insert_spills(ir: FuncIR, env: ClassIR) -> None:
ir.blocks = spill_regs(ir.blocks, env, entry_live, live, ir.arg_regs[0])


def sort_values(values: Collection[Op], blocks: list[BasicBlock]) -> list[Op]:
if len(values) > 1:
order = {}
i = 0
for block in blocks:
for op in block.ops:
order[op] = i
i += 1
return sorted(values, key=lambda v: order[v])
else:
return list(values)


def spill_regs(
blocks: list[BasicBlock],
env: ClassIR,
Expand All @@ -48,7 +65,9 @@ def spill_regs(
env_reg = self_reg

spill_locs = {}
for i, val in enumerate(to_spill):
# Sort values to make the order deterministic. All the spilled values are
# known to be Op instances, so the cast is safe.
for i, val in enumerate(sort_values(cast(set[Op], to_spill), blocks)):
name = f"{TEMP_ATTR_NAME}2_{i}"
env.attributes[name] = val.type
if val.type.error_overlap:
Expand Down
Loading