@@ -24,6 +24,7 @@ add_dependencies!(methodinfo::MethodInfo, be::CodeEdges, src, isrequired) = meth
2424add_includes! (methodinfo:: MethodInfo , mod:: Module , filename) = methodinfo
2525
2626function 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))
4445end
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)
7176end
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
8395end
@@ -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
169181 minimal_evaluation! (predicate, methodinfo, moduleof (frame), frame. framecode. src, mode)
170182
171183function 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
0 commit comments