@@ -826,7 +826,9 @@ function abstract_call_gf_by_type(f::ANY, atype::ANY, sv::InferenceState)
826826 return Any
827827 end
828828 end
829- applicable = _methods_by_ftype (argtype, 4 , sv. world)
829+ min_valid = UInt[typemin (UInt)]
830+ max_valid = UInt[typemax (UInt)]
831+ applicable = _methods_by_ftype (argtype, 4 , sv. world, min_valid, max_valid)
830832 rettype = Bottom
831833 if is (applicable, false )
832834 # this means too many methods matched
@@ -956,6 +958,7 @@ function abstract_call_gf_by_type(f::ANY, atype::ANY, sv::InferenceState)
956958 # also need an edge to the method table in case something gets
957959 # added that did not intersect with any existing method
958960 add_mt_backedge (ft. name. mt, argtype, sv)
961+ update_valid_age! (min_valid[1 ], max_valid[1 ], sv)
959962 end
960963 if isempty (x)
961964 # TODO : this is needed because type intersection is wrong in some cases
@@ -1060,7 +1063,9 @@ function pure_eval_call(f::ANY, argtypes::ANY, atype, vtypes, sv::InferenceState
10601063 end
10611064 end
10621065
1063- meth = _methods_by_ftype (atype, 1 , sv. world)
1066+ min_valid = UInt[typemin (UInt)]
1067+ max_valid = UInt[typemax (UInt)]
1068+ meth = _methods_by_ftype (atype, 1 , sv. world, min_valid, max_valid)
10641069 if meth === false || length (meth) != 1
10651070 return false
10661071 end
@@ -1074,6 +1079,7 @@ function pure_eval_call(f::ANY, argtypes::ANY, atype, vtypes, sv::InferenceState
10741079 args = Any[ isa (a,Const) ? a. val : a. parameters[1 ] for a in drop (argtypes,1 ) ]
10751080 try
10761081 value = Core. _apply_pure (f, args)
1082+ # TODO : add some sort of edge(s)
10771083 return abstract_eval_constant (value)
10781084 catch
10791085 return false
@@ -1530,23 +1536,24 @@ function converge_valid_age!(sv::InferenceState)
15301536 i. max_valid = sv. max_valid
15311537 updated = true
15321538 end
1539+ @assert ! isdefined (i. linfo, :def ) || i. min_valid <= i. world <= i. max_valid " invalid age range update"
15331540 if updated
15341541 converge_valid_age! (i)
15351542 end
15361543 end
15371544 end
15381545 nothing
15391546end
1540- function update_valid_age! (edge:: InferenceState , sv:: InferenceState )
1541- sv. min_valid = max (edge. min_valid, sv. min_valid)
1542- sv. max_valid = min (edge. max_valid, sv. max_valid)
1543- nothing
1544- end
1545- function update_valid_age! (li:: MethodInstance , sv:: InferenceState )
1546- sv. min_valid = max (sv. min_valid, min_age (li))
1547- sv. max_valid = min (sv. max_valid, max_age (li))
1547+
1548+ function update_valid_age! (min_valid:: UInt , max_valid:: UInt , sv:: InferenceState )
1549+ sv. min_valid = max (sv. min_valid, min_valid)
1550+ sv. max_valid = min (sv. max_valid, max_valid)
1551+ @assert ! isdefined (sv. linfo, :def ) || sv. min_valid <= sv. world <= sv. max_valid " invalid age range update"
15481552 nothing
15491553end
1554+ update_valid_age! (edge:: InferenceState , sv:: InferenceState ) = update_valid_age! (edge. min_valid, edge. max_valid, sv)
1555+ update_valid_age! (li:: MethodInstance , sv:: InferenceState ) = update_valid_age! (min_age (li), max_age (li), sv)
1556+
15501557function add_backedge (li:: MethodInstance , caller:: InferenceState )
15511558 isdefined (caller. linfo, :def ) || return # don't add backedges to toplevel exprs
15521559 if caller. stmt_edges[caller. currpc] === ()
@@ -1556,6 +1563,7 @@ function add_backedge(li::MethodInstance, caller::InferenceState)
15561563 update_valid_age! (li, caller)
15571564 nothing
15581565end
1566+
15591567function add_mt_backedge (mt:: MethodTable , typ:: ANY , caller:: InferenceState )
15601568 isdefined (caller. linfo, :def ) || return # don't add backedges to toplevel exprs
15611569 if caller. stmt_edges[caller. currpc] === ()
@@ -1566,6 +1574,7 @@ function add_mt_backedge(mt::MethodTable, typ::ANY, caller::InferenceState)
15661574 # TODO : how to compute the affect this has on valid ages for caller?
15671575 nothing
15681576end
1577+
15691578function finalize_backedges (frame:: InferenceState )
15701579 caller = frame. linfo
15711580 for edges in frame. stmt_edges
@@ -1666,7 +1675,7 @@ function typeinf_edge(method::Method, atypes::ANY, sparams::SimpleVector, caller
16661675 code = code_for_method (method, atypes, sparams, caller. world)
16671676 code === nothing && return Any
16681677 code = code:: MethodInstance
1669- add_backedge (code, caller)
1678+ add_backedge (code, caller) # TODO : need to defer the tracking of this backedge till later
16701679 if isdefined (code, :inferred )
16711680 # return rettype if the code is already inferred
16721681 # staged functions make this hard since they have two "inferred" conditions,
@@ -2682,7 +2691,9 @@ function inlineable(f::ANY, ft::ANY, e::Expr, atypes::Vector{Any}, sv::Inference
26822691 else
26832692 atype = atype_unlimited
26842693 end
2685- meth = _methods_by_ftype (atype, 1 , sv. world)
2694+ min_valid = UInt[typemin (UInt)]
2695+ max_valid = UInt[typemax (UInt)]
2696+ meth = _methods_by_ftype (atype, 1 , sv. world, min_valid, max_valid)
26862697 if meth === false || length (meth) != 1
26872698 return invoke_NF ()
26882699 end
@@ -4083,9 +4094,9 @@ end
40834094# make sure that typeinf is executed before turning on typeinf_ext
40844095# this ensures that typeinf_ext doesn't recurse before it can add the item to the workq
40854096
4086- for m in _methods_by_ftype (Tuple{typeof (typeinf_loop), Vararg{Any}}, 10 , typemax (UInt))
4097+ for m in _methods_by_ftype (Tuple{typeof (typeinf_loop), Vararg{Any}}, 10 , typemax (UInt), UInt[ typemin (UInt)], UInt[ typemax (UInt)] )
40874098 typeinf_type (m[3 ], m[1 ], m[2 ], typemax (UInt))
40884099end
4089- for m in _methods_by_ftype (Tuple{typeof (typeinf_edge), Vararg{Any}}, 10 , typemax (UInt))
4100+ for m in _methods_by_ftype (Tuple{typeof (typeinf_edge), Vararg{Any}}, 10 , typemax (UInt), UInt[ typemin (UInt)], UInt[ typemax (UInt)] )
40904101 typeinf_type (m[3 ], m[1 ], m[2 ], typemax (UInt))
40914102end
0 commit comments