Skip to content

Commit 687c7d5

Browse files
committed
Look through SSAValue to find include
There's no guarantee that all include calls will be literal GlobalRefs and in fact JuliaLang/julia#56746 will likely make them never GlobalRef.
1 parent 71eb16a commit 687c7d5

File tree

2 files changed

+20
-8
lines changed

2 files changed

+20
-8
lines changed

src/lowered.jl

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ add_dependencies!(methodinfo::MethodInfo, be::CodeEdges, src, isrequired) = meth
2424
add_includes!(methodinfo::MethodInfo, mod::Module, filename) = methodinfo
2525

2626
function is_some_include(@nospecialize(f))
27+
@assert !isa(f, Core.SSAValue) && !isa(f, JuliaInterpreter.SSAValue)
2728
if isa(f, GlobalRef)
2829
return f.name === :include
2930
elseif isa(f, Symbol)
@@ -44,17 +45,21 @@ function is_some_include(@nospecialize(f))
4445
end
4546

4647
# This is not generally used, see `is_method_or_eval` instead
47-
function hastrackedexpr(stmt; heads=LoweredCodeUtils.trackedheads)
48+
function hastrackedexpr(stmt, code; heads=LoweredCodeUtils.trackedheads)
4849
haseval = false
4950
if isa(stmt, Expr)
5051
haseval = matches_eval(stmt)
5152
if stmt.head === :call
5253
f = stmt.args[1]
54+
while isa(f, Core.SSAValue) || isa(f, JuliaInterpreter.SSAValue)
55+
f = code[f.id]
56+
end
5357
callee_matches(f, Core, :_typebody!) && return true, haseval
5458
callee_matches(f, Core, :_setsuper!) && return true, haseval
5559
is_some_include(f) && return true, haseval
5660
elseif stmt.head === :thunk
57-
any(s->any(hastrackedexpr(s; heads=heads)), (stmt.args[1]::Core.CodeInfo).code) && return true, haseval
61+
newcode = (stmt.args[1]::Core.CodeInfo).code
62+
any(s->any(hastrackedexpr(s, newcode; heads=heads)), newcode) && return true, haseval
5863
elseif stmt.head heads
5964
return true, haseval
6065
end
@@ -70,14 +75,21 @@ function matches_eval(stmt::Expr)
7075
(isa(f, GlobalRef) && f.name === :eval) || is_quotenode_egal(f, Core.eval)
7176
end
7277

73-
function categorize_stmt(@nospecialize(stmt))
78+
function categorize_stmt(@nospecialize(stmt), code::Vector{Any})
7479
ismeth, haseval, isinclude, isnamespace, istoplevel = false, false, false, false, false
7580
if isa(stmt, Expr)
7681
haseval = matches_eval(stmt)
7782
ismeth = stmt.head === :method || (stmt.head === :thunk && defines_function(only(stmt.args)))
7883
istoplevel = stmt.head === :toplevel
7984
isnamespace = stmt.head === :export || stmt.head === :import || stmt.head === :using
80-
isinclude = stmt.head === :call && is_some_include(stmt.args[1])
85+
isinclude = false
86+
if stmt.head === :call && length(stmt.args) >= 1
87+
callee = stmt.args[1]
88+
while isa(callee, Core.SSAValue) || isa(callee, JuliaInterpreter.SSAValue)
89+
callee = code[callee.id]
90+
end
91+
isinclude = is_some_include(callee)
92+
end
8193
end
8294
return ismeth, haseval, isinclude, isnamespace, istoplevel
8395
end
@@ -112,7 +124,7 @@ function minimal_evaluation!(@nospecialize(predicate), methodinfo, mod::Module,
112124
evalassign = false
113125
for (i, stmt) in enumerate(src.code)
114126
if !isrequired[i]
115-
isrequired[i], haseval = predicate(stmt)::Tuple{Bool,Bool}
127+
isrequired[i], haseval = predicate(stmt, src.code)::Tuple{Bool,Bool}
116128
if haseval # line `i` may be the equivalent of `f = Core.eval`, so...
117129
isrequired[edges.succs[i]] .= true # ...require each stmt that calls `eval` via `f(expr)`
118130
isrequired[i] = true
@@ -169,8 +181,8 @@ end
169181
minimal_evaluation!(predicate, methodinfo, moduleof(frame), frame.framecode.src, mode)
170182

171183
function minimal_evaluation!(methodinfo, frame::JuliaInterpreter.Frame, mode::Symbol)
172-
minimal_evaluation!(methodinfo, frame, mode) do @nospecialize(stmt)
173-
ismeth, haseval, isinclude, isnamespace, istoplevel = categorize_stmt(stmt)
184+
minimal_evaluation!(methodinfo, frame, mode) do @nospecialize(stmt), code
185+
ismeth, haseval, isinclude, isnamespace, istoplevel = categorize_stmt(stmt, code)
174186
isreq = ismeth | isinclude | istoplevel
175187
return mode === :sigs ? (isreq, haseval) : (isreq | isnamespace, haseval)
176188
end

src/packagedef.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ function add_dependencies!(methodinfo::CodeTrackingMethodInfo, edges::CodeEdges,
453453
# It is aimed at solving #249, but this will have to be generalized for anything real.
454454
for (stmt, me) in zip(src.code, musteval)
455455
me || continue
456-
if hastrackedexpr(stmt)[1]
456+
if hastrackedexpr(stmt, src.code)[1]
457457
push!(methodinfo.deps, dep)
458458
break
459459
end

0 commit comments

Comments
 (0)