@@ -203,14 +203,20 @@ function direct_links!(cl::CodeLinks, src::CodeInfo)
203
203
push! (assign, i)
204
204
end
205
205
continue
206
- elseif isexpr (stmt, :method )
206
+ elseif isa (stmt, Expr) && stmt . head ∈ trackedheads
207
207
name = stmt. args[1 ]
208
208
if isa (name, Symbol)
209
209
assign = get (cl. nameassigns, name, nothing )
210
210
if assign === nothing
211
211
cl. nameassigns[name] = assign = Int[]
212
212
end
213
213
push! (assign, i)
214
+ targetstore = get (cl. namepreds, name, nothing )
215
+ if targetstore === nothing
216
+ cl. namepreds[name] = targetstore = Links ()
217
+ end
218
+ target = name=> targetstore
219
+ add_links! (target, stmt, cl)
214
220
end
215
221
rhs = stmt
216
222
target = SSAValue (i)=> cl. ssapreds[i]
@@ -294,7 +300,7 @@ function Base.push!(l::Links, id)
294
300
return id
295
301
end
296
302
297
- # # Phase 2: replacing name -links with statement-links
303
+ # # Phase 2: replacing slot -links with statement-links (and adding name-links to statement-links)
298
304
299
305
# Now that we know the full set of dependencies, we can safely replace references to names
300
306
# by references to the relevant line numbers.
@@ -375,12 +381,23 @@ function CodeEdges(src::CodeInfo, cl::CodeLinks)
375
381
end
376
382
return dest
377
383
end
384
+ # The main task here is to elide the slot-dependencies and convert
385
+ # everything to just ssas & names.
386
+ # Hence we "follow" slot links to their non-slot leaves.
387
+ function follow_links! (marked, l:: Links , slotlinks, slotassigns, slothandled)
388
+ pushall! (marked, l. ssas)
389
+ for id in l. slots
390
+ slothandled[id] && continue
391
+ slothandled[id] = true
392
+ pushall! (marked, slotassigns[id])
393
+ follow_links! (marked, slotlinks[id], slotlinks, slotassigns, slothandled)
394
+ end
395
+ return marked
396
+ end
378
397
379
- src. inferred && error (" supply lowered but not inferred code" )
380
- cl = CodeLinks (src)
381
- # Phase 2: replace named intermediates (slot & named-variable references) with statement numbers
398
+ # Replace/add named intermediates (slot & named-variable references) with statement numbers
382
399
nstmts, nslots = length (src. code), length (src. slotnames)
383
- marked = BitSet () # working storage during resolution
400
+ marked, slothandled = BitSet (), fill ( false , nslots ) # working storage during resolution
384
401
edges = CodeEdges (nstmts)
385
402
emptylink = Links ()
386
403
emptylist = Int[]
@@ -407,25 +424,19 @@ function CodeEdges(src::CodeInfo, cl::CodeLinks)
407
424
# Assign the predecessors
408
425
# For "named" predecessors, we depend only on their assignments
409
426
empty! (marked)
410
- pushall! (marked, cl . ssapreds[i] . ssas )
411
- pushall ! (marked, linkpreds. ssas )
427
+ fill! (slothandled, false )
428
+ follow_links ! (marked, linkpreds, cl . slotpreds, cl . slotassigns, slothandled )
412
429
pushall! (marked, listassigns)
413
- for j in linkpreds. slots
414
- pushall! (marked, cl. slotassigns[j])
415
- end
416
430
for key in linkpreds. names
417
431
pushall! (marked, get (cl. nameassigns, key, emptylist))
418
432
end
419
433
delete! (marked, i)
420
434
append! (edges. preds[i], marked)
421
435
# Similarly for successors
422
436
empty! (marked)
423
- pushall! (marked, cl . ssasuccs[i] . ssas )
424
- pushall ! (marked, linksuccs. ssas )
437
+ fill! (slothandled, false )
438
+ follow_links ! (marked, linksuccs, cl . slotsuccs, cl . slotassigns, slothandled )
425
439
pushall! (marked, listassigns)
426
- for j in linksuccs. slots
427
- pushall! (marked, cl. slotassigns[j])
428
- end
429
440
for key in linksuccs. names
430
441
pushall! (marked, get (cl. nameassigns, key, emptylist))
431
442
end
@@ -451,6 +462,7 @@ function CodeEdges(src::CodeInfo, cl::CodeLinks)
451
462
pushall! (marked, linksuccs. ssas)
452
463
for j in linksuccs. slots
453
464
pushall! (marked, cl. slotassigns[j])
465
+ pushall! (marked, cl. slotsuccs[j]. ssas)
454
466
end
455
467
for key in linksuccs. names
456
468
pushall! (marked, get (cl. nameassigns, key, emptylist))
0 commit comments