Forcing @inline

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