Julia: Inefficient codegen for non-concrete varargs

Created on 21 Jan 2020  Â·  1Comment  Â·  Source: JuliaLang/julia

The following example generates bad code on recent Julia releases (including master):

function foo(args...)
    Base.pointerset(args[1], 1, 1, 1)
    return
end

code_llvm(foo, Tuple{Ptr{Int}, Type{Int}})
define void @julia_foo_11773(i64, %jl_value_t addrspace(10)* nonnull) #0 {
top:
  %2 = alloca %jl_value_t addrspace(10)*, i32 3
  %gcframe = alloca %jl_value_t addrspace(10)*, i32 3, align 16
...
  %19 = call nonnull %jl_value_t addrspace(10)* @jl_f_tuple(%jl_value_t addrspace(10)* addrspacecast (%jl_value_t* null to %jl_value_t addrspace(10)*), %jl_value_t addrspace(10)** %2, i32 2)
...
  %24 = call nonnull %jl_value_t addrspace(10)* @jl_f_getfield(%jl_value_t addrspace(10)* addrspacecast (%jl_value_t* null to %jl_value_t addrspace(10)*), %jl_value_t addrspace(10)** %2, i32 3)
...
  %25 = bitcast %jl_value_t addrspace(10)* %24 to i64* addrspace(10)*
  %26 = load i64*, i64* addrspace(10)* %25, align 8
  store i64 1, i64* %26, align 1
...
  ret void
}

Not passing a Type{Int} (or any other non-concrete argument), or getting rid of the varargs, results in the expected clean code.


This doesn't look like an inference/specialization problem to me (i.e. not https://github.com/JuliaLang/julia/issues/34365):

julia> first(code_typed(foo, Tuple{Ptr{Int}, Type{Int}})[])
CodeInfo(
1 ─ %1 = Base.pointerset::Core.Compiler.Const(Core.Intrinsics.pointerset, false)
│   %2 = Base.getfield(args, 1, true)::Ptr{Int64}
│        (%1)(%2, 1, 1, 1)::Ptr{Int64}
└──      return
)

julia> first(code_typed(foo, Tuple{Ptr{Int}, Type{Int}})[]).parent.specTypes
Tuple{typeof(foo),Ptr{Int64},Type{Int64}}

Instead, we get the tuple from the specsig but non-concrete varargs code path here: https://github.com/JuliaLang/julia/blob/0549bf1ce39071f22cb7c8065d99e8215714c063/src/codegen.cpp#L6177-L6202


This penalizes a lot of Cassette-based code, where splatting is used heavily for _every_ function call (overdub(ctx, args...)) and we get plenty calls to jl_f_tuple and jl_f_getfield as soon as passing a non-concrete argument (as observed in https://github.com/JuliaGPU/CUDAnative.jl/pull/334 where these calls break compilation).

codegen

Most helpful comment

Looks like I ran into this already: https://github.com/JuliaLang/julia/issues/27929. I'll close that issue since this has much more information.

>All comments

Looks like I ran into this already: https://github.com/JuliaLang/julia/issues/27929. I'll close that issue since this has much more information.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

wilburtownsend picture wilburtownsend  Â·  3Comments

felixrehren picture felixrehren  Â·  3Comments

m-j-w picture m-j-w  Â·  3Comments

musm picture musm  Â·  3Comments

TotalVerb picture TotalVerb  Â·  3Comments