-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Open
Labels
compiler:inferenceType inferenceType inference
Description
I found this while looking into invalidations on Julia v1.10-rc1. The code
using SnoopCompileCore
invalidations = @snoopr begin using OrdinaryDiffEq end
using SnoopCompile
@show length(uinvalidated(invalidations))
trees = invalidation_trees(invalidations)
and investigating the last entry lead to
julia> trees[end]
inserting &(::Static.StaticInteger{X}, y::Union{Missing, Integer}) where X @ Static ~/.julia/packages/Static/dLrtk/src/Static.jl:489 invalidated:
mt_backedges: 1: signature Tuple{typeof(&), Any, UInt8} triggered MethodInstance for ismutable(::Tuple{Vararg{T, _A}} where {T, _A}) (8 children)
2: signature Tuple{typeof(&), Any, UInt8} triggered MethodInstance for ismutable(::Function) (732 children)
julia> trees[end].mt_backedges[end].second |> ascend
Choose a call for analysis (q to quit):
> ismutable(::Function)
pointer_from_objref(::Function)
unsafe_convert(::Type{Ptr{T}}, ::Base.RefValue{T}) where T<:Function
unsafe_convert(::Type{Ref{T}}, ::Base.RefValue{T}) where T<:Function
utf8proc_decompose(::String, ::Int64, ::Ptr{Nothing}, ::Int64, ::Function)
utf8proc_map(::String, ::Int64, ::Function)
utf8proc_map(::String, ::Int64)
normalize(::String, ::Symbol)
isfile_casesensitive(::String)
v active_project(::Bool)
ismutable(x) @ Base reflection.jl:517
┌ Warning: Some line information is missing, type-assignment may be incomplete
└ @ Cthulhu ~/.julia/packages/Cthulhu/Ndnbu/src/codeview.jl:144
517 ismutable(@nospecialize(x::Function))::Any = (@_total_meta; ((typeof(x::Function)::Type{<:Function}.name::Any.flags::Any & 0x2)::Any == 0x2)::Any)
Select a call to descend into or ↩ to ascend. [q]uit. [b]ookmark.
Toggles: [w]arn, [h]ide type-stable statements, [t]ype annotations, [s]yntax highlight for Source/LLVM/Native, [j]ump to source always.
Show: [S]ource code, [A]ST, [T]yped code, [L]LVM IR, [N]ative code
Actions: [E]dit source code, [R]evise and redisplay
• typeof(x::Function)::Type{<:Function}.name
runtime typeof(x::Function)::Type{<:Function}.name::Any.flags
runtime typeof(x::Function)::Type{<:Function}.name::Any.flags::Any & 0x2
runtime (typeof(x::Function)::Type{<:Function}.name::Any.flags::Any & 0x2)::Any == 0x2
An MWE reproducing the type inference problem is
julia> function foo(x)
return typeof(first(x)).name.flags
end
foo (generic function with 1 method)
julia> @code_warntype foo([1.0]) # fine
MethodInstance for foo(::Vector{Float64})
from foo(x) @ Main REPL[1]:1
Arguments
#self#::Core.Const(foo)
x::Vector{Float64}
Body::UInt8
1 ─ %1 = Main.first(x)::Float64
│ %2 = Main.typeof(%1)::Core.Const(Float64)
│ %3 = Base.getproperty(%2, :name)::Core.Const(typename(Float64))
│ %4 = Base.getproperty(%3, :flags)::Core.Const(0x04)
└── return %4
julia> @code_warntype foo(Any[1.0]) # fine
MethodInstance for foo(::Vector{Any})
from foo(x) @ Main REPL[1]:1
Arguments
#self#::Core.Const(foo)
x::Vector{Any}
Body::UInt8
1 ─ %1 = Main.first(x)::Any
│ %2 = Main.typeof(%1)::DataType
│ %3 = Base.getproperty(%2, :name)::Core.TypeName
│ %4 = Base.getproperty(%3, :flags)::UInt8
└── return %4
julia> @code_warntype foo(Real[1.0]) # bad
MethodInstance for foo(::Vector{Real})
from foo(x) @ Main REPL[1]:1
Arguments
#self#::Core.Const(foo)
x::Vector{Real}
Body::Any
1 ─ %1 = Main.first(x)::Real
│ %2 = Main.typeof(%1)::Type{<:Real}
│ %3 = Base.getproperty(%2, :name)::Any
│ %4 = Base.getproperty(%3, :flags)::Any
└── return %4
julia> @code_warntype foo(Function[identity])
MethodInstance for foo(::Vector{Function})
from foo(x) @ Main REPL[1]:1
Arguments
#self#::Core.Const(foo)
x::Vector{Function}
Body::Any
1 ─ $(Expr(:meta, :noinline))
│ nothing
│ %3 = Base.getindex(x, 1)::Function
│ %4 = Main.typeof(%3)::Type{<:Function}
│ %5 = Base.getproperty(%4, :name)::Any
│ %6 = Base.getproperty(%5, :flags)::Any
└── return %6
Here, type inference gets worse with more information such as Type{<:Function}
instead of DataType
.
- Is there a way to fix this underlying issue?
- If there is no easy way to fix it, can I assume that
typeof(x).name::Core.TypeName
holds for everyx
to fix at least the invalidations soon in the code below?
Line 630 in e746ba4
ismutable(@nospecialize(x)) = (@_total_meta; typeof(x).name.flags & 0x2 == 0x2) |
Metadata
Metadata
Assignees
Labels
compiler:inferenceType inferenceType inference