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

Function insert_branch_inc_and_decrefs

mypyc/transform/refcount.py:161–208  ·  view source on GitHub ↗

Insert inc_refs and/or dec_refs after a branch/goto. Add dec_refs for registers that become dead after a branch. Add inc_refs for registers that become unborrowed after a branch or goto. Branches are special as the true and false targets may have a different live and borrowed regis

(
    block: BasicBlock,
    cache: BlockCache,
    blocks: list[BasicBlock],
    pre_live: AnalysisDict[Value],
    pre_borrow: AnalysisDict[Value],
    post_borrow: AnalysisDict[Value],
    post_must_defined: AnalysisDict[Value],
    ordering: dict[Value, int],
)

Source from the content-addressed store, hash-verified

159
160
161def insert_branch_inc_and_decrefs(
162 block: BasicBlock,
163 cache: BlockCache,
164 blocks: list[BasicBlock],
165 pre_live: AnalysisDict[Value],
166 pre_borrow: AnalysisDict[Value],
167 post_borrow: AnalysisDict[Value],
168 post_must_defined: AnalysisDict[Value],
169 ordering: dict[Value, int],
170) -> None:
171 """Insert inc_refs and/or dec_refs after a branch/goto.
172
173 Add dec_refs for registers that become dead after a branch.
174 Add inc_refs for registers that become unborrowed after a branch or goto.
175
176 Branches are special as the true and false targets may have a different
177 live and borrowed register sets. Add new blocks before the true/false target
178 blocks that tweak reference counts.
179
180 Example where we need to add an inc_ref:
181
182 def f(a: int) -> None
183 if a:
184 a = 1
185 return a # a is borrowed if condition is false and unborrowed if true
186 """
187 prev_key = (block, len(block.ops) - 1)
188 source_live_regs = pre_live[prev_key]
189 source_borrowed = post_borrow[prev_key]
190 source_defined = post_must_defined[prev_key]
191
192 term = block.terminator
193 for i, target in enumerate(term.targets()):
194 # HAX: After we've checked against an error value the value we must not touch the
195 # refcount since it will be a null pointer. The correct way to do this would be
196 # to perform data flow analysis on whether a value can be null (or is always
197 # null).
198 omitted: Iterable[Value]
199 if isinstance(term, Branch) and term.op == Branch.IS_ERROR and i == 0:
200 omitted = (term.value,)
201 else:
202 omitted = ()
203
204 decs = after_branch_decrefs(
205 target, pre_live, source_defined, source_borrowed, source_live_regs, ordering, omitted
206 )
207 incs = after_branch_increfs(target, pre_live, pre_borrow, source_borrowed, ordering)
208 term.set_target(i, add_block(decs, incs, cache, blocks, target))
209
210
211def after_branch_decrefs(

Callers 1

insert_ref_count_opcodesFunction · 0.85

Calls 8

lenFunction · 0.85
enumerateFunction · 0.85
isinstanceFunction · 0.85
after_branch_decrefsFunction · 0.85
after_branch_increfsFunction · 0.85
add_blockFunction · 0.85
targetsMethod · 0.45
set_targetMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…