@@ -761,17 +761,10 @@ function type_annotate!(interp::AbstractInterpreter, sv::InferenceState)
761761end
762762
763763function merge_call_chain! (:: AbstractInterpreter , parent:: InferenceState , child:: InferenceState )
764- # add backedge of parent <- child
765- # then add all backedges of parent <- parent.parent
764+ # update all cycleid to be in the same group
766765 frames = parent. callstack:: Vector{AbsIntState}
767766 @assert child. callstack === frames
768767 ancestorid = child. cycleid
769- while true
770- add_cycle_backedge! (parent, child)
771- parent. cycleid === ancestorid && break
772- child = parent
773- parent = cycle_parent (child):: InferenceState
774- end
775768 # ensure that walking the callstack has the same cycleid (DAG)
776769 for frameid = reverse (ancestorid: length (frames))
777770 frame = frames[frameid]:: InferenceState
@@ -782,7 +775,6 @@ function merge_call_chain!(::AbstractInterpreter, parent::InferenceState, child:
782775end
783776
784777function add_cycle_backedge! (caller:: InferenceState , frame:: InferenceState )
785- update_valid_age! (caller, frame. world. valid_worlds)
786778 backedge = (caller, caller. currpc)
787779 contains_is (frame. cycle_backedges, backedge) || push! (frame. cycle_backedges, backedge)
788780 return frame
801793# frame matching `mi` is encountered, then there is a cycle in the call graph
802794# (i.e. `mi` is a descendant callee of itself). Upon encountering this cycle,
803795# we "resolve" it by merging the call chain, which entails updating each intermediary
804- # frame's `cycleid` field and adding the appropriate backedges. Finally,
805- # we return `mi`'s pre-existing frame. If no cycles are found, `nothing` is
806- # returned instead.
796+ # frame's `cycleid` field. Finally, we return `mi`'s pre-existing frame.
797+ # If no cycles are found, `nothing` is returned instead.
807798function resolve_call_cycle! (interp:: AbstractInterpreter , mi:: MethodInstance , parent:: AbsIntState )
808799 # TODO (#48913) implement a proper recursion handling for irinterp:
809800 # This works most of the time currently just because the irinterp code doesn't get used much with
@@ -992,6 +983,7 @@ function typeinf_edge(interp::AbstractInterpreter, method::Method, @nospecialize
992983 result. ci_as_edge = edge_ci # set the edge for the inliner usage
993984 VolatileInferenceResult (result)
994985 end
986+ isinferred || add_cycle_backedge! (caller, frame)
995987 mresult[] = MethodCallResult (interp, caller, method, bestguess, exc_bestguess, effects,
996988 edge, edgecycle, edgelimited, volatile_inf_result)
997989 return true
@@ -1010,6 +1002,7 @@ function typeinf_edge(interp::AbstractInterpreter, method::Method, @nospecialize
10101002 update_valid_age! (caller, valid_worlds)
10111003 bestguess = frame. bestguess
10121004 exc_bestguess = refine_exception_type (frame. exc_bestguess, effects)
1005+ add_cycle_backedge! (caller, frame)
10131006 return Future (MethodCallResult (interp, caller, method, bestguess, exc_bestguess, effects, nothing , edgecycle, edgelimited))
10141007end
10151008
0 commit comments