MCPcopy Index your code
hub / github.com/python/mypy / spill_regs

Function spill_regs

mypyc/transform/spill.py:34–113  ·  view source on GitHub ↗
(
    blocks: list[BasicBlock],
    env: ClassIR,
    to_spill: set[Value],
    live: AnalysisResult[Value],
    self_reg: Register,
)

Source from the content-addressed store, hash-verified

32
33
34def spill_regs(
35 blocks: list[BasicBlock],
36 env: ClassIR,
37 to_spill: set[Value],
38 live: AnalysisResult[Value],
39 self_reg: Register,
40) -> list[BasicBlock]:
41 env_reg: Value
42 for op in blocks[0].ops:
43 if isinstance(op, GetAttr) and op.attr == "__mypyc_env__":
44 env_reg = op
45 break
46 else:
47 # Environment has been merged into generator object
48 env_reg = self_reg
49
50 spill_locs = {}
51 for i, val in enumerate(to_spill):
52 name = f"{TEMP_ATTR_NAME}2_{i}"
53 env.attributes[name] = val.type
54 if val.type.error_overlap:
55 # We can safely treat as always initialized, since the type has no pointers.
56 # This way we also don't need to manage the defined attribute bitfield.
57 env._always_initialized_attrs.add(name)
58 spill_locs[val] = name
59
60 for block in blocks:
61 ops = block.ops
62 block.ops = []
63
64 for i, op in enumerate(ops):
65 to_decref = []
66
67 if isinstance(op, IncRef) and op.src in spill_locs:
68 raise AssertionError("not sure what to do with an incref of a spill...")
69 if isinstance(op, DecRef) and op.src in spill_locs:
70 # When we decref a spilled value, we turn that into
71 # NULLing out the attribute, but only if the spilled
72 # value is not live *when we include yields in the
73 # CFG*. (The original decrefs are computed without that.)
74 #
75 # We also skip a decref is the env register is not
76 # live. That should only happen when an exception is
77 # being raised, so everything should be handled there.
78 if op.src not in live.after[block, i] and env_reg in live.after[block, i]:
79 # Skip the DecRef but null out the spilled location
80 null = LoadErrorValue(op.src.type)
81 block.ops.extend([null, SetAttr(env_reg, spill_locs[op.src], null, op.line)])
82 continue
83
84 if (
85 any(src in spill_locs for src in op.sources())
86 # N.B: IS_ERROR should be before a spill happens
87 # XXX: but could we have a regular branch?
88 and not (isinstance(op, Branch) and op.op == Branch.IS_ERROR)
89 ):
90 new_sources: list[Value] = []
91 stolen = op.stolen()

Callers 1

insert_spillsFunction · 0.85

Calls 13

LoadErrorValueClass · 0.90
SetAttrClass · 0.90
GetAttrClass · 0.90
DecRefClass · 0.90
isinstanceFunction · 0.85
enumerateFunction · 0.85
anyFunction · 0.85
extendMethod · 0.80
appendMethod · 0.80
addMethod · 0.45
sourcesMethod · 0.45
stolenMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…