33
33
from mypyc .ir .func_ir import FuncIR , all_values
34
34
35
35
36
- DecIncs = Tuple [Tuple [Tuple [Value , bool ], ...], Tuple [Value , ...]]
36
+ Decs = Tuple [Tuple [Value , bool ], ...]
37
+ Incs = Tuple [Value , ...]
37
38
38
- # A of basic blocks that decrement and increment specific values and
39
- # then jump to some target block. This lets us cut down on how much
40
- # code we generate in some circumstances.
41
- BlockCache = Dict [Tuple [BasicBlock , DecIncs ], BasicBlock ]
39
+ # A cache of basic blocks that decrement and increment specific values
40
+ # and then jump to some target block. This lets us cut down on how
41
+ # much code we generate in some circumstances.
42
+ BlockCache = Dict [Tuple [BasicBlock , Decs , Incs ], BasicBlock ]
42
43
43
44
44
45
def insert_ref_count_opcodes (ir : FuncIR ) -> None :
@@ -161,36 +162,25 @@ def f(a: int) -> None
161
162
source_live_regs = pre_live [prev_key ]
162
163
source_borrowed = post_borrow [prev_key ]
163
164
source_defined = post_must_defined [prev_key ]
164
- if isinstance (block .ops [- 1 ], Branch ):
165
- branch = block .ops [- 1 ]
165
+
166
+ term = block .terminator
167
+ for i , target in enumerate (term .targets ()):
166
168
# HAX: After we've checked against an error value the value we must not touch the
167
169
# refcount since it will be a null pointer. The correct way to do this would be
168
170
# to perform data flow analysis on whether a value can be null (or is always
169
171
# null).
170
- if branch .op == Branch .IS_ERROR :
171
- omitted = {branch .value }
172
+ omitted : Iterable [Value ]
173
+ if isinstance (term , Branch ) and term .op == Branch .IS_ERROR and i == 0 :
174
+ omitted = (term .value ,)
172
175
else :
173
- omitted = set ()
174
- true_decincs = (
175
- after_branch_decrefs (
176
- branch .true , pre_live , source_defined ,
177
- source_borrowed , source_live_regs , ordering , omitted ),
178
- after_branch_increfs (
179
- branch .true , pre_live , pre_borrow , source_borrowed , ordering ))
180
- branch .true = add_block (true_decincs , cache , blocks , branch .true )
181
-
182
- false_decincs = (
183
- after_branch_decrefs (
184
- branch .false , pre_live , source_defined , source_borrowed , source_live_regs ,
185
- ordering ),
186
- after_branch_increfs (
187
- branch .false , pre_live , pre_borrow , source_borrowed , ordering ))
188
- branch .false = add_block (false_decincs , cache , blocks , branch .false )
189
- elif isinstance (block .ops [- 1 ], Goto ):
190
- goto = block .ops [- 1 ]
191
- new_decincs = ((), after_branch_increfs (
192
- goto .label , pre_live , pre_borrow , source_borrowed , ordering ))
193
- goto .label = add_block (new_decincs , cache , blocks , goto .label )
176
+ omitted = ()
177
+
178
+ decs = after_branch_decrefs (
179
+ target , pre_live , source_defined ,
180
+ source_borrowed , source_live_regs , ordering , omitted )
181
+ incs = after_branch_increfs (
182
+ target , pre_live , pre_borrow , source_borrowed , ordering )
183
+ term .set_target (i , add_block (decs , incs , cache , blocks , target ))
194
184
195
185
196
186
def after_branch_decrefs (label : BasicBlock ,
@@ -199,7 +189,7 @@ def after_branch_decrefs(label: BasicBlock,
199
189
source_borrowed : Set [Value ],
200
190
source_live_regs : Set [Value ],
201
191
ordering : Dict [Value , int ],
202
- omitted : Iterable [Value ] = () ) -> Tuple [Tuple [Value , bool ], ...]:
192
+ omitted : Iterable [Value ]) -> Tuple [Tuple [Value , bool ], ...]:
203
193
target_pre_live = pre_live [label , 0 ]
204
194
decref = source_live_regs - target_pre_live - source_borrowed
205
195
if decref :
@@ -224,22 +214,21 @@ def after_branch_increfs(label: BasicBlock,
224
214
return ()
225
215
226
216
227
- def add_block (decincs : DecIncs , cache : BlockCache ,
217
+ def add_block (decs : Decs , incs : Incs , cache : BlockCache ,
228
218
blocks : List [BasicBlock ], label : BasicBlock ) -> BasicBlock :
229
- decs , incs = decincs
230
219
if not decs and not incs :
231
220
return label
232
221
233
222
# TODO: be able to share *partial* results
234
- if (label , decincs ) in cache :
235
- return cache [label , decincs ]
223
+ if (label , decs , incs ) in cache :
224
+ return cache [label , decs , incs ]
236
225
237
226
block = BasicBlock ()
238
227
blocks .append (block )
239
228
block .ops .extend (DecRef (reg , is_xdec = xdec ) for reg , xdec in decs )
240
229
block .ops .extend (IncRef (reg ) for reg in incs )
241
230
block .ops .append (Goto (label ))
242
- cache [label , decincs ] = block
231
+ cache [label , decs , incs ] = block
243
232
return block
244
233
245
234
0 commit comments