From 6c0ee5f5421f7418305993ca8bc3e83af87cd3a7 Mon Sep 17 00:00:00 2001 From: Cody Tapscott Date: Thu, 3 Jul 2025 13:20:51 -0400 Subject: [PATCH] IRShow: Print type of arg0 for `invoke` when necessary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When invoking any "functor-like", such as a closure: ```julia bar(x) = @noinline ((y)->x+y)(x) ``` our IR printing was not showing the arg0 invoked, even when it is required to determine which MethodInstance this is invoking. Before: ``` julia> @code_typed optimize=true bar(1) CodeInfo( 1 ─ %1 = %new(var"#bar##2#bar##3"{Int64}, x)::var"#bar##2#bar##3"{Int64} │ %2 = invoke %1(x::Int64)::Int64 └── return %2 ) => Int64 ``` After: ``` julia> @code_typed optimize=true bar(1) CodeInfo( 1 ─ %1 = %new(var"#bar##2#bar##3"{Int64}, x)::var"#bar##2#bar##3"{Int64} │ %2 = invoke (%1::var"#bar##2#bar##3"{Int64})(x::Int64)::Int64 └── return %2 ) => Int64 ``` --- Compiler/src/ssair/show.jl | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/Compiler/src/ssair/show.jl b/Compiler/src/ssair/show.jl index de58018866274..2a1c16b6c091d 100644 --- a/Compiler/src/ssair/show.jl +++ b/Compiler/src/ssair/show.jl @@ -105,11 +105,30 @@ function print_stmt(io::IO, idx::Int, @nospecialize(stmt), code::Union{IRCode,Co printstyled(io, "dynamic invoke "; color = :yellow) abi = (ci::Core.MethodInstance).specTypes end - show_unquoted(io, stmt.args[2], indent) - print(io, "(") # XXX: this is wrong if `sig` is not a concretetype method # more correct would be to use `fieldtype(sig, i)`, but that would obscure / discard Varargs information in show sig = abi == Tuple ? Core.svec() : Base.unwrap_unionall(abi).parameters::Core.SimpleVector + f = stmt.args[2] + ft = maybe_argextype(f, code, sptypes) + + # We can elide the type for arg0 if it... + skip_ftype = (length(sig) == 0) # doesn't exist... + skip_ftype = skip_ftype || ( + # ... or, f prints as a user-accessible value... + (f isa GlobalRef) && + # ... and matches the value of the singleton type of the invoked MethodInstance + (singleton_type(ft) === singleton_type(sig[1]) !== nothing) + ) + if skip_ftype + show_unquoted(io, f, indent) + else + print(io, "(") + show_unquoted(io, f, indent) + print(io, "::", sig[1], ")") + end + + # Print the remaining arguments (with type annotations from the invoked MethodInstance) + print(io, "(") print_arg(i) = sprint(; context=io) do io show_unquoted(io, stmt.args[i], indent) if (i - 1) <= length(sig)