1
1
# This file is a part of Julia. License is MIT: https://julialang.org/license
2
2
3
3
# 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)
6
6
frame === nothing && return false
7
- cached && lock_mi_inference (interp, result. linfo)
7
+ cache === :global && lock_mi_inference (interp, result. linfo)
8
8
return typeinf (interp, frame)
9
9
end
10
10
@@ -774,22 +774,30 @@ function typeinf_edge(interp::AbstractInterpreter, method::Method, @nospecialize
774
774
mi = specialize_method (method, atypes, sparams):: MethodInstance
775
775
code = get (code_cache (interp), mi, nothing )
776
776
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
787
795
else
788
- return Const (rettype_const) , mi
796
+ return rettype , mi
789
797
end
790
- else
791
- return rettype, mi
792
798
end
799
+ else
800
+ cache = :global # cache edge targets by default
793
801
end
794
802
if ccall (:jl_get_module_infer , Cint, (Any,), method. module) == 0
795
803
return Any, nothing
@@ -805,7 +813,7 @@ function typeinf_edge(interp::AbstractInterpreter, method::Method, @nospecialize
805
813
# completely new
806
814
lock_mi_inference (interp, mi)
807
815
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
809
817
if frame === nothing
810
818
# can't get the source for this, so we know nothing
811
819
unlock_mi_inference (interp, mi)
@@ -834,14 +842,10 @@ function typeinf_code(interp::AbstractInterpreter, method::Method, @nospecialize
834
842
mi = specialize_method (method, atypes, sparams):: MethodInstance
835
843
ccall (:jl_typeinf_begin , Cvoid, ())
836
844
result = InferenceResult (mi)
837
- frame = InferenceState (result, false , interp)
845
+ frame = InferenceState (result, :no , interp)
838
846
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
+ run_optimizer && (frame. cached = true )
848
+ typeinf (interp, frame)
845
849
ccall (:jl_typeinf_end , Cvoid, ())
846
850
frame. inferred || return (nothing , Any)
847
851
return (frame. src, widenconst (ignorelimited (result. result)))
@@ -898,7 +902,7 @@ function typeinf_ext(interp::AbstractInterpreter, mi::MethodInstance)
898
902
return retrieve_code_info (mi)
899
903
end
900
904
lock_mi_inference (interp, mi)
901
- frame = InferenceState (InferenceResult (mi), #= cached =# true , interp)
905
+ frame = InferenceState (InferenceResult (mi), #= cache =# :global , interp)
902
906
frame === nothing && return nothing
903
907
typeinf (interp, frame)
904
908
ccall (:jl_typeinf_end , Cvoid, ())
@@ -921,11 +925,11 @@ function typeinf_type(interp::AbstractInterpreter, method::Method, @nospecialize
921
925
return code. rettype
922
926
end
923
927
end
924
- frame = InferenceResult (mi)
925
- typeinf (interp, frame, true )
928
+ result = InferenceResult (mi)
929
+ typeinf (interp, result, :global )
926
930
ccall (:jl_typeinf_end , Cvoid, ())
927
- frame . result isa InferenceState && return nothing
928
- return widenconst (ignorelimited (frame . result))
931
+ result . result isa InferenceState && return nothing
932
+ return widenconst (ignorelimited (result . result))
929
933
end
930
934
931
935
# This is a bridge for the C code calling `jl_typeinf_func()`
@@ -941,7 +945,7 @@ function typeinf_ext_toplevel(interp::AbstractInterpreter, linfo::MethodInstance
941
945
ccall (:jl_typeinf_begin , Cvoid, ())
942
946
if ! src. inferred
943
947
result = InferenceResult (linfo)
944
- frame = InferenceState (result, src, #= cached =# true , interp)
948
+ frame = InferenceState (result, src, #= cache =# :global , interp)
945
949
typeinf (interp, frame)
946
950
@assert frame. inferred # TODO : deal with this better
947
951
src = frame. src
0 commit comments