You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
inference: fixes and improvements for backedge computation (#46741)
This commit consists of the following changes:
* inference: setup separate functions for each backedge kind
Also changes the argument list so that they are ordered as
`(caller, [backedge information])`.
* inference: fix backedge computation for const-prop'ed callsite
With this commit `abstract_call_method_with_const_args` doesn't add
backedge but rather returns the backedge to the caller, letting the
callers like `abstract_call_gf_by_type` and `abstract_invoke` take the
responsibility to add backedge to current context appropriately.
As a result, this fixes the backedge calculation for const-prop'ed
`invoke` callsite.
For example, for the following call graph,
```julia
foo(a::Int) = a > 0 ? :int : println(a)
foo(a::Integer) = a > 0 ? "integer" : println(a)
bar(a::Int) = @invoke foo(a::Integer)
```
Previously we added the wrong backedge `nothing, bar(Int64) from bar(Int64)`:
```julia
julia> last(only(code_typed(()->bar(42))))
String
julia> let m = only(methods(foo, (UInt,)))
@eval Core.Compiler for (sig, caller) in BackedgeIterator($m.specializations[1].backedges)
println(sig, ", ", caller)
end
end
Tuple{typeof(Main.foo), Integer}, bar(Int64) from bar(Int64)
nothing, bar(Int64) from bar(Int64)
```
but now we only add `invoke`-backedge:
```julia
julia> last(only(code_typed(()->bar(42))))
String
julia> let m = only(methods(foo, (UInt,)))
@eval Core.Compiler for (sig, caller) in BackedgeIterator($m.specializations[1].backedges)
println(sig, ", ", caller)
end
end
Tuple{typeof(Main.foo), Integer}, bar(Int64) from bar(Int64)
```
* inference: make `BackedgePair` struct
* add invalidation test for `invoke` call
* optimizer: fixup inlining backedge calculation
Should fix the following backedge calculation:
```julia
julia> m = which(unique, Tuple{Any})
unique(itr)
@ Base set.jl:170
julia> specs = collect(Iterators.filter(m.specializations) do mi
mi === nothing && return false
return mi.specTypes.parameters[end] === Vector{Int} # find specialization of `unique(::Any)` for `::Vector{Int}`
end)
Any[]
julia> Base._unique_dims([1,2,3],:) # no existing callers with specialization `Vector{Int}`, let's make one
3-element Vector{Int64}:
1
2
3
julia> mi = only(Iterators.filter(m.specializations) do mi
mi === nothing && return false
return mi.specTypes.parameters[end] === Vector{Int} # find specialization of `unique(::Any)` for `::Vector{Int}`
end)
MethodInstance for unique(::Vector{Int64})
julia> mi.def
unique(itr)
@ Base set.jl:170
julia> mi.backedges
3-element Vector{Any}:
Tuple{typeof(unique), Any}
MethodInstance for Base._unique_dims(::Vector{Int64}, ::Colon)
MethodInstance for Base._unique_dims(::Vector{Int64}, ::Colon) # <= now we don't register this backedge
```
0 commit comments