1
- const NamedVar = Union{Symbol,GlobalRef}
2
-
3
1
# # Phase 1: direct links
4
2
5
3
# There are 3 types of entities to track: ssavalues (line/statement numbers), slots, and named objects.
@@ -9,42 +7,44 @@ const NamedVar = Union{Symbol,GlobalRef}
9
7
struct Links
10
8
ssas:: Vector{Int}
11
9
slots:: Vector{Int}
12
- names:: Vector{NamedVar }
10
+ names:: Vector{GlobalRef }
13
11
end
14
- Links () = Links (Int[], Int[], NamedVar [])
12
+ Links () = Links (Int[], Int[], GlobalRef [])
15
13
16
14
function Base. show (io:: IO , l:: Links )
17
15
print (io, " ssas: " , showempty (l. ssas),
18
16
" , slots: " , showempty (l. slots),
19
17
" , names: " )
20
- print (IOContext (io, :typeinfo => Vector{NamedVar }), showempty (l. names))
18
+ print (IOContext (io, :typeinfo => Vector{GlobalRef }), showempty (l. names))
21
19
print (io, ' ;' )
22
20
end
23
21
24
22
struct CodeLinks
23
+ thismod:: Module
25
24
ssapreds:: Vector{Links}
26
25
ssasuccs:: Vector{Links}
27
26
slotpreds:: Vector{Links}
28
27
slotsuccs:: Vector{Links}
29
28
slotassigns:: Vector{Vector{Int}}
30
- namepreds:: Dict{NamedVar ,Links}
31
- namesuccs:: Dict{NamedVar ,Links}
32
- nameassigns:: Dict{NamedVar ,Vector{Int}}
29
+ namepreds:: Dict{GlobalRef ,Links}
30
+ namesuccs:: Dict{GlobalRef ,Links}
31
+ nameassigns:: Dict{GlobalRef ,Vector{Int}}
33
32
end
34
- function CodeLinks (nlines:: Int , nslots:: Int )
33
+ function CodeLinks (thismod :: Module , nlines:: Int , nslots:: Int )
35
34
makelinks (n) = [Links () for _ = 1 : n]
36
35
37
- return CodeLinks (makelinks (nlines),
36
+ return CodeLinks (thismod,
37
+ makelinks (nlines),
38
38
makelinks (nlines),
39
39
makelinks (nslots),
40
40
makelinks (nslots),
41
41
[Int[] for _ = 1 : nslots],
42
- Dict {NamedVar ,Links} (),
43
- Dict {NamedVar ,Links} (),
44
- Dict {NamedVar ,Vector{Int}} ())
42
+ Dict {GlobalRef ,Links} (),
43
+ Dict {GlobalRef ,Links} (),
44
+ Dict {GlobalRef ,Vector{Int}} ())
45
45
end
46
- function CodeLinks (src:: CodeInfo )
47
- cl = CodeLinks (length (src. code), length (src. slotnames))
46
+ function CodeLinks (thismod :: Module , src:: CodeInfo )
47
+ cl = CodeLinks (thismod, length (src. code), length (src. slotnames))
48
48
direct_links! (cl, src)
49
49
end
50
50
175
175
176
176
177
177
function namedkeys (cl:: CodeLinks )
178
- ukeys = Set {NamedVar } ()
178
+ ukeys = Set {GlobalRef } ()
179
179
for c in (cl. namepreds, cl. namesuccs, cl. nameassigns)
180
180
for k in keys (c)
181
181
push! (ukeys, k)
@@ -203,20 +203,23 @@ function direct_links!(cl::CodeLinks, src::CodeInfo)
203
203
end
204
204
end
205
205
206
- P = Pair{Union{SSAValue,SlotNumber,NamedVar },Links}
206
+ P = Pair{Union{SSAValue,SlotNumber,GlobalRef },Links}
207
207
208
208
for (i, stmt) in enumerate (src. code)
209
209
if isexpr (stmt, :thunk ) && isa (stmt. args[1 ], CodeInfo)
210
- icl = CodeLinks (stmt. args[1 ])
210
+ icl = CodeLinks (cl . thismod, stmt. args[1 ])
211
211
add_inner! (cl, icl, i)
212
212
continue
213
213
elseif isa (stmt, Expr) && stmt. head ∈ trackedheads
214
214
if stmt. head === :method && length (stmt. args) === 3 && isa (stmt. args[3 ], CodeInfo)
215
- icl = CodeLinks (stmt. args[3 ])
215
+ icl = CodeLinks (cl . thismod, stmt. args[3 ])
216
216
add_inner! (cl, icl, i)
217
217
end
218
218
name = stmt. args[1 ]
219
- if isa (name, Symbol)
219
+ if isa (name, GlobalRef) || isa (name, Symbol)
220
+ if isa (name, Symbol)
221
+ name = GlobalRef (cl. thismod, name)
222
+ end
220
223
assign = get (cl. nameassigns, name, nothing )
221
224
if assign === nothing
222
225
cl. nameassigns[name] = assign = Int[]
@@ -228,6 +231,10 @@ function direct_links!(cl::CodeLinks, src::CodeInfo)
228
231
end
229
232
target = P (name, targetstore)
230
233
add_links! (target, stmt, cl)
234
+ elseif name in (nothing , false )
235
+ else
236
+ @show stmt
237
+ error (" name " , typeof (name), " not recognized" )
231
238
end
232
239
rhs = stmt
233
240
target = P (SSAValue (i), cl. ssapreds[i])
@@ -240,7 +247,10 @@ function direct_links!(cl::CodeLinks, src::CodeInfo)
240
247
id = lhs. id
241
248
target = P (SlotNumber (id), cl. slotpreds[id])
242
249
push! (cl. slotassigns[id], i)
243
- elseif isa (lhs, NamedVar)
250
+ elseif isa (lhs, GlobalRef) || isa (lhs, Symbol)
251
+ if isa (lhs, Symbol)
252
+ lhs = GlobalRef (cl. thismod, lhs)
253
+ end
244
254
targetstore = get (cl. namepreds, lhs, nothing )
245
255
if targetstore === nothing
246
256
cl. namepreds[lhs] = targetstore = Links ()
@@ -263,9 +273,9 @@ function direct_links!(cl::CodeLinks, src::CodeInfo)
263
273
return cl
264
274
end
265
275
266
- function add_links! (target:: Pair{Union{SSAValue,SlotNumber,NamedVar },Links} , @nospecialize (stmt), cl:: CodeLinks )
276
+ function add_links! (target:: Pair{Union{SSAValue,SlotNumber,GlobalRef },Links} , @nospecialize (stmt), cl:: CodeLinks )
267
277
_targetid, targetstore = target
268
- targetid = _targetid:: Union{SSAValue,SlotNumber,NamedVar }
278
+ targetid = _targetid:: Union{SSAValue,SlotNumber,GlobalRef }
269
279
# Adds bidirectional edges
270
280
if @isssa (stmt)
271
281
stmt = stmt:: AnySSAValue
@@ -275,7 +285,10 @@ function add_links!(target::Pair{Union{SSAValue,SlotNumber,NamedVar},Links}, @no
275
285
stmt = stmt:: AnySlotNumber
276
286
push! (targetstore, SlotNumber (stmt. id))
277
287
push! (cl. slotsuccs[stmt. id], targetid)
278
- elseif isa (stmt, Symbol) || isa (stmt, GlobalRef) # NamedVar
288
+ elseif isa (stmt, GlobalRef) || isa (stmt, Symbol)
289
+ if isa (stmt, Symbol)
290
+ stmt = GlobalRef (cl. thismod, stmt)
291
+ end
279
292
push! (targetstore, stmt)
280
293
namestore = get (cl. namesuccs, stmt, nothing )
281
294
if namestore === nothing
@@ -311,7 +324,7 @@ function Base.push!(l::Links, id)
311
324
k = id. id
312
325
k ∉ l. slots && push! (l. slots, k)
313
326
else
314
- id = id:: NamedVar
327
+ id = id:: GlobalRef
315
328
id ∉ l. names && push! (l. names, id)
316
329
end
317
330
return id
355
368
struct CodeEdges
356
369
preds:: Vector{Vector{Int}}
357
370
succs:: Vector{Vector{Int}}
358
- byname:: Dict{NamedVar ,Variable}
371
+ byname:: Dict{GlobalRef ,Variable}
359
372
end
360
- CodeEdges (n:: Integer ) = CodeEdges ([Int[] for i = 1 : n], [Int[] for i = 1 : n], Dict {Union{ GlobalRef,Symbol} ,Variable} ())
373
+ CodeEdges (n:: Integer ) = CodeEdges ([Int[] for i = 1 : n], [Int[] for i = 1 : n], Dict {GlobalRef,Variable} ())
361
374
362
375
function Base. show (io:: IO , edges:: CodeEdges )
363
376
println (io, " CodeEdges:" )
@@ -383,10 +396,10 @@ Analyze `src` and determine the chain of dependencies.
383
396
- `edges.preds[i]` lists the preceding statements that statement `i` depends on.
384
397
- `edges.succs[i]` lists the succeeding statements that depend on statement `i`.
385
398
- `edges.byname[v]` returns information about the predecessors, successors, and assignment statements
386
- for an object `v::$NamedVar `.
399
+ for an object `v::GlobalRef `.
387
400
"""
388
- function CodeEdges (src:: CodeInfo )
389
- cl = CodeLinks (src)
401
+ function CodeEdges (mod :: Module , src:: CodeInfo )
402
+ cl = CodeLinks (mod, src)
390
403
CodeEdges (src, cl)
391
404
end
392
405
@@ -412,7 +425,10 @@ function CodeEdges(src::CodeInfo, cl::CodeLinks)
412
425
id = lhs. id
413
426
linkpreds, linksuccs, listassigns = cl. slotpreds[id], cl. slotsuccs[id], cl. slotassigns[id]
414
427
else
415
- lhs = lhs:: NamedVar
428
+ lhs = lhs:: Union{GlobalRef,Symbol}
429
+ if lhs isa Symbol
430
+ lhs = GlobalRef (cl. thismod, lhs)
431
+ end
416
432
linkpreds = get (cl. namepreds, lhs, emptylink)
417
433
linksuccs = get (cl. namesuccs, lhs, emptylink)
418
434
listassigns = get (cl. nameassigns, lhs, emptylist)
@@ -546,7 +562,7 @@ function terminal_preds(i::Int, edges::CodeEdges)
546
562
end
547
563
548
564
"""
549
- isrequired = lines_required(obj::$NamedVar , src::CodeInfo, edges::CodeEdges)
565
+ isrequired = lines_required(obj::GlobalRef , src::CodeInfo, edges::CodeEdges)
550
566
isrequired = lines_required(idx::Int, src::CodeInfo, edges::CodeEdges)
551
567
552
568
Determine which lines might need to be executed to evaluate `obj` or the statement indexed by `idx`.
@@ -556,16 +572,16 @@ will end up skipping a subset of such statements, perhaps while repeating others
556
572
557
573
See also [`lines_required!`](@ref) and [`selective_eval!`](@ref).
558
574
"""
559
- function lines_required (obj:: NamedVar , src:: CodeInfo , edges:: CodeEdges ; kwargs... )
575
+ function lines_required (obj:: GlobalRef , src:: CodeInfo , edges:: CodeEdges ; kwargs... )
560
576
isrequired = falses (length (edges. preds))
561
- objs = Set {NamedVar } ([obj])
577
+ objs = Set {GlobalRef } ([obj])
562
578
return lines_required! (isrequired, objs, src, edges; kwargs... )
563
579
end
564
580
565
581
function lines_required (idx:: Int , src:: CodeInfo , edges:: CodeEdges ; kwargs... )
566
582
isrequired = falses (length (edges. preds))
567
583
isrequired[idx] = true
568
- objs = Set {NamedVar } ()
584
+ objs = Set {GlobalRef } ()
569
585
return lines_required! (isrequired, objs, src, edges; kwargs... )
570
586
end
571
587
@@ -583,7 +599,7 @@ For example, use `norequire = LoweredCodeUtils.exclude_named_typedefs(src, edges
583
599
extracting method signatures and not evaluating new definitions.
584
600
"""
585
601
function lines_required! (isrequired:: AbstractVector{Bool} , src:: CodeInfo , edges:: CodeEdges ; kwargs... )
586
- objs = Set {NamedVar } ()
602
+ objs = Set {GlobalRef } ()
587
603
return lines_required! (isrequired, objs, src, edges; kwargs... )
588
604
end
589
605
@@ -643,7 +659,7 @@ function lines_required!(isrequired::AbstractVector{Bool}, objs, src::CodeInfo,
643
659
end
644
660
645
661
function add_requests! (isrequired, objs, edges:: CodeEdges , norequire)
646
- objsnew = Set {NamedVar } ()
662
+ objsnew = Set {GlobalRef } ()
647
663
for obj in objs
648
664
add_obj! (isrequired, objsnew, obj, edges, norequire)
649
665
end
0 commit comments