Skip to content

Commit 0f4a513

Browse files
committed
inference: invalidate stale slot wrapper types in ssavaluetypes
When updating a state of local variables from an assignment, all stale slot wrapper types must be invalidated. However, up until now, only those held in the local variable state were being invalidated. In fact, those held in `ssavaluetypes` also need to be invalidated, and this commit addresses that. Currently all `ssavaluetypes` are iterated over with each assignment to a local variable, so this could potentially lead to performance issues. If so it might be necessary to perform invalidation more efficiently along with flow control. - fixes #55548
1 parent 86cba99 commit 0f4a513

File tree

2 files changed

+37
-14
lines changed

2 files changed

+37
-14
lines changed

base/compiler/abstractinterpretation.jl

+3
Original file line numberDiff line numberDiff line change
@@ -3510,6 +3510,9 @@ function typeinf_local(interp::AbstractInterpreter, frame::InferenceState)
35103510
end
35113511
if changes !== nothing
35123512
stoverwrite1!(currstate, changes)
3513+
# widen any slot wrapper types that should be invalidated by this change
3514+
# just like what's done for `currstate`
3515+
invalidate_ssa_slotwrapper!(ssavaluetypes, slot_id(changes.var))
35133516
end
35143517
if refinements isa SlotRefinement
35153518
apply_refinement!(𝕃ᵢ, refinements.slot, refinements.typ, currstate, changes)

base/compiler/typelattice.jl

+34-14
Original file line numberDiff line numberDiff line change
@@ -745,15 +745,38 @@ end
745745
@nospecializeinfer @inline schanged(lattice::AbstractLattice, @nospecialize(n), @nospecialize(o)) =
746746
(n !== o) && (o === NOT_FOUND || (n !== NOT_FOUND && !(n.undef <= o.undef && (lattice, n.typ, o.typ))))
747747

748-
# remove any lattice elements that wrap the reassigned slot object from the vartable
749-
function invalidate_slotwrapper(vt::VarState, changeid::Int, ignore_conditional::Bool)
750-
newtyp = ignorelimited(vt.typ)
751-
if (!ignore_conditional && isa(newtyp, Conditional) && newtyp.slot == changeid) ||
752-
(isa(newtyp, MustAlias) && newtyp.slot == changeid)
748+
function should_invalidate(@nospecialize(typ), changeid::Int, ignore_conditional::Bool=false)
749+
typ = ignorelimited(typ)
750+
return ((!ignore_conditional && typ isa Conditional && typ.slot == changeid) ||
751+
(typ isa MustAlias && typ.slot == changeid))
752+
end
753+
754+
# remove any lattice elements that wrap the reassigned slot object within `state`
755+
function invalidate_slotwrapper!(state::VarTable, changeid::Int, ignore_conditional::Bool)
756+
for idx = 1:length(state)
757+
invalidate_slotwrapper!(state, idx, changeid, ignore_conditional)
758+
end
759+
end
760+
function invalidate_slotwrapper!(state::VarTable, idx::Int, changeid::Int, ignore_conditional::Bool)
761+
vt = state[idx]
762+
if should_invalidate(vt.typ, changeid, ignore_conditional)
753763
newtyp = @noinline widenwrappedslotwrapper(vt.typ)
754-
return VarState(newtyp, vt.undef)
764+
state[idx] = VarState(newtyp, vt.undef)
765+
end
766+
end
767+
768+
# remove any lattice elements that wrap the reassigned slot object within `ssavaluetypes`
769+
function invalidate_ssa_slotwrapper!(ssavaluetypes::Vector{Any}, changeid::Int)
770+
for idx = 1:length(ssavaluetypes)
771+
invalidate_ssa_slotwrapper!(ssavaluetypes, idx, changeid)
772+
end
773+
end
774+
function invalidate_ssa_slotwrapper!(ssavaluetypes::Vector{Any}, idx::Int, changeid::Int)
775+
typ = ssavaluetypes[idx]
776+
if should_invalidate(typ, changeid)
777+
newtyp = @noinline widenwrappedslotwrapper(typ)
778+
ssavaluetypes[idx] = newtyp
755779
end
756-
return nothing
757780
end
758781

759782
function stupdate!(lattice::AbstractLattice, state::VarTable, changes::VarTable)
@@ -778,13 +801,10 @@ end
778801

779802
function stoverwrite1!(state::VarTable, change::StateUpdate)
780803
changeid = slot_id(change.var)
781-
for i = 1:length(state)
782-
invalidated = invalidate_slotwrapper(state[i], changeid, change.conditional)
783-
if invalidated !== nothing
784-
state[i] = invalidated
785-
end
786-
end
787-
# and update the type of it
804+
# widen any slot wrapper types that should be invalidated by this change
805+
# (unless if this change is made from `Conditional`)
806+
invalidate_slotwrapper!(state, changeid, #=ignore_conditional=#change.conditional)
807+
# and update the type of the slot
788808
newtype = change.vtype
789809
state[changeid] = newtype
790810
return state

0 commit comments

Comments
 (0)