Cthulhu.jl icon indicating copy to clipboard operation
Cthulhu.jl copied to clipboard

Cthulhu reports untrue overspecialization for Types, Functions, Varargs

Open NHDaly opened this issue 2 years ago • 1 comments

I was surprised by this, because I thought I recalled you saying in the past that while @code_typed gets this wrong, Cthulhu actually gets this right and shows the true code.

However, we ran into a case where code was allocating because the author wasn't aware of the nuances in this performance tip: https://docs.julialang.org/en/v1/manual/performance-tips/#Be-aware-of-when-Julia-avoids-specializing

As a heuristic, Julia avoids automatically specializing on argument type parameters in three specific cases: Type, Function, and Vararg. Julia will always specialize when the argument is used within the method, but not if the argument is just passed through to another function.

The code in question was not specializing on the Type, causing the allocations. But Cthulhu reports that it is fully type stable and fully specialized, which is not reflecting the real decisions julia makes.


Here is a simple reproducer where you can see that Cthulhu reports the call to atexit() as knowing the type of f::typeof(foo), when in reality it will only be compiled once, for ::Function:

const atexit_hooks = Function[]

# This isn't specialized (for good reason)
function atexit(f::Function)
    push!(atexit_hooks, f)
end

do_register() = atexit(foo)
foo() = 2
julia> @descend do_register()
do_register() in Main at REPL[16]:1
1 do_register()::Vector{Function} = atexit(foo)
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.
Show: [S]ource code, [A]ST, [T]yped code, [L]LVM IR, [N]ative code
Actions: [E]dit source code, [R]evise and redisplay
 • 1 atexit(foo)
   ↩
atexit(f::Function) in Main at REPL[15]:2
2 function atexit(f::typeof(foo)::Function)::Vector{Function}
3     push!(atexit_hooks::Vector{Function}, f::typeof(foo))::Vector{Function}
4 end
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.
Show: [S]ource code, [A]ST, [T]yped code, [L]LVM IR, [N]ative code
Actions: [E]dit source code, [R]evise and redisplay
 • 3 push!(atexit_hooks::Vector{Function}, f::typeof(foo))
   ↩

In our case, this hid the type instability, making the performance problem difficult to track down.

NHDaly avatar May 24 '23 00:05 NHDaly

Also was struck by this issue! Seems to happen not just in Cthulhu, but also in JET (@report_opt).

aplavin avatar Dec 08 '23 18:12 aplavin