@@ -210,6 +210,8 @@ function direct_links!(cl::CodeLinks, src::CodeInfo)
210
210
end
211
211
end
212
212
213
+ P = Pair{Union{SSAValue,SlotNumber,NamedVar},Links}
214
+
213
215
for (i, stmt) in enumerate (src. code)
214
216
if isexpr (stmt, :thunk ) && isa (stmt. args[1 ], CodeInfo)
215
217
icl = CodeLinks (stmt. args[1 ])
@@ -231,26 +233,26 @@ function direct_links!(cl::CodeLinks, src::CodeInfo)
231
233
if targetstore === nothing
232
234
cl. namepreds[name] = targetstore = Links ()
233
235
end
234
- target = name=> targetstore
236
+ target = P ( name, targetstore)
235
237
add_links! (target, stmt, cl)
236
238
end
237
239
rhs = stmt
238
- target = SSAValue (i)=> cl. ssapreds[i]
240
+ target = P ( SSAValue (i), cl. ssapreds[i])
239
241
elseif isexpr (stmt, :(= ))
240
242
# An assignment
241
243
stmt = stmt:: Expr
242
244
lhs, rhs = stmt. args[1 ], stmt. args[2 ]
243
245
if isslotnum (lhs)
244
246
lhs = lhs:: AnySlotNumber
245
247
id = lhs. id
246
- target = SlotNumber (id)=> cl. slotpreds[id]
248
+ target = P ( SlotNumber (id), cl. slotpreds[id])
247
249
push! (cl. slotassigns[id], i)
248
250
elseif isa (lhs, NamedVar)
249
251
targetstore = get (cl. namepreds, lhs, nothing )
250
252
if targetstore === nothing
251
253
cl. namepreds[lhs] = targetstore = Links ()
252
254
end
253
- target = lhs=> targetstore
255
+ target = P ( lhs, targetstore)
254
256
assign = get (cl. nameassigns, lhs, nothing )
255
257
if assign === nothing
256
258
cl. nameassigns[lhs] = assign = Int[]
@@ -261,30 +263,34 @@ function direct_links!(cl::CodeLinks, src::CodeInfo)
261
263
end
262
264
else
263
265
rhs = stmt
264
- target = SSAValue (i)=> cl. ssapreds[i]
266
+ target = P ( SSAValue (i), cl. ssapreds[i])
265
267
end
266
268
add_links! (target, rhs, cl)
267
269
end
268
270
return cl
269
271
end
270
272
271
- function add_links! (target:: Pair{<:Any,Links} , @nospecialize (stmt), cl:: CodeLinks )
272
- targetid, targetstore = target
273
+ function add_links! (target:: Pair{Union{SSAValue,SlotNumber,NamedVar},Links} , @nospecialize (stmt), cl:: CodeLinks )
274
+ _targetid, targetstore = target
275
+ targetid = _targetid:: Union{SSAValue,SlotNumber,NamedVar}
273
276
# Adds bidirectional edges
274
277
if isssa (stmt)
275
- push! (targetstore, stmt) # forward edge
278
+ stmt = stmt:: AnySSAValue
279
+ push! (targetstore, SSAValue (stmt. id)) # forward edge
276
280
push! (cl. ssasuccs[stmt. id], targetid) # backward edge
277
281
elseif isslotnum (stmt)
278
- push! (targetstore, stmt)
282
+ stmt = stmt:: AnySlotNumber
283
+ push! (targetstore, SlotNumber (stmt. id))
279
284
push! (cl. slotsuccs[stmt. id], targetid)
280
- elseif isa (stmt, NamedVar)
285
+ elseif isa (stmt, Symbol) || isa (stmt, GlobalRef) # NamedVar
281
286
push! (targetstore, stmt)
282
287
namestore = get (cl. namesuccs, stmt, nothing )
283
288
if namestore === nothing
284
289
cl. namesuccs[stmt] = namestore = Links ()
285
290
end
286
291
push! (namestore, targetid)
287
292
elseif isa (stmt, Expr) && stmt. head != = :copyast
293
+ stmt = stmt:: Expr
288
294
arng = 1 : length (stmt. args)
289
295
if stmt. head === :call
290
296
f = stmt. args[1 ]
@@ -303,14 +309,14 @@ function add_links!(target::Pair{<:Any,Links}, @nospecialize(stmt), cl::CodeLink
303
309
end
304
310
305
311
function Base. push! (l:: Links , id)
306
- if isssa (id)
312
+ if isa (id, SSAValue )
307
313
k = id. id
308
314
k ∉ l. ssas && push! (l. ssas, k)
309
- elseif isslotnum (id)
315
+ elseif isa (id, SlotNumber )
310
316
k = id. id
311
317
k ∉ l. slots && push! (l. slots, k)
312
318
else
313
- # NamedVar
319
+ id = id :: NamedVar
314
320
id ∉ l. names && push! (l. names, id)
315
321
end
316
322
return id
393
399
function CodeEdges (src:: CodeInfo , cl:: CodeLinks )
394
400
# The main task here is to elide the slot-dependencies and convert
395
401
# everything to just ssas & names.
396
- # Hence we "follow" slot links to their non-slot leaves.
397
- function follow_links! (marked, l:: Links , slotlinks, slotassigns, slothandled)
398
- pushall! (marked, l. ssas)
399
- for id in l. slots
400
- slothandled[id] && continue
401
- slothandled[id] = true
402
- pushall! (marked, slotassigns[id])
403
- follow_links! (marked, slotlinks[id], slotlinks, slotassigns, slothandled)
404
- end
405
- return marked
406
- end
407
402
408
403
# Replace/add named intermediates (slot & named-variable references) with statement numbers
409
404
nstmts, nslots = length (src. code), length (src. slotnames)
@@ -484,6 +479,18 @@ function CodeEdges(src::CodeInfo, cl::CodeLinks)
484
479
return edges
485
480
end
486
481
482
+ # Follow slot links to their non-slot leaves
483
+ function follow_links! (marked, l:: Links , slotlinks, slotassigns, slothandled)
484
+ pushall! (marked, l. ssas)
485
+ for id in l. slots
486
+ slothandled[id] && continue
487
+ slothandled[id] = true
488
+ pushall! (marked, slotassigns[id])
489
+ follow_links! (marked, slotlinks[id], slotlinks, slotassigns, slothandled)
490
+ end
491
+ return marked
492
+ end
493
+
487
494
"""
488
495
print_with_code(io, src::CodeInfo, edges::CodeEdges)
489
496
0 commit comments