@@ -361,10 +361,14 @@ function InferenceState(result::InferenceResult,
361
361
end
362
362
363
363
function get_staged (li:: MethodInstance )
364
- return ccall (:jl_code_for_staged , Any, (Any,), li):: CodeInfo
364
+ try
365
+ # user code might throw errors – ignore them
366
+ return ccall (:jl_code_for_staged , Any, (Any,), li):: CodeInfo
367
+ catch
368
+ return nothing
369
+ end
365
370
end
366
371
367
-
368
372
mutable struct OptimizationState
369
373
linfo:: MethodInstance
370
374
vararg_type_container # ::Type
462
466
function retrieve_code_info (linfo:: MethodInstance )
463
467
m = linfo. def:: Method
464
468
if isdefined (m, :generator )
465
- try
466
- # user code might throw errors – ignore them
467
- c = get_staged (linfo)
468
- catch
469
- return nothing
470
- end
469
+ return get_staged (linfo)
471
470
else
472
471
# TODO : post-inference see if we can swap back to the original arrays?
473
472
if isa (m. source, Array{UInt8,1 })
@@ -2073,6 +2072,24 @@ function abstract_call_method_with_const_args(argtypes::Vector{Any}, match::Simp
2073
2072
return result
2074
2073
end
2075
2074
2075
+ function method_for_inference_heuristics (infstate:: InferenceState )
2076
+ m = infstate. src. method_for_inference_heuristics
2077
+ return isa (m, Method) ? m : infstate. linfo. def
2078
+ end
2079
+
2080
+ function method_for_inference_heuristics (method:: Method , @nospecialize (sig), sparams, world)
2081
+ if isdefined (method, :generator ) && method. generator. expand_early
2082
+ method_instance = code_for_method (method, sig, sparams, world, false )
2083
+ if isa (method_instance, MethodInstance)
2084
+ cinfo = get_staged (method_instance)
2085
+ if isa (cinfo, CodeInfo) && isa (cinfo. method_for_inference_heuristics, Method)
2086
+ return cinfo. method_for_inference_heuristics
2087
+ end
2088
+ end
2089
+ end
2090
+ return method
2091
+ end
2092
+
2076
2093
function abstract_call_method (method:: Method , @nospecialize (sig), sparams:: SimpleVector , sv:: InferenceState )
2077
2094
topmost = nothing
2078
2095
# Limit argument type tuple growth of functions:
@@ -2082,16 +2099,18 @@ function abstract_call_method(method::Method, @nospecialize(sig), sparams::Simpl
2082
2099
cyclei = 0
2083
2100
infstate = sv
2084
2101
edgecycle = false
2102
+ checked_method = method_for_inference_heuristics (method, sig, sparams, sv. params. world)
2085
2103
while ! (infstate === nothing )
2086
2104
infstate = infstate:: InferenceState
2087
- if method === infstate. linfo. def
2088
- if infstate. linfo. specTypes == sig
2089
- # avoid widening when detecting self-recursion
2090
- # TODO : merge call cycle and return right away
2091
- topmost = nothing
2092
- edgecycle = true
2093
- break
2094
- end
2105
+ if infstate. linfo. specTypes == sig
2106
+ # avoid widening when detecting self-recursion
2107
+ # TODO : merge call cycle and return right away
2108
+ topmost = nothing
2109
+ edgecycle = true
2110
+ break
2111
+ end
2112
+ working_method = method_for_inference_heuristics (infstate)
2113
+ if checked_method === working_method
2095
2114
if topmost === nothing
2096
2115
# inspect the parent of this edge,
2097
2116
# to see if they are the same Method as sv
@@ -2110,7 +2129,8 @@ function abstract_call_method(method::Method, @nospecialize(sig), sparams::Simpl
2110
2129
# then check the parent link
2111
2130
if topmost === nothing && parent != = nothing
2112
2131
parent = parent:: InferenceState
2113
- if parent. cached && parent. linfo. def === sv. linfo. def
2132
+ parent_method = method_for_inference_heuristics (parent)
2133
+ if parent. cached && parent_method === working_method
2114
2134
topmost = infstate
2115
2135
edgecycle = true
2116
2136
end
0 commit comments