1- const NamedVar = Union{Symbol,GlobalRef}
2-
31# # Phase 1: direct links
42
53# 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}
97struct Links
108 ssas:: Vector{Int}
119 slots:: Vector{Int}
12- names:: Vector{NamedVar }
10+ names:: Vector{GlobalRef }
1311end
14- Links () = Links (Int[], Int[], NamedVar [])
12+ Links () = Links (Int[], Int[], GlobalRef [])
1513
1614function Base. show (io:: IO , l:: Links )
1715 print (io, " ssas: " , showempty (l. ssas),
1816 " , slots: " , showempty (l. slots),
1917 " , names: " )
20- print (IOContext (io, :typeinfo => Vector{NamedVar }), showempty (l. names))
18+ print (IOContext (io, :typeinfo => Vector{GlobalRef }), showempty (l. names))
2119 print (io, ' ;' )
2220end
2321
2422struct CodeLinks
23+ thismod:: Module
2524 ssapreds:: Vector{Links}
2625 ssasuccs:: Vector{Links}
2726 slotpreds:: Vector{Links}
2827 slotsuccs:: Vector{Links}
2928 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}}
3332end
34- function CodeLinks (nlines:: Int , nslots:: Int )
33+ function CodeLinks (thismod :: Module , nlines:: Int , nslots:: Int )
3534 makelinks (n) = [Links () for _ = 1 : n]
3635
37- return CodeLinks (makelinks (nlines),
36+ return CodeLinks (thismod,
37+ makelinks (nlines),
3838 makelinks (nlines),
3939 makelinks (nslots),
4040 makelinks (nslots),
4141 [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}} ())
4545end
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))
4848 direct_links! (cl, src)
4949end
5050
175175
176176
177177function namedkeys (cl:: CodeLinks )
178- ukeys = Set {NamedVar } ()
178+ ukeys = Set {GlobalRef } ()
179179 for c in (cl. namepreds, cl. namesuccs, cl. nameassigns)
180180 for k in keys (c)
181181 push! (ukeys, k)
@@ -203,20 +203,23 @@ function direct_links!(cl::CodeLinks, src::CodeInfo)
203203 end
204204 end
205205
206- P = Pair{Union{SSAValue,SlotNumber,NamedVar },Links}
206+ P = Pair{Union{SSAValue,SlotNumber,GlobalRef },Links}
207207
208208 for (i, stmt) in enumerate (src. code)
209209 if isexpr (stmt, :thunk ) && isa (stmt. args[1 ], CodeInfo)
210- icl = CodeLinks (stmt. args[1 ])
210+ icl = CodeLinks (cl . thismod, stmt. args[1 ])
211211 add_inner! (cl, icl, i)
212212 continue
213213 elseif isa (stmt, Expr) && stmt. head ∈ trackedheads
214214 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 ])
216216 add_inner! (cl, icl, i)
217217 end
218218 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
220223 assign = get (cl. nameassigns, name, nothing )
221224 if assign === nothing
222225 cl. nameassigns[name] = assign = Int[]
@@ -228,6 +231,10 @@ function direct_links!(cl::CodeLinks, src::CodeInfo)
228231 end
229232 target = P (name, targetstore)
230233 add_links! (target, stmt, cl)
234+ elseif name in (nothing , false )
235+ else
236+ @show stmt
237+ error (" name " , typeof (name), " not recognized" )
231238 end
232239 rhs = stmt
233240 target = P (SSAValue (i), cl. ssapreds[i])
@@ -240,7 +247,10 @@ function direct_links!(cl::CodeLinks, src::CodeInfo)
240247 id = lhs. id
241248 target = P (SlotNumber (id), cl. slotpreds[id])
242249 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
244254 targetstore = get (cl. namepreds, lhs, nothing )
245255 if targetstore === nothing
246256 cl. namepreds[lhs] = targetstore = Links ()
@@ -263,9 +273,9 @@ function direct_links!(cl::CodeLinks, src::CodeInfo)
263273 return cl
264274end
265275
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 )
267277 _targetid, targetstore = target
268- targetid = _targetid:: Union{SSAValue,SlotNumber,NamedVar }
278+ targetid = _targetid:: Union{SSAValue,SlotNumber,GlobalRef }
269279 # Adds bidirectional edges
270280 if @isssa (stmt)
271281 stmt = stmt:: AnySSAValue
@@ -275,7 +285,10 @@ function add_links!(target::Pair{Union{SSAValue,SlotNumber,NamedVar},Links}, @no
275285 stmt = stmt:: AnySlotNumber
276286 push! (targetstore, SlotNumber (stmt. id))
277287 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
279292 push! (targetstore, stmt)
280293 namestore = get (cl. namesuccs, stmt, nothing )
281294 if namestore === nothing
@@ -311,7 +324,7 @@ function Base.push!(l::Links, id)
311324 k = id. id
312325 k ∉ l. slots && push! (l. slots, k)
313326 else
314- id = id:: NamedVar
327+ id = id:: GlobalRef
315328 id ∉ l. names && push! (l. names, id)
316329 end
317330 return id
355368struct CodeEdges
356369 preds:: Vector{Vector{Int}}
357370 succs:: Vector{Vector{Int}}
358- byname:: Dict{NamedVar ,Variable}
371+ byname:: Dict{GlobalRef ,Variable}
359372end
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} ())
361374
362375function Base. show (io:: IO , edges:: CodeEdges )
363376 println (io, " CodeEdges:" )
@@ -383,10 +396,10 @@ Analyze `src` and determine the chain of dependencies.
383396- `edges.preds[i]` lists the preceding statements that statement `i` depends on.
384397- `edges.succs[i]` lists the succeeding statements that depend on statement `i`.
385398- `edges.byname[v]` returns information about the predecessors, successors, and assignment statements
386- for an object `v::$NamedVar `.
399+ for an object `v::GlobalRef `.
387400"""
388- function CodeEdges (src:: CodeInfo )
389- cl = CodeLinks (src)
401+ function CodeEdges (mod :: Module , src:: CodeInfo )
402+ cl = CodeLinks (mod, src)
390403 CodeEdges (src, cl)
391404end
392405
@@ -412,7 +425,10 @@ function CodeEdges(src::CodeInfo, cl::CodeLinks)
412425 id = lhs. id
413426 linkpreds, linksuccs, listassigns = cl. slotpreds[id], cl. slotsuccs[id], cl. slotassigns[id]
414427 else
415- lhs = lhs:: NamedVar
428+ lhs = lhs:: Union{GlobalRef,Symbol}
429+ if lhs isa Symbol
430+ lhs = GlobalRef (cl. thismod, lhs)
431+ end
416432 linkpreds = get (cl. namepreds, lhs, emptylink)
417433 linksuccs = get (cl. namesuccs, lhs, emptylink)
418434 listassigns = get (cl. nameassigns, lhs, emptylist)
@@ -546,7 +562,7 @@ function terminal_preds(i::Int, edges::CodeEdges)
546562end
547563
548564"""
549- isrequired = lines_required(obj::$NamedVar , src::CodeInfo, edges::CodeEdges)
565+ isrequired = lines_required(obj::GlobalRef , src::CodeInfo, edges::CodeEdges)
550566 isrequired = lines_required(idx::Int, src::CodeInfo, edges::CodeEdges)
551567
552568Determine 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
556572
557573See also [`lines_required!`](@ref) and [`selective_eval!`](@ref).
558574"""
559- function lines_required (obj:: NamedVar , src:: CodeInfo , edges:: CodeEdges ; kwargs... )
575+ function lines_required (obj:: GlobalRef , src:: CodeInfo , edges:: CodeEdges ; kwargs... )
560576 isrequired = falses (length (edges. preds))
561- objs = Set {NamedVar } ([obj])
577+ objs = Set {GlobalRef } ([obj])
562578 return lines_required! (isrequired, objs, src, edges; kwargs... )
563579end
564580
565581function lines_required (idx:: Int , src:: CodeInfo , edges:: CodeEdges ; kwargs... )
566582 isrequired = falses (length (edges. preds))
567583 isrequired[idx] = true
568- objs = Set {NamedVar } ()
584+ objs = Set {GlobalRef } ()
569585 return lines_required! (isrequired, objs, src, edges; kwargs... )
570586end
571587
@@ -583,7 +599,7 @@ For example, use `norequire = LoweredCodeUtils.exclude_named_typedefs(src, edges
583599extracting method signatures and not evaluating new definitions.
584600"""
585601function lines_required! (isrequired:: AbstractVector{Bool} , src:: CodeInfo , edges:: CodeEdges ; kwargs... )
586- objs = Set {NamedVar } ()
602+ objs = Set {GlobalRef } ()
587603 return lines_required! (isrequired, objs, src, edges; kwargs... )
588604end
589605
@@ -643,7 +659,7 @@ function lines_required!(isrequired::AbstractVector{Bool}, objs, src::CodeInfo,
643659end
644660
645661function add_requests! (isrequired, objs, edges:: CodeEdges , norequire)
646- objsnew = Set {NamedVar } ()
662+ objsnew = Set {GlobalRef } ()
647663 for obj in objs
648664 add_obj! (isrequired, objsnew, obj, edges, norequire)
649665 end
0 commit comments