Skip to content

callsite inlining interacts very badly with source deletion #42078

@aviatesk

Description

@aviatesk

There are several points in our codegen pipeline that discard the inferred source code that is not "inlineable",
and it easily breaks the idempotency of callsite inlining, e.g.:

julia> using LinearAlgebra

julia> const CC = Core.Compiler;

julia> function getsource(mi)
           codeinf = CC.get(CC.code_cache(CC.NativeInterpreter()), mi, nothing)
           return isnothing(codeinf) ? nothing : 
                  isdefined(codeinf, :inferrred) ? nothing :
                  typeof(codeinf.inferred)
       end
getsource (generic function with 1 method)

julia> code_typed1(args...; kwargs...) = first(only(code_typed(args...; kwargs...))).code
code_typed1 (generic function with 1 method)

julia> mi = only(methods(factorize, (Matrix{Float64},))).specializations[1]
MethodInstance for LinearAlgebra.factorize(::Matrix{Float64})

julia> getsource(mi)

julia> code_typed1() do
           A = Array(Bidiagonal(fill(1.0, (5, 5)), :U))
           @inline factorize(A)
       end |> length
431 # succeed in inlining

julia> getsource(mi)
Vector{UInt8} (alias for Array{UInt8, 1})

julia> let # run the codegen pipeline
           A = Array(Bidiagonal(fill(1.0, (5, 5)), :U))
           factorize(A)
       end;

julia> getsource(mi)
Nothing # the inferred source has been discarded

julia> code_typed1() do
           A = Array(Bidiagonal(fill(1.0, (5, 5)), :U))
           @inline factorize(A)
       end |> length
37 # inlining failed, becuase there is no inferred source available

julia> getsource(mi)
Nothing

We can keep the idempotency If we turn off following lines:

but of course this leads to the fat sysimages...:

master

❯ ls -la ./usr/lib/julia/
total 434420
drwxr-xr-x 2 aviatesk aviatesk      4096 Sep  1 03:44 .
drwxr-xr-x 5 aviatesk aviatesk     16384 Sep  1 01:23 ..
-rw-r--r-- 1 aviatesk aviatesk  14742218 Sep  1 03:38 corecompiler.ji
-rw-r--r-- 1 aviatesk aviatesk  92237537 Sep  1 03:40 sys.ji
-rw-r--r-- 1 aviatesk aviatesk 177971028 Sep  1 03:44 sys-o.a
-rwxr-xr-x 1 aviatesk aviatesk 159864072 Sep  1 03:44 sys.so

with source deletion turned off

 ls -la ./usr/lib/julia/
total 457132
drwxr-xr-x 2 aviatesk aviatesk      4096 Sep  1 03:49 .
drwxr-xr-x 5 aviatesk aviatesk     16384 Sep  1 03:39 ..
-rw-r--r-- 1 aviatesk aviatesk  16111154 Sep  1 03:43 corecompiler.ji
-rw-r--r-- 1 aviatesk aviatesk  95654621 Sep  1 03:45 sys.ji
-rw-r--r-- 1 aviatesk aviatesk 187393556 Sep  1 03:49 sys-o.a
-rwxr-xr-x 1 aviatesk aviatesk 168911408 Sep  1 03:49 sys.so

So that actually means, we really want "re-inference" stuff here after all ?

else
# maybe we want to make inference keep the source in a local cache if a statement is going to inlined
# and re-optimize it here with disabling further inlining to avoid infinite optimization loop
# (we can even naively try to re-infer it entirely)
# but it seems like that "single-level-inlining" is more trouble and complex than it's worth
# see https://github.com/JuliaLang/julia/pull/41328/commits/0fc0f71a42b8c9d04b0dafabf3f1f17703abf2e7
return nothing

Metadata

Metadata

Assignees

No one assigned

    Labels

    compiler:optimizerOptimization passes (mostly in base/compiler/ssair/)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions