11# This file is a part of Julia. License is MIT: https://julialang.org/license
22
33# build (and start inferring) the inference frame for the top-level MethodInstance
4- function typeinf (interp:: AbstractInterpreter , result:: InferenceResult , cached :: Bool )
5- frame = InferenceState (result, cached , interp)
4+ function typeinf (interp:: AbstractInterpreter , result:: InferenceResult , cache :: Symbol )
5+ frame = InferenceState (result, cache , interp)
66 frame === nothing && return false
7- cached && lock_mi_inference (interp, result. linfo)
7+ cache === :global && lock_mi_inference (interp, result. linfo)
88 return typeinf (interp, frame)
99end
1010
@@ -774,22 +774,30 @@ function typeinf_edge(interp::AbstractInterpreter, method::Method, @nospecialize
774774 mi = specialize_method (method, atypes, sparams):: MethodInstance
775775 code = get (code_cache (interp), mi, nothing )
776776 if code isa CodeInstance # return existing rettype if the code is already inferred
777- update_valid_age! (caller, WorldRange (min_world (code), max_world (code)))
778- rettype = code. rettype
779- if isdefined (code, :rettype_const )
780- rettype_const = code. rettype_const
781- if isa (rettype_const, Vector{Any}) && ! (Vector{Any} <: rettype )
782- return PartialStruct (rettype, rettype_const), mi
783- elseif rettype <: Core.OpaqueClosure && isa (rettype_const, PartialOpaque)
784- return rettype_const, mi
785- elseif isa (rettype_const, InterConditional)
786- return rettype_const, mi
777+ if code. inferred === nothing && is_stmt_inline (get_curr_ssaflag (caller))
778+ # we already inferred this edge previously and decided to discarded the inferred code
779+ # but the inlinear will request to use it, we re-infer it here and keep it around in the local cache
780+ cache = :local
781+ else
782+ update_valid_age! (caller, WorldRange (min_world (code), max_world (code)))
783+ rettype = code. rettype
784+ if isdefined (code, :rettype_const )
785+ rettype_const = code. rettype_const
786+ if isa (rettype_const, Vector{Any}) && ! (Vector{Any} <: rettype )
787+ return PartialStruct (rettype, rettype_const), mi
788+ elseif rettype <: Core.OpaqueClosure && isa (rettype_const, PartialOpaque)
789+ return rettype_const, mi
790+ elseif isa (rettype_const, InterConditional)
791+ return rettype_const, mi
792+ else
793+ return Const (rettype_const), mi
794+ end
787795 else
788- return Const (rettype_const) , mi
796+ return rettype , mi
789797 end
790- else
791- return rettype, mi
792798 end
799+ else
800+ cache = :global # cache edge targets by default
793801 end
794802 if ccall (:jl_get_module_infer , Cint, (Any,), method. module) == 0
795803 return Any, nothing
@@ -805,7 +813,7 @@ function typeinf_edge(interp::AbstractInterpreter, method::Method, @nospecialize
805813 # completely new
806814 lock_mi_inference (interp, mi)
807815 result = InferenceResult (mi)
808- frame = InferenceState (result, #= cached =# true , interp) # always use the cache for edge targets
816+ frame = InferenceState (result, cache , interp) # always use the cache for edge targets
809817 if frame === nothing
810818 # can't get the source for this, so we know nothing
811819 unlock_mi_inference (interp, mi)
@@ -834,14 +842,9 @@ function typeinf_code(interp::AbstractInterpreter, method::Method, @nospecialize
834842 mi = specialize_method (method, atypes, sparams):: MethodInstance
835843 ccall (:jl_typeinf_begin , Cvoid, ())
836844 result = InferenceResult (mi)
837- frame = InferenceState (result, false , interp)
845+ frame = InferenceState (result, run_optimizer ? :global : :no , interp)
838846 frame === nothing && return (nothing , Any)
839- if typeinf (interp, frame) && run_optimizer
840- opt_params = OptimizationParams (interp)
841- result. src = src = OptimizationState (frame, opt_params, interp)
842- optimize (interp, src, opt_params, ignorelimited (result. result))
843- frame. src = finish! (interp, result)
844- end
847+ typeinf (interp, frame)
845848 ccall (:jl_typeinf_end , Cvoid, ())
846849 frame. inferred || return (nothing , Any)
847850 return (frame. src, widenconst (ignorelimited (result. result)))
@@ -898,7 +901,7 @@ function typeinf_ext(interp::AbstractInterpreter, mi::MethodInstance)
898901 return retrieve_code_info (mi)
899902 end
900903 lock_mi_inference (interp, mi)
901- frame = InferenceState (InferenceResult (mi), #= cached =# true , interp)
904+ frame = InferenceState (InferenceResult (mi), #= cache =# :global , interp)
902905 frame === nothing && return nothing
903906 typeinf (interp, frame)
904907 ccall (:jl_typeinf_end , Cvoid, ())
@@ -921,11 +924,11 @@ function typeinf_type(interp::AbstractInterpreter, method::Method, @nospecialize
921924 return code. rettype
922925 end
923926 end
924- frame = InferenceResult (mi)
925- typeinf (interp, frame, true )
927+ result = InferenceResult (mi)
928+ typeinf (interp, result, :global )
926929 ccall (:jl_typeinf_end , Cvoid, ())
927- frame . result isa InferenceState && return nothing
928- return widenconst (ignorelimited (frame . result))
930+ result . result isa InferenceState && return nothing
931+ return widenconst (ignorelimited (result . result))
929932end
930933
931934# This is a bridge for the C code calling `jl_typeinf_func()`
@@ -941,7 +944,7 @@ function typeinf_ext_toplevel(interp::AbstractInterpreter, linfo::MethodInstance
941944 ccall (:jl_typeinf_begin , Cvoid, ())
942945 if ! src. inferred
943946 result = InferenceResult (linfo)
944- frame = InferenceState (result, src, #= cached =# true , interp)
947+ frame = InferenceState (result, src, #= cache =# :global , interp)
945948 typeinf (interp, frame)
946949 @assert frame. inferred # TODO : deal with this better
947950 src = frame. src
0 commit comments