I’ve got a relatively large function, that I’d like to be inlined. Although I used the @inline
annotation, the compiler apparently still decides that it’s not worth inlining. It might be right, but I really want to at least measure whether that’s indeed true. Is there any way to force inlining?
I guess you could make it a macro, or just copy and paste it into where it’s called.
Not since https://github.com/JuliaLang/julia/pull/27857. But if you can make your dispatch signature concrete, you should hit https://github.com/JuliaLang/julia/pull/29258
1 Like
Could you elaborate what a “concrete dispatch signature” or (from the comment linked from your link) a “maximally typed function type” is? Thanks!
There’s a reflection function:
help?> isdispatchtuple
isdispatchtuple(T)
Determine whether type T is a tuple "leaf type", meaning it could appear as a type signature in dispatch and has no subtypes (or supertypes) which could appear in a call
julia> isdispatchtuple(Tuple{Int})
true
julia> isdispatchtuple(Tuple{Any})
false
The latter occurs when the call to your function is badly typed:
julia> foo(x) = x
julia> bar(x) = foo(first(x))
julia> code_warntype(bar, Tuple{Vector{Int}})
Body::Int64
1 1 ─ ...
│ %5 = invoke Main.foo(%4::Int64)::Int64
└── return %5
julia> code_warntype(bar, Tuple{Vector{Any}})
Body::Any
1 1 ─ ...
│ %5 = (Main.foo)(%4::Any)::Any
└── return %5
In that case, doing dynamic dispatch will compile a specialized version for the concrete run-time types which is typically faster (ie. the function barrier pattern).
4 Likes