The results of JETβs report_opt
accurately reflect the behavior of the Julia compiler in most cases, so generally speaking you can trust them.
Looking at the results of @code_typed
, you will see several :call
s to Base.getindex(...)
:
CodeInfo(
1 ββ %1 = Base.getfield(m, :alist)::Union{Nothing, Vector{Int64}}
β %2 = (isa)(%1, Vector{Int64})::Bool
ββββ goto #8 if not %2
2 ββ %4 = Ο (%1, Vector{Int64})
β %5 = $(Expr(:boundscheck, true))::Bool
ββββ goto #6 if not %5
3 ββ %7 = Base.sub_int(1, 1)::Int64
β %8 = Base.bitcast(Base.UInt, %7)::UInt64
β %9 = Base.getfield(%4, :size)::Tuple{Int64}
β %10 = $(Expr(:boundscheck, true))::Bool
β %11 = Base.getfield(%9, 1, %10)::Int64
β %12 = Base.bitcast(Base.UInt, %11)::UInt64
β %13 = Base.ult_int(%8, %12)::Bool
ββββ goto #5 if not %13
4 ββ goto #6
5 ββ %16 = Core.tuple(1)::Tuple{Int64}
β invoke Base.throw_boundserror(%4::Vector{Int64}, %16::Tuple{Int64})::Union{}
ββββ unreachable
6 ββ %19 = Base.getfield(%4, :ref)::MemoryRef{Int64}
β %20 = Base.memoryrefnew(%19, 1, false)::MemoryRef{Int64}
β %21 = Base.memoryrefget(%20, :not_atomic, false)::Int64
ββββ goto #7
7 ββ goto #9
8 ββ %24 = Base.getindex(%1, 1)::Int64
ββββ goto #9
9 ββ %26 = Ο (#7 => %21, #8 => %24)::Int64
β %27 = Base.getfield(m, :alist)::Union{Nothing, Vector{Int64}}
β %28 = (isa)(%27, Vector{Int64})::Bool
ββββ goto #16 if not %28
10 β %30 = Ο (%27, Vector{Int64})
β %31 = $(Expr(:boundscheck, true))::Bool
ββββ goto #14 if not %31
11 β %33 = Base.sub_int(2, 1)::Int64
β %34 = Base.bitcast(Base.UInt, %33)::UInt64
β %35 = Base.getfield(%30, :size)::Tuple{Int64}
β %36 = $(Expr(:boundscheck, true))::Bool
β %37 = Base.getfield(%35, 1, %36)::Int64
β %38 = Base.bitcast(Base.UInt, %37)::UInt64
β %39 = Base.ult_int(%34, %38)::Bool
ββββ goto #13 if not %39
12 β goto #14
13 β %42 = Core.tuple(2)::Tuple{Int64}
β invoke Base.throw_boundserror(%30::Vector{Int64}, %42::Tuple{Int64})::Union{}
ββββ unreachable
14 β %45 = Base.getfield(%30, :ref)::MemoryRef{Int64}
β %46 = Base.memoryrefnew(%45, 2, false)::MemoryRef{Int64}
β %47 = Base.memoryrefget(%46, :not_atomic, false)::Int64
ββββ goto #15
15 β goto #17
16 β %50 = Base.getindex(%27, 2)::Int64
ββββ goto #17
17 β %52 = Ο (#15 => %47, #16 => %50)::Int64
β %53 = Base.add_int(%26, %52)::Int64
ββββ return %53
) => Int64
These correspond to the union split branches where m.alist
is nothing
. In such cases, a MethodError
is raised, and since such βmust-throwβ case is not optimized, it results in dynamic dispatch. However, Inline statically known method errors. by gbaraldi Β· Pull Request #54972 Β· JuliaLang/julia Β· GitHub might change this behavior.